

We already implemented 3 of 8 rules, those three already model the main game rules, the “non-interactive” things: boards, cards and deck; what we need next are the “interactive” things: players and their actions. Specifically we must implement the following:
Diff implementing this iteration.
From reading the requirements we can tell there are two subjects: Caller
and Player
, the Caller
is the one announcing the game (orchestrating the game and publishing the called cards) and the Player
s are the ones listening (are subscribed) to the game. (Please notice I will not cover the specific event handlers in this iteration, I will do that next time).
Taking those requirements we can model two concrete subjects accordingly, first one is the Caller which acts a game host, it does the following:
Players have to listen to the announced cards
,There are N players, each player is given one Tabla (Board)
and Given tablas are unique during the duration of the game
,Announcer is in charge of randomly selecting cards from the deck
, andThe winner is determined by the first player who shouts "LOTERIA"
.The second one is the Player:
Each player is given one Tabla (Board)
and Given tablas are unique during the duration of the game
,Players have to listen to the announced cards and mark them on their boards
, andThe winner is determined by the first player who shouts "LOTERIA!"
.To satisfy the requirements the Caller
requires keeping track of:
Deck
of shuffled cards: to properly announce the cards,Players
playing the game, to properly determine the winner,Boards
assigned to the players: to properly assign unique boards and determine the winner,For shuffling and announcing cards the original Deck
type was converted into a struct, and Shuffe()
and Select()
methods were implemented.
A new Player
type was added, this is a simple one so far, what’s important is that the Caller
keeps that of those in a map by using their unique name.
To determine the uniqueness of the Board
s, a new method was added:
func (b *Board) ID() BoardID {
if b.id != 0 {
return b.id
}
var res uint64
for c := range b.cardsMap {
res |= 1 << uint64(c)
}
b.id = BoardID(res)
return b.id
}
Recall we keep track of the added cards on the board, and each board represents an int64
with one bit enabled, so we can easily determine the unique ID using bit masking again. Keeping that information in a map
allows to satisfy the uniqueness requirement, not to mention that the same map
is used to mark off our already assigned boards to later determine if the player is really a winner.
To satisfy the requirements, the Player
requires doing two things:
Board
, andThis type, so far, is a simple one, it basically delegates both actions to the Board which already implements them.
Like I mentioned in the beginning this still requires a bit of event publishing and subscription to properly simulate a real game, however the current code implements successfully the business requirements, there’s a command already available that runs all of this. Feel free to check it out.
It looks like we made significant progress!! Let’s take a break for now, digest everything and come back tomorrow.