blob: e59d5f1bd89efa68e1985e6d64974135f29cd029 (
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
package scalevalapokalypsi.Model
import scalevalapokalypsi.Model.Entities.*
/** 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
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
|