aboutsummaryrefslogtreecommitdiff
path: root/src/scalevalapokalypsi/Model/Action.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/scalevalapokalypsi/Model/Action.scala')
-rw-r--r--src/scalevalapokalypsi/Model/Action.scala69
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
+