diff options
Diffstat (limited to 'src/scalevalapokalypsi/Model/Action.scala')
-rw-r--r-- | src/scalevalapokalypsi/Model/Action.scala | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/src/scalevalapokalypsi/Model/Action.scala b/src/scalevalapokalypsi/Model/Action.scala new file mode 100644 index 0000000..32f513d --- /dev/null +++ b/src/scalevalapokalypsi/Model/Action.scala @@ -0,0 +1,69 @@ +package scalevalapokalypsi.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 + |