Skip to content

Commit

Permalink
chore: refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
alemazzo committed Oct 13, 2023
1 parent dd21f02 commit 48fcd4e
Show file tree
Hide file tree
Showing 60 changed files with 736 additions and 373 deletions.
87 changes: 85 additions & 2 deletions src/main/scala/scatan/controllers/game/GameController.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,107 @@ import scatan.model.game.config.ScatanPlayer
import scatan.model.map.{Hexagon, RoadSpot, StructureSpot}
import scatan.views.game.GameView

/** The controller for the game.
*/
trait GameController extends Controller[ApplicationState]:
def state: ApplicationState

/** Goes to the next turn. */
def nextTurn(): Unit

/** Rolls the dice. */
def rollDice(): Unit

/** Assigns a road to the current player.
* @param spot
* The spot to assign the road to.
*/
def assignRoad(spot: RoadSpot): Unit

/** Assigns a settlement to the current player.
* @param spot
* The spot to assign the settlement to.
*/
def assignSettlement(spot: StructureSpot): Unit

/** Builds a road for the current player.
* @param spot
* The spot to build the road on.
*/
def buildRoad(spot: RoadSpot): Unit

/** Builds a settlement for the current player.
* @param spot
* The spot to build the settlement on.
*/
def buildSettlement(spot: StructureSpot): Unit

/** Builds a city for the current player.
* @param spot
* The spot to build the city on.
*/
def buildCity(spot: StructureSpot): Unit

/** Places the robber on a hexagon.
* @param hexagon
* The hexagon to place the robber on.
*/
def placeRobber(hexagon: Hexagon): Unit
def nextTurn(): Unit
def rollDice(): Unit

/** Steals a card from a player.
* @param player
* The player to steal a card from.
*/
def stealCard(player: ScatanPlayer): Unit

/** Buys a development card for the current player.
*/
def buyDevelopmentCard(): Unit

/** Plays a knight development card for the current player.
* @param robberPosition
* The hexagon to place the robber on.
*/
def playKnightDevelopment(robberPosition: Hexagon): Unit

/** Plays a year of plenty development card for the current player.
* @param resource1
* The first resource to get.
* @param resource2
* The second resource to get.
*/
def playYearOfPlentyDevelopment(resource1: ResourceType, resource2: ResourceType): Unit

/** Plays a monopoly development card for the current player.
* @param resource
* The resource to get.
*/
def playMonopolyDevelopment(resource: ResourceType): Unit

/** Plays a road building development card for the current player.
* @param spot1
* The first spot to build a road on.
* @param spot2
* The second spot to build a road on.
*/
def playRoadBuildingDevelopment(spot1: RoadSpot, spot2: RoadSpot): Unit

/** Trades with the bank.
* @param offer
* The resource to offer.
* @param request
* The resource to request.
*/
def tradeWithBank(offer: ResourceType, request: ResourceType): Unit

/** Trades with a player.
* @param receiver
* The player to trade with.
* @param offer
* The cards to offer.
* @param request
* The cards to request.
*/
def tradeWithPlayer(receiver: ScatanPlayer, offer: Seq[ResourceCard], request: Seq[ResourceCard]): Unit

object GameController:
Expand Down
25 changes: 10 additions & 15 deletions src/main/scala/scatan/controllers/game/SetUpController.scala
Original file line number Diff line number Diff line change
@@ -1,26 +1,21 @@
package scatan.controllers.game

import scatan.lib.mvc.{BaseController, Controller}
import scatan.lib.mvc.{Controller, EmptyController}
import scatan.model.ApplicationState
import scatan.views.game.SetUpView

/** This is the controller for the setup page.
/** The controller for the game setup screen.
*/
trait SetUpController extends Controller[ApplicationState]:

/** Starts the game with the given usernames.
* @param usernames,
* the usernames of the players.
*/
def startGame(usernames: String*): Unit

object SetUpController:
def apply(requirements: Controller.Requirements[SetUpView, ApplicationState]): SetUpController =
SetUpControllerImpl(requirements)

/** This is the implementation of the controller for the setup page.
* @param requirements,
* the requirements for the controller.
*/
private class SetUpControllerImpl(requirements: Controller.Requirements[SetUpView, ApplicationState])
extends BaseController(requirements)
with SetUpController:

override def startGame(usernames: String*): Unit =
this.model
.update(_.createGame(usernames*))
new EmptyController(requirements) with SetUpController:
override def startGame(usernames: String*): Unit =
this.model.update(_.createGame(usernames*))
10 changes: 4 additions & 6 deletions src/main/scala/scatan/controllers/home/AboutController.scala
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
package scatan.controllers.home

import scatan.lib.mvc.{BaseController, Controller}
import scatan.lib.mvc.{Controller, EmptyController}
import scatan.model.ApplicationState
import scatan.views.home.AboutView

/** The about page controller.
*/
trait AboutController extends Controller[ApplicationState]

object AboutController:
def apply(requirements: Controller.Requirements[AboutView, ApplicationState]): AboutController =
AboutControllerImpl(requirements)

private class AboutControllerImpl(requirements: Controller.Requirements[AboutView, ApplicationState])
extends BaseController(requirements)
with AboutController
new EmptyController(requirements) with AboutController
14 changes: 3 additions & 11 deletions src/main/scala/scatan/controllers/home/HomeController.scala
Original file line number Diff line number Diff line change
@@ -1,21 +1,13 @@
package scatan.controllers.home

import scatan.lib.mvc.{BaseController, Controller}
import scatan.lib.mvc.{Controller, EmptyController}
import scatan.model.ApplicationState
import scatan.views.home.HomeView

/** This is the controller for the home page.
/** The home page controller.
*/
trait HomeController extends Controller[ApplicationState]

object HomeController:
def apply(requirements: Controller.Requirements[HomeView, ApplicationState]): HomeController =
HomeControllerImpl(requirements)

/** This is the implementation of the controller for the home page.
* @param requirements,
* the requirements for the controller.
*/
class HomeControllerImpl(requirements: Controller.Requirements[HomeView, ApplicationState])
extends BaseController(requirements)
with HomeController
new EmptyController(requirements) with HomeController
4 changes: 3 additions & 1 deletion src/main/scala/scatan/lib/game/ops/GamePlayOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -58,5 +58,7 @@ object GamePlayOps:
else newGame

extension (bool: Boolean)
def option: Option[Unit] =
/** Convert a boolean to an option, returning Some(()) if true, None if false
*/
private def option: Option[Unit] =
if bool then Some(()) else None
97 changes: 0 additions & 97 deletions src/main/scala/scatan/lib/game/ops/RulesOps.scala

This file was deleted.

24 changes: 23 additions & 1 deletion src/main/scala/scatan/lib/mvc/Controller.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,29 @@ object Controller:
trait Provider[C <: Controller[?]]:
def controller: C

/** A wrapper for a model that updates the view when the model is updated.
* @param view
* The view to update
* @param model
* The model to wrap
* @tparam S
* The state type
*/
class ReactiveModelWrapper[S <: Model.State](view: => View[S], model: Model[S]) extends Model[S]:
private val internalModel = model
override def state: S = internalModel.state
override def update(f: S => S): Unit =
internalModel.update(f)
view.updateState(this.state)

/** A base controller that wraps a model and a view.
* @param requirements
* The requirements for the controller
* @tparam V
* The view type
* @tparam S
* The state type
*/
abstract class BaseController[V <: View[S], S <: Model.State](requirements: Controller.Requirements[V, S])
extends Controller[S]
with Controller.Dependencies(requirements):
Expand All @@ -31,5 +47,11 @@ abstract class BaseController[V <: View[S], S <: Model.State](requirements: Cont
override protected val model: Model[S] =
new ReactiveModelWrapper(requirements.view, requirements.model)

class EmptyController[State <: Model.State](requirements: Controller.Requirements[View[State], State])
/** A controller that does nothing.
* @param requirements
* The requirements for the controller
* @tparam State
* The state type
*/
class EmptyController[State <: Model.State, V <: View[State]](requirements: Controller.Requirements[V, State])
extends BaseController(requirements)
8 changes: 6 additions & 2 deletions src/main/scala/scatan/lib/mvc/Model.scala
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
package scatan.lib.mvc

/** A model is a container for a state object. It provides a way to update the state object.
* @tparam S
* The type of the state object.
*/
trait Model[S <: Model.State]:
def state: S
def update(f: S => S): Unit

object Model:
trait State
def apply[S <: State](__state: S): Model[S] =
def apply[S <: State](initialState: S): Model[S] =
new Model[S]:
private var _state = __state
private var _state = initialState
override def state: S = _state
override def update(f: S => S): Unit = _state = f(_state)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ package scatan.lib.mvc

import scatan.lib.mvc.application.NavigableApplication

/** A singleton object that manages the currently running application. It is used to start the application and to
* navigate to a new route. It is also used to navigate back to the previous route.
*/
object NavigableApplicationManager:
private var _application: Option[NavigableApplication[?, ?]] = None

Expand Down
Loading

0 comments on commit 48fcd4e

Please sign in to comment.