Skip to content

Commit

Permalink
Merge pull request #37 from scalaquest/feature/base-model-scaladoc
Browse files Browse the repository at this point in the history
ScalaDoc for Model, Resolver, Interpreter, Reducer; package refactoring
  • Loading branch information
maldins46 committed Jan 24, 2021
2 parents a4f612f + 3cf2bdf commit 99ba985
Show file tree
Hide file tree
Showing 78 changed files with 1,367 additions and 904 deletions.
2 changes: 1 addition & 1 deletion cli/src/main/scala/io/github/scalaquest/cli/CLI.scala
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ object CLI {
})
_ <- putStrLn(out)
_ <-
if (!nextState.game.ended) UIO.succeed(nextState) flatMap gameLoop(game, pusher)
if (!nextState.matchState.ended) UIO.succeed(nextState) flatMap gameLoop(game, pusher)
else ZIO.unit
} yield ()

Expand Down
4 changes: 2 additions & 2 deletions core/src/main/scala/io/github/scalaquest/core/Game.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package io.github.scalaquest.core

import io.github.scalaquest.core.model.std.StdModel
import io.github.scalaquest.core.model.behaviorBased.impl.SimpleModel
import io.github.scalaquest.core.model.{Message, Model}
import io.github.scalaquest.core.pipeline.Pipeline.PipelineBuilder

Expand Down Expand Up @@ -35,7 +35,7 @@ object Game {
}

object ExampleUsage {
implicit val model: StdModel.type = StdModel
implicit val model: SimpleModel.type = SimpleModel
val pipelineBuilder: PipelineBuilder[model.S, model.type] = ???

val game: Game[model.type] = Game fromModel model withPipelineBuilder pipelineBuilder
Expand Down
25 changes: 25 additions & 0 deletions core/src/main/scala/io/github/scalaquest/core/model/Action.scala
Original file line number Diff line number Diff line change
@@ -1,3 +1,28 @@
package io.github.scalaquest.core.model

/**
* An action is a base representation of a single 'move' into the Game. To be significant, could be
* associated to one or more [[Model.Item]].
*/
trait Action

/**
* Companion object for the [[Action]] trait, including some commonly actions.
*/
object Action {

/**
* Some commonly used [[Action]] s.
*/
object Common {
import io.github.scalaquest.core.model.Room.Direction

case object Take extends Action
case object Open extends Action
case object Close extends Action
case object Enter extends Action
case object Eat extends Action
case object Inspect extends Action
case class Go(direction: Direction) extends Action
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package io.github.scalaquest.core.model

trait ItemRef

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package io.github.scalaquest.core.model

/**
* Represents the current state of the match.
* @tparam I
* the specific implementation of the [[Model.Item]].
*/
trait MatchState[I <: Model#Item] {

/**
* The player involved into the match. As it is a core concept, an instance of [[Player]] is
* included into the [[MatchState]].
* @return
* The current [[Player]].
*/
def player: Player[I]

/**
* Indicates whether the match has reached the end. When true, the entire match ende after the
* current pipeline round.
* @return
* True if the match has to end after the current round, false otherwise.
*/
def ended: Boolean

/**
* Represents the configuration match, in terms of [[Room]] s and [[Model.Item]].
* @return
* a [[Map]] representing all [[Room]] s of the match, and the [[Model.Item]] s in them.
*/
def geography: Map[Room, Set[I]]
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
package io.github.scalaquest.core.model

/**
* A representation a single line of output to render to the user at the end of the pipeline round.
*/
trait Message
67 changes: 61 additions & 6 deletions core/src/main/scala/io/github/scalaquest/core/model/Model.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,75 @@ trait Model {

type Reaction = S => S

trait State { self: S =>
def game: GameState[I]
/**
* Represents a snapshot of the current game, at an higher level in comparison to [[MatchState]],
* including the state of the game. The key fact is that this level of abstraction can handle also
* [[Message]] s, that is a representation of the output to render to the user at the end of the
* pipeline round.
*/
abstract class State { self: S =>

/**
* The state of the game, in a vision scoped to the [[Player]] capabilities.
*
* @return
* The [[MatchState]] of the match.
*/
def matchState: MatchState[I]

/**
* A representation of the output to render to the user at the end of the pipeline round.
* @return
* A [[Seq]] of [[Message]] s.
*/
def messages: Seq[Message]

/**
* A method that extracts a [[Map]] that links all the [[Item]] inside the [[State]] to their
* [[ItemRef]] s. This should be implemented for each concrete [[Model]] implementation.
* @return
* A [[Map]] from [[ItemRef]] to [[Item]].
*/
def extractRefs: Map[ItemRef, I]
}

trait Item { item: I =>
def use(action: Action, state: S, sideItem: Option[I] = None): Option[Reaction]
/**
* Represents a single object against which the [[Player]] can interact.
*/
abstract class Item { item: I =>

/**
* The unique identifier of the [[Item]]. This is necessary, as passing from a state to another,
* the reference to an object changes, the [[State]] works in an immutable fashion.
*/
def itemRef: ItemRef
override def hashCode(): Int = itemRef.hashCode()

/**
* The hash code of the [[Item]] is overridden in a way that delegates to the Item's [[ItemRef]]
* the creation of the hash code. This enables the possibility of make a match between a same
* [[Item]] from different [[State]] s.
* @return
* The Item's [[ItemRef]] hashcode.
*/
final override def hashCode(): Int = itemRef.hashCode()

/**
* Define a way make the item interact with the [[State]]. The interaction is founded into the
* [[Action]] (ex. 'open the door'), but it can include also an additional [[Item]] ('open the
* door with the key'). The item should react to each combination with an appropriate
* [[Reaction]].
* @param action
* An action from a statement (ex. <b>open</b> the door with a key).
* @param state
* the starting state, useful to give a context to the decision to take.
* @param sideItem
* A side [[Item]] from a statement (ex. open the door with <b>a key</b>).
* @return
*/
def use(action: Action, state: S, sideItem: Option[I] = None): Option[Reaction]
}

trait Ground { ground: G =>
abstract class Ground { ground: G =>
def use(action: Action, state: S): Option[Reaction]
}
}
17 changes: 17 additions & 0 deletions core/src/main/scala/io/github/scalaquest/core/model/Player.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,23 @@
package io.github.scalaquest.core.model

/**
* Represents the main properties of the character impersonated by the user.
* @tparam I
* a subtype of [[Model.Item]], the one effectively used into the model implementation.
*/
trait Player[I <: Model#Item] {

/**
* [[Model.Item]] s that the player brings with him. In a contrete story, this not necessarily a
* real bag: it is simply an intuitive term to refer to this set of items.
* @return
*/
def bag: Set[I]

/**
* The current location of the player into the map.
* @return
* The current location of the player into the map.
*/
def location: Room
}
41 changes: 33 additions & 8 deletions core/src/main/scala/io/github/scalaquest/core/model/Room.scala
Original file line number Diff line number Diff line change
@@ -1,18 +1,43 @@
package io.github.scalaquest.core.model

import io.github.scalaquest.core.model.Direction.Direction
import io.github.scalaquest.core.model.std.StdRoom

object Direction extends Enumeration {
type Direction = Value
val NORTH, SOUTH, WEST, EAST, UP, DOWN = Value
}
import io.github.scalaquest.core.model.Room.Direction

/**
* A geographical portion of the match map.
*
* This is one of the basic block for the story build by the storyteller, as it is used to identify
* [[Player]] 's and [[Model.Item]] s' location, in a given moment of the story.
*/
trait Room {

/**
* A textual identifier for the room.
* @return
* A textual identifier for the room.
*/
def name: String

/**
* Identifies rooms near to the current one, at the cardinal points.
*/
def neighbors(direction: Direction): Option[Room]
}

case class SimpleRoom(name: String, _neighbors: () => Map[Direction, Room]) extends Room {
override def neighbors(direction: Direction): Option[Room] = _neighbors() get direction
}

object Room {
def apply(name: String, neighbors: () => Map[Direction, Room]): Room = StdRoom(name, neighbors)
def apply(name: String, neighbors: () => Map[Direction, Room]): Room = SimpleRoom(name, neighbors)

sealed trait Direction

object Direction {
case object North extends Direction
case object South extends Direction
case object East extends Direction
case object West extends Direction
case object Up extends Direction
case object Down extends Direction
}
}

0 comments on commit 99ba985

Please sign in to comment.