After today’s pairing session I did not feel quite satisfied yet. We had a bit of a gap between where I ended yesterday and where she ended yesterday, so I didn’t get to do any coding. I decided to get some coding done through katas on code wars and got especially interested in creating a game of ladders and snakes. I am going to assume that you know the rules of the game, if not this is the kata I worked on; https://www.codewars.com/kata/587136ba2eefcb92a9000027/train/ruby.
I got started with a class I called Turns.
describe Turns do
let(:turn) { Turns.new }
describe ‘#count_dice’ do
it ‘should count up the dice’ do
expect(turn.count_dice(3, 3)).to eq 6
end
end
describe ‘#equal?’ do
it ‘should know if the value of both dice is equal’ do
expect(turn.equal?(3, 3)).to eq true
end
it ‘should know if the value is not equal’ do
expect(turn.equal?(4, 2)).to eq false
end
end
end
This would be quite a simple class, but very important for the game. The class can count up the dice, assuming you throw two dice, and it can see if the two dice are the same, or if they are different.
class Turns
attr_reader :die1, :die2
def count_dice(die1, die2)
[die1, die2].sum
end
def equal?(die1, die2)
die1 == die2
end
end
Next, I took a look at a class that I would call Player, this is going to be each player, they can make the moves on the board.
describe Player do
let(:player) { Player.new }
describe ‘#next_player?’ do
it ‘should decide if the player can go again’ do
expect(player.next_player?(1, 1)).to eq false
end
it ‘should know the next player can go’ do
expect(player.next_player?(4, 1 )).to eq true
end
end
describe ‘#location’ do
it ‘should know its current location’ do
expect(player.location).to eq 0
end
end
describe ‘#move’ do
it ‘should ba able ot make a normal move’ do
expect(player.move(1, 4)).to eq 5
end
it ‘should be able to move its location with ladder’ do
player.move(4, 2)
expect(player.location).to eq 6
end
it ‘should be able to move its location with snake’ do
expect(player.move(45, 1)).to eq 25
end
end
describe ‘#finish’ do
it ‘should know when the player has won’ do
expect(player.move(98, 2)).to eq ‘Congratz! You won’
end
end
describe ‘#near_the_end’ do
it ‘should go backwards if gone over 100’ do
expect(player.move(98, 4)).to eq 98
end
end
end
To make the move, we have to know where the snakes and ladders are as well. I gave them to this class as a constant, because all games of snakes and ladders should be the same.
class Player
LOCATION_LADDERS = {
2 => 38, 7 => 14, 8 => 31, 15 => 26, 21 => 42, 36 => 44, 51 => 67, 71 => 91, 78 => 98, 87 => 94
}
LOCATION_SNAKES = {
16 => 6, 46 => 25, 49 => 11, 62 => 19, 64 => 60, 74 => 53, 89 => 68, 92 => 88, 95 => 75, 99 => 80
}
attr_reader :location
def initialize(location = 0)
@location = location
@turn = Turns.new
@moving_back = 0
end
def move(die1, die2)
@location = [@location += @turn.count_dice(die1, die2), LOCATION_LADDERS[@location], LOCATION_SNAKES[@location]].compact.last
near_the_end
congratz
end
def ladders_or_snakes
[@location += @turn.count_dice(die1, die2), LOCATION_LADDERS[@location], LOCATION_SNAKES[@location]].compact.last
end
def next_player?(die1, die2)
!@turn.equal?(die1, die2)
end
def finish
@location == 100
end
def congratz
finish ? “Congratz! You won” : @location
end
def near_the_end
@location >= 100 ? @location -= ((@location — 100) * 2) : @location
end
end
Lastly, I wanted to bring it all together in a SnakesAndLadders class, that would call for all the methods in the right order.
describe SnakesAndLadders do
let(:game) { SnakesAndLadders.new }
let(:player) { Player.new }
describe ‘#player1_’ do
let(:die1) { 1 }
let(:die2) { 1 }
it ‘should roll dice and move a piece for a player’ do
expect(game.player1_(die1, die2)).to eq “Player 1 is on square #{player.move(die1,die2)}”
end
end
describe ‘#player2_’ do
let(:die1) { 4 }
let(:die2) { 1 }
it ‘should roll dice and move player 2’ do
expect(game.player2_(die1, die2)).to eq “Player 2 is on square #{player.move(die1, die2)}”
end
end
describe ‘#switch_turn’ do
it ‘should switch whose turn it is’ do
player1 = Player.new
game.player1_(1, 4)
expect(game.turn)
end
end
describe ‘#game_over’ do
it ‘should say game over if a player has won’ do
game.play(98, 2)
expect(game.play(5, 1)).to eq ‘Game over’
end
end
end
describe Player do
let(:player) { Player.new }
describe ‘#next_player?’ do
it ‘should decide if the player can go again’ do
expect(player.next_player?(1, 1)).to eq false
end
it ‘should know the next player can go’ do
expect(player.next_player?(4, 1 )).to eq true
end
end
describe ‘#location’ do
it ‘should know its current location’ do
expect(player.location).to eq 0
end
end
describe ‘#move’ do
it ‘should ba able ot make a normal move’ do
expect(player.move(1, 4)).to eq 5
end
it ‘should be able to move its location with ladder’ do
player.move(4, 2)
expect(player.location).to eq 6
end
it ‘should be able to move its location with snake’ do
expect(player.move(45, 1)).to eq 25
end
end
describe ‘#finish’ do
it ‘should know when the player has won’ do
expect(player.move(98, 2)).to eq ‘Congratz! You won’
end
end
describe ‘#near_the_end’ do
it ‘should go backwards if gone over 100’ do
expect(player.move(98, 4)).to eq 98
end
end
end
This class will also return to us what location our players are on after each move, and shout game over if a player won, and the other keeps going.
class SnakesAndLadders
attr_reader :turn
def initialize
@player1 = Player.new
@player2 = Player.new
@turn = @player1
end
def play(die1, die2)
@turn == @player1 ? player1_(die1, die2) : player2_(die1, die2)
end
def player1_(die1, die2)
moved = @player1.move(die1, die2)
return ‘Game over’ if @player2.finish
switch_turn(die1, die2)
“Player 1 is on square #{moved}”
end
def player2_(die1, die2)
moved = @player2.move(die1, die2)
return ‘Game over’ if @player1.finish
switch_turn(die1, die2)
“Player 2 is on square #{moved}”
end
def switch_turn(die1, die2)
if @turn == @player1 && @player1.next_player?(die1, die2)
@turn = @player2
elsif @turn == @player2 && @player2.next_player?(die1, die2)
@turn = @player1
end
end
end
This is what I did today. It does not seem to be working perfectly quite yet, but my brain cannot take anything more today. I will update the git once I have the energy to improve it. You can find that here: https://github.com/Emmapr123/snakes_and_ladders