package o1game.Model /** The class `Action` represents actions that a player may take in a text adventure game. * `Action` objects are constructed on the basis of textual commands and are, in effect, * parsers for such commands. An action object is immutable after creation. * @param input a textual in-game command such as “go east” or “rest” */ class Action(input: String): private val commandText = input.trim.toLowerCase private val verb = commandText.takeWhile( _ != ' ' ) private val modifiers = commandText.drop(verb.length).trim def takesATurnFor(actor: Player): Boolean = this.verb match case "rest" => true case "go" => actor.location.hasNeighbor(modifiers) case "get" => actor.location.hasItem(this.modifiers) case "drop" => actor.canDrop(this.modifiers) case "say" => false case other => false /** Causes the given player to take the action represented by this object, assuming * that the command was understood. Returns a description of what happened as a result * of the action (such as “You go west.”). The description is returned in an `Option` * wrapper; if the command was not recognized, `None` is returned. */ def execute(actor: Player): Option[String] = val oldLocation = actor.location val resOption: Option[(String, String)] = this.verb match case "go" => Some(actor.go(this.modifiers)) case "rest" => Some(actor.rest()) case "get" => Some(actor.pickUp(this.modifiers)) case "say" => val to = "to" val recipient = modifiers.reverse.takeWhile(_ != ' ').reverse val recipientEntity = actor.location.getEntity(recipient) val maybeTo = modifiers.slice( modifiers.length - recipient.length - s"$to ".length, modifiers.length - recipient.length - 1 ) val message = modifiers.take(modifiers.length - recipient.length - 4) if maybeTo == to then recipientEntity.map(actor.sayTo(_, message)) else Some(actor.say(modifiers)) case "drop" => Some(actor.drop(this.modifiers)) case "xyzzy" => Some(( "The grue tastes yummy.", s"${actor.name} tastes some grue.") ) case other => None // println(resOption) // println(actor.location.getEntities) resOption.map(_(1)).filter(_.length > 0) .foreach(s => actor.location.getEntities.filter(_ != actor).foreach(_.observe(s)) if oldLocation != actor.location then oldLocation.getEntities.foreach(_.observe(s)) ) resOption.map(_(0)) /** Returns a textual description of the action object, for debugging purposes. */ override def toString = s"$verb (modifiers: $modifiers)" end Action