aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/Model/Action.scala
blob: 9f812561c8243f25d0b0f0657ee2ec0af8c6a366 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
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: Entity): 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 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: Entity): 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 "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