Ludo Game with first-class moves
TL;DR
In order to browse the state of the game over time, we make moves first-class objects.
Motivation
Motivation: our test examples all consist of a setup example and the test case itself.
We would like to be able to see explicitly what the moves are and visualize them.
The driver for the change is the need for visualization.
Views are useful because they document what developers found interesting about the domain objects and how to query them.
Move objects
We start by creating a Move object that encapsulates a token to move and the rolled number of of steps to move.
game := GtLudoGame new. game roll: 6. move := GtLudoMove new roll: 6; token: (game tokenNamed: 'a'); yourself. game
We have changed players so they know their game, and now we can navigate back and forth.
We want to reuse the BoardElement to highlight a token on the board.
token := move token. boardElement := token player game boardElement. (boardElement children select: [ :each | (each isKindOf: GtLudoSquareElement) and: [ each square token = token ] ]) do: #highlight. boardElement
From a token we can navigate to its player, and highlight the player's tokens.
token player
We introduce GtLudoRecordingGame
as a subclass of GtLudoGame
, with first-class moves.
GtLudoRecordingGame new
We add numerous views with highlights for the locations of tokens, squares and players.
A RecordingGame records its moves, and has a view showing the list of recorded moves.
To automatically update views, we should use GtPhlowView>>#updateWhen:in:
For example, see GtLudoGame>>#gtPlayersFor:
, which is automatically updated when the game state is updated.
Recorded Game views
Moves should also record the from and to squares, and the before and after feedback.
This can be displayed in the game view.
We can subclass the GameExamples class to create the same examples for the recorded games.
game := GtLudoRecordingGame new. game roll: 6. game moveTokenNamed: 'a'. game roll: 6. game moveTokenNamed: 'A'.
Autoplay
We introduce GtLudoRecordingGame>>#autoPlay:
and storeOn:
game := GtLudoRecordingGame new.