aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/Model
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/scala/Model')
-rw-r--r--src/main/scala/Model/Action.scala21
-rw-r--r--src/main/scala/Model/Adventure.scala10
-rw-r--r--src/main/scala/Model/Area.scala1
-rw-r--r--src/main/scala/Model/Entity.scala61
4 files changed, 67 insertions, 26 deletions
diff --git a/src/main/scala/Model/Action.scala b/src/main/scala/Model/Action.scala
index 11b0bc8..9f81256 100644
--- a/src/main/scala/Model/Action.scala
+++ b/src/main/scala/Model/Action.scala
@@ -23,15 +23,30 @@ class Action(input: String):
* 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] =
- this.verb match
+ 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.")
- case "quit" => Some(actor.quit())
+ 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)"
diff --git a/src/main/scala/Model/Adventure.scala b/src/main/scala/Model/Adventure.scala
index 4d0a256..7d5a061 100644
--- a/src/main/scala/Model/Adventure.scala
+++ b/src/main/scala/Model/Adventure.scala
@@ -34,16 +34,18 @@ class Adventure(val playerNames: Vector[String]):
"Problem is, there's no battery."
))
- val players: Map[String, Entity] = Map()
+ val players: Map[String, Player] = Map()
playerNames.foreach(this.addPlayer(_))
+ val entities: Map[String, Entity] = Map()
+
/** Adds a player entity with the specified name to the game.
*
* @param name the name of the player entity to add
* @return the created player entity
*/
- def addPlayer(name: String): Entity =
- val newPlayer = Entity(name, middle)
+ def addPlayer(name: String): Player =
+ val newPlayer = Player(name, middle)
middle.addEntity(newPlayer)
players += name -> newPlayer
newPlayer
@@ -53,7 +55,7 @@ class Adventure(val playerNames: Vector[String]):
* @param name name of the player to find
* @return the player, if one with the name was found
*/
- def getPlayer(name: String): Option[Entity] = this.players.get(name)
+ def getPlayer(name: String): Option[Player] = this.players.get(name)
/** Returns a message that is to be displayed to the player at the beginning of the game. */
def welcomeMessage = "Generic welcome message"
diff --git a/src/main/scala/Model/Area.scala b/src/main/scala/Model/Area.scala
index ae1c98e..5a8de2a 100644
--- a/src/main/scala/Model/Area.scala
+++ b/src/main/scala/Model/Area.scala
@@ -23,6 +23,7 @@ class Area(val name: String, var description: String):
def getNeighborNames: Iterable[String] = this.neighbors.keys
def getItemNames: Iterable[String] = this.items.keys
def getEntityNames: Iterable[String] = this.entities.keys
+ def getEntities: Iterable[Entity] = this.entities.values
/** Tells whether this area has a neighbor in the given direction.
*
diff --git a/src/main/scala/Model/Entity.scala b/src/main/scala/Model/Entity.scala
index c18ffea..37fdbc2 100644
--- a/src/main/scala/Model/Entity.scala
+++ b/src/main/scala/Model/Entity.scala
@@ -1,14 +1,35 @@
package o1game.Model
-import scala.collection.mutable.Map
+import scala.collection.mutable.{Buffer,Map}
-/** A `Player` object represents a player character controlled by the real-life user
+
+
+/** A `Player` object represents a player character controlled by one real-life player
* of the program.
*
* A player object’s state is mutable: the player’s location and possessions can change,
* for instance.
*
* @param startingArea the player’s initial location */
+class Player(name: String, initialLocation: Area) extends Entity(name, initialLocation):
+
+ private val observations: Buffer[String] = Buffer.empty
+
+ override def observe(observation: String): Unit =
+ this.observations.append(observation)
+
+ def readAndClearObservations(): Vector[String] =
+ val res = this.observations.toVector
+ observations.clear()
+ res
+
+end Player
+
+/** An in-game entity.
+ *
+ * @param name the name of the entity
+ * @param initialLocation the Area where the entity is instantiated
+ */
class Entity(val name: String, initialLocation: Area):
private var currentLocation: Area = initialLocation
private var quitCommandGiven = false // one-way flag
@@ -17,35 +38,43 @@ class Entity(val name: String, initialLocation: Area):
/** Determines if the player has indicated a desire to quit the game. */
def hasQuit = this.quitCommandGiven // TODO: This is probably unneccessary?
+ /** Does nothing, except possibly in inherited classes. */
+ def observe(observation: String): Unit =
+ println("no observation made.")
+ ()
+
/** Returns the player’s current location. */
def location = this.currentLocation
/** Attempts to move the player in the given direction. This is successful if there
* is an exit from the player’s current location towards the direction name. Returns
* a description of the result: "You go DIRECTION." or "You can't go DIRECTION." */
- def go(direction: String) =
+ def go(direction: String): (String, String) =
val destination = this.location.neighbor(direction)
if destination.isDefined then
this.currentLocation.removeEntity(this.name)
this.currentLocation = destination.getOrElse(this.currentLocation)
destination.foreach(_.addEntity(this))
- s"You go $direction."
+ (s"You go $direction.", s"$name goes $direction")
else
- "You can't go " + direction + "."
+ (
+ s"You can't go $direction.",
+ s"$name tries to go $direction and stumbles in their feet."
+ )
- def pickUp(itemName: String): String =
+ def pickUp(itemName: String): (String, String) =
this.currentLocation.removeItem(itemName) match
case Some(i) =>
this.inventory += i.name -> i
- s"You pick up the ${i.name}"
- case None => s"There is no $itemName here to pick up."
+ (s"You pick up the ${i.name}", s"$name picks up the ${i.name}")
+ case None => (s"There is no $itemName here to pick up.", "WHAAAT THIS SHOULDN'T HAPPEN???")
- def drop(itemName: String): String =
+ def drop(itemName: String): (String, String) =
this.inventory.remove(itemName) match
case Some(item) =>
this.currentLocation.addItem(item)
- s"You drop the $itemName"
- case None => "You don't have that!"
+ (s"You drop the $itemName", s"$name drops the $itemName")
+ case None => ("You don't have that!", s"$name reaches their backpack to drop $itemName but miserably fails to find it there.")
/** Tells whether this entity can drop the specified item
* (if an action were to specify so).
@@ -57,14 +86,8 @@ class Entity(val name: String, initialLocation: Area):
/** Causes the player to rest for a short while (this has no substantial effect in game terms).
* Returns a description of what happened. */
- def rest() =
- "You rest for a while. Better get a move on, though."
-
- /** Signals that the player wants to quit the game. Returns a description of what happened within
- * the game as a result (which is the empty string, in this case). */
- def quit() =
- this.quitCommandGiven = true
- ""
+ def rest(): (String, String) =
+ ("You rest for a while. Better get a move on, though.", "")
/** Returns a brief description of the player’s state, for debugging purposes. */
override def toString = "Now at: " + this.location.name