refactoring
This commit is contained in:
79
src/main/kotlin/eventDemo/app/event/CardIsPlayedEvent.kt
Normal file
79
src/main/kotlin/eventDemo/app/event/CardIsPlayedEvent.kt
Normal file
@@ -0,0 +1,79 @@
|
||||
package eventDemo.app.event
|
||||
|
||||
import eventDemo.app.GameId
|
||||
import eventDemo.app.entity.Card
|
||||
import eventDemo.app.entity.Deck
|
||||
import eventDemo.app.entity.Player
|
||||
import eventDemo.libs.event.Event
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* An [Event] of a Game.
|
||||
*/
|
||||
@Serializable
|
||||
sealed interface GameEvent : Event<GameId> {
|
||||
override val id: GameId
|
||||
}
|
||||
|
||||
/**
|
||||
* An [Event] to represent a played card.
|
||||
*/
|
||||
data class CardIsPlayedEvent(
|
||||
override val id: GameId,
|
||||
val card: Card,
|
||||
val player: Player,
|
||||
) : GameEvent
|
||||
|
||||
/**
|
||||
* An [Event] to represent a new player joining the game.
|
||||
*/
|
||||
data class NewPlayerEvent(
|
||||
override val id: GameId,
|
||||
val player: Player,
|
||||
) : GameEvent
|
||||
|
||||
/**
|
||||
* This [Event] is sent when a player is ready.
|
||||
*/
|
||||
data class PlayerReadyEvent(
|
||||
override val id: GameId,
|
||||
val player: Player,
|
||||
) : GameEvent
|
||||
|
||||
/**
|
||||
* This [Event] is sent when a player is ready.
|
||||
*/
|
||||
data class GameStartedEvent(
|
||||
override val id: GameId,
|
||||
val firstPlayer: Player,
|
||||
val deck: Deck,
|
||||
) : GameEvent {
|
||||
companion object {
|
||||
fun new(
|
||||
id: GameId,
|
||||
players: Set<Player>,
|
||||
): GameStartedEvent =
|
||||
GameStartedEvent(
|
||||
id = id,
|
||||
firstPlayer = players.random(),
|
||||
deck = Deck.initHands(players).putOneCardOnDiscard(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This [Event] is sent when a player can play.
|
||||
*/
|
||||
data class PlayerHavePassEvent(
|
||||
override val id: GameId,
|
||||
val player: Player,
|
||||
) : GameEvent
|
||||
|
||||
/**
|
||||
* This [Event] is sent when a player chose a color.
|
||||
*/
|
||||
data class PlayerChoseColorEvent(
|
||||
override val id: GameId,
|
||||
val player: Player,
|
||||
val color: Card.Color,
|
||||
) : GameEvent
|
||||
8
src/main/kotlin/eventDemo/app/event/GameEventBus.kt
Normal file
8
src/main/kotlin/eventDemo/app/event/GameEventBus.kt
Normal file
@@ -0,0 +1,8 @@
|
||||
package eventDemo.app.event
|
||||
|
||||
import eventDemo.app.GameId
|
||||
import eventDemo.libs.event.EventBus
|
||||
|
||||
class GameEventBus(
|
||||
bus: EventBus<GameEvent, GameId>,
|
||||
) : EventBus<GameEvent, GameId> by bus
|
||||
18
src/main/kotlin/eventDemo/app/event/GameEventStream.kt
Normal file
18
src/main/kotlin/eventDemo/app/event/GameEventStream.kt
Normal file
@@ -0,0 +1,18 @@
|
||||
package eventDemo.app.event
|
||||
|
||||
import eventDemo.app.GameId
|
||||
import eventDemo.libs.event.EventBus
|
||||
import eventDemo.libs.event.EventStream
|
||||
|
||||
/**
|
||||
* A stream to publish and read the played card event.
|
||||
*/
|
||||
class GameEventStream(
|
||||
private val eventBus: EventBus<GameEvent, GameId>,
|
||||
private val m: EventStream<GameEvent, GameId>,
|
||||
) : EventStream<GameEvent, GameId> by m {
|
||||
override fun publish(event: GameEvent) {
|
||||
m.publish(event)
|
||||
eventBus.publish(event)
|
||||
}
|
||||
}
|
||||
72
src/main/kotlin/eventDemo/app/event/GameStateBuilder.kt
Normal file
72
src/main/kotlin/eventDemo/app/event/GameStateBuilder.kt
Normal file
@@ -0,0 +1,72 @@
|
||||
package eventDemo.app.event
|
||||
|
||||
import eventDemo.app.GameId
|
||||
import eventDemo.app.GameState
|
||||
import eventDemo.app.entity.Card
|
||||
import eventDemo.libs.event.EventStream
|
||||
|
||||
fun GameId.buildStateFromEventStream(eventStream: EventStream<GameEvent, GameId>): GameState =
|
||||
buildStateFromEvents(
|
||||
eventStream.readAll(this),
|
||||
)
|
||||
|
||||
private fun GameId.buildStateFromEvents(events: List<GameEvent>): GameState =
|
||||
events.fold(GameState(this)) { state: GameState, event: GameEvent ->
|
||||
when (event) {
|
||||
is CardIsPlayedEvent -> {
|
||||
val direction =
|
||||
when (event.card) {
|
||||
is Card.ReverseCard -> state.direction.revert()
|
||||
else -> state.direction
|
||||
}
|
||||
|
||||
val color =
|
||||
when (event.card) {
|
||||
is Card.ColorCard -> event.card.color
|
||||
else -> state.lastColor
|
||||
}
|
||||
|
||||
state.copy(
|
||||
lastPlayer = event.player,
|
||||
direction = direction,
|
||||
lastColor = color,
|
||||
)
|
||||
}
|
||||
|
||||
is NewPlayerEvent -> {
|
||||
if (state.isReady) error("The game is already started")
|
||||
|
||||
state.copy(
|
||||
players = state.players + event.player,
|
||||
)
|
||||
}
|
||||
|
||||
is PlayerReadyEvent -> {
|
||||
state.copy(
|
||||
readyPlayers = state.readyPlayers + event.player,
|
||||
)
|
||||
}
|
||||
|
||||
is PlayerHavePassEvent -> {
|
||||
state.copy(
|
||||
lastPlayer = event.player,
|
||||
)
|
||||
}
|
||||
|
||||
is PlayerChoseColorEvent -> {
|
||||
state.copy(
|
||||
lastColor = event.color,
|
||||
)
|
||||
}
|
||||
|
||||
is GameStartedEvent -> {
|
||||
state.copy(
|
||||
lastColor = (event.deck.discard.first() as? Card.ColorCard)?.color,
|
||||
lastCard = eventDemo.app.GameState.LastCard(event.deck.discard.first(), event.firstPlayer),
|
||||
lastPlayer = event.firstPlayer,
|
||||
deck = event.deck,
|
||||
isStarted = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user