matatena = Game()
assert not matatena.is_done()
matatenaPlayer 1 *
[[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]
Player 2
[[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]
Knucklebones is a simple game in which a dice is rolled and one of the two players must place it in their corresponding board. Each player can only choose the column in which the dice is placed, and if any dice is already placed in that column, the following is put behind. If there are more than one dice with the same number, their score is added and then multiplied by the number of times it appears. For example, if a column has two 6s, their values add up to 24, but if a column has a 6 and a 5, the total score would be 11.
The basic board is a 3x3 grid.
Each game board (one for each player) can be represented, for example, with a np.array. But we may probably benefit from having a “global” object that controls both of the players to keep track of both boards and the score in a more simple manner.
Game (n_players=2, board_size=3)
Class that controls the whole game. It keeps track of both boards.
| Type | Default | Details | |
|---|---|---|---|
| n_players | int | 2 | Number of players. |
| board_size | int | 3 | Size of the board. It is a squared grid of board_sizexboard_size |
Player 1 *
[[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]
Player 2
[[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]
matatena = Game()
matatena.boards[1] = np.ones_like(matatena.boards[1])
assert matatena.is_done()
matatenaPlayer 1 *
[[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]
Player 2
[[1. 1. 1.]
[1. 1. 1.]
[1. 1. 1.]]
matatena = Game()
matatena.add_dice(player=0, column=0, dice=6)
print(matatena)
matatena.add_dice(player=0, column=0, dice=6)
print(matatena)Player 1 *
[[6. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]
Player 2
[[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]
Player 1 *
[[6. 0. 0.]
[6. 0. 0.]
[0. 0. 0.]]
Player 2
[[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]
matatena = Game()
matatena.add_dice(player=0, column=0, dice=6)
matatena.add_dice(player=0, column=0, dice=6)
matatena.add_dice(player=0, column=0, dice=6)
# matatena.add_dice(player=0, column=0, dice=6)False
matatena = Game()
matatena.current_player = 0
matatena.boards[1] = np.ones_like(matatena.boards[1])
print(matatena)
matatena.add_dice(player=0, column=0, dice=1)
assert not (matatena.boards[1][:,0] == 1).any()
matatenaPlayer 1 *
[[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]
Player 2
[[1. 1. 1.]
[1. 1. 1.]
[1. 1. 1.]]
Player 1 *
[[1. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]
Player 2
[[0. 1. 1.]
[0. 1. 1.]
[0. 1. 1.]]
Game.score (player)
Returns the calculated score for a player. If there are numbers repeated in a column, their values must be added and multiplied by the number of repetitions. Otherwise, they are added. If there are repreated and non-repeated in the same column, the repeated are summed and multiplied by the number of repetitions and then the result is added to the non-repeated.
| Details | |
|---|---|
| player | Number of the player we want to calculate the score. |
Now that we know how to calculate the score, we can patch the __repr__ method of our class to show the score of each player as well:
Player 1 (0.0) *
[[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]
Player 2 (0.0)
[[0. 0. 0.]
[0. 0. 0.]
[0. 0. 0.]]
A full turn in a Matatena game must follow the following steps:
Game.play_turn ()
Plays a full turn.
matatena = Game()
print(matatena.current_player)
matatena.play_turn()
# The player is asked for an input and the rolled dice is placed
# in the chosen column.
print(matatena.current_player)
matatena0
Dice to place: 6
Player 1 (0.0) * | Player 2 (0.0)
[[0. 0. 0.] | [[0. 0. 0.]
[0. 0. 0.] | [0. 0. 0.]
[0. 0. 0.]] | [0. 0. 0.]]
0
Player 1 (6.0) * | Player 2 (0.0)
[[6. 0. 0.] | [[0. 0. 0.]
[0. 0. 0.] | [0. 0. 0.]
[0. 0. 0.]] | [0. 0. 0.]]