Skip to content

Instantly share code, notes, and snippets.

@thutch
Created March 27, 2012 01:28
Show Gist options
  • Save thutch/2211500 to your computer and use it in GitHub Desktop.
Save thutch/2211500 to your computer and use it in GitHub Desktop.
Ruby Mancala
class Well
attr_accessor :next_well, :seeds, :game
def initialize game
self.seeds = 0
self.game = game
self.game.wells << self
end
def sow
current_seeds = self.seeds
self.seeds = 0
self.next_well.take_seed current_seeds
self.game.determine_winner
end
def take_seed count
self.seeds += 1
count = count - 1
self.next_well.take_seed count if count > 0
end
end
class GoalWell < Well
attr_accessor :owner
def take_seed count
if game.turn == self.owner
super
else
self.next_well.take_seed count
end
end
end
class Game
attr_accessor :wells, :winner, :turn
def initialize
self.wells = Array.new
end
def determine_winner
if self.ended?
return if !self.player1_goal_well
return if !self.player2_goal_well
if self.player1_goal_well.seeds > self.player2_goal_well.seeds
self.winner = :player1
return
end
if self.player2_goal_well.seeds > self.player1_goal_well.seeds
self.winner = :player2
return
end
self.winner = :tie
end
end
def ended?
self.playable_wells
.map { |w| w.seeds }
.inject { |sum, n| sum + n } == 0
end
def playable_wells
self.wells.find_all { |w| w.instance_of? Well }
end
def player1_goal_well
self.goal_well_for :player1
end
def player2_goal_well
self.goal_well_for :player2
end
def goal_well_for player
self.wells.find { |w| w.instance_of? GoalWell and w.owner == player }
end
end
require './kata.rb'
describe "sowing" do
before(:each) do
@game = Game.new
@well1 = Well.new @game
@well2 = Well.new @game
@well1.next_well = @well2
@well2.next_well = @well1
end
it "sowing 1 seed across 2 wells" do
@well1.seeds = 1
@well1.sow
@well2.seeds.should == 1
@well1.seeds.should == 0
end
it "sowing 2 seed across 2 wells" do
@well1.seeds = 2
@well1.sow
@well2.seeds.should == 1
@well1.seeds.should == 1
end
it "sowing 3 seed across 2 wells" do
@well1.seeds = 3
@well1.sow
@well2.seeds.should == 2
@well1.seeds.should == 1
end
end
describe "end game" do
before(:each) do
@game = Game.new
@well1 = Well.new @game
@goal_well = GoalWell.new @game
@goal_well.owner = :player1
@well2 = Well.new @game
@well1.next_well = @goal_well
@goal_well.next_well = @well2
@well2.next_well = @well1
end
it "game ends if no one can sow seeds" do
@game.turn = :player1
@well1.seeds = 1
@well1.sow
@well1.game.ended?.should be_true
end
it "game continues if there are seeds to sow" do
@game.turn = :player1
@well1.seeds = 2
@well1.sow
@well1.game.ended?.should be_false
end
it "game continues if there are seeds to sow" do
@game.turn = :player1
@well1.seeds = 3
@well1.sow
@well1.game.ended?.should be_false
end
end
describe "winner" do
before(:each) do
@game = Game.new
@well1 = Well.new @game
@goal_well = GoalWell.new @game
@goal_well.owner = :player1
@well2 = Well.new @game
@goal_well_2 = GoalWell.new @game
@goal_well_2.owner = :player2
@well1.next_well = @goal_well
@goal_well.next_well = @well2
@well2.next_well = @goal_well_2
@goal_well_2.next_well = @well1
end
it "player one wins" do
@game.turn = :player1
@well1.seeds = 1
@well1.sow
@well1.game.winner.should == :player1
end
it "player two wins" do
@game.turn = :player2
@well2.seeds = 1
@well2.sow
@game.winner.should == :player2
end
it "tie" do
@game.turn = :player1
@well1.seeds = 1
@well2.seeds = 1
@well1.sow
@game.turn = :player2
@well2.sow
@game.winner.should == :tie
end
end
describe "goal well" do
before(:each) do
@game = Game.new
@well1 = Well.new @game
@goal_well = GoalWell.new @game
@goal_well.owner = :player1
@well2 = Well.new @game
@goal_well_2 = GoalWell.new @game
@goal_well_2.owner = :player2
@well1.next_well = @goal_well
@goal_well.next_well = @well2
@well2.next_well = @goal_well_2
@goal_well_2.next_well = @well1
end
it "player 2's well is skipped on player 1's turn" do
@game.turn = :player1
@well1.seeds = 3
@well1.sow
@goal_well_2.seeds.should == 0
@well1.seeds.should == 1
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment