"""
Student facing implement of solitaire version of Mancala - Tchoukaillon
Goal: Move as many seeds from given houses into the store
In GUI, you make ask computer AI to make move or click to attempt a legal move
"""
class SolitaireMancala:
"""
Simple class that implements Solitaire Mancala
"""
def __init__(self):
"""
Create Mancala game with empty store and no houses
"""
self.configuration = [0]
def set_board(self, configuration):
"""
Take the list configuration of initial number of seeds for given houses
house zero corresponds to the store and is on right
houses are number in ascending order from right to left
"""
self.configuration = configuration
print "Setting Board: "
print self.configuration
def __str__(self):
"""
Return string representation for Mancala board
"""
view_config = []
for index in self.configuration:
view_config.append(index)
view_config.reverse()
return str(view_config)
def get_num_seeds(self, house_num):
"""
Return the number of seeds in given house on board
"""
return self.configuration[house_num]
def is_game_won(self):
"""
Check to see if all houses but house zero are empty
"""
return self.configuration[1:].count(0) == len(self.configuration[1:])
def is_legal_move(self, house_num):
"""
Check whether a given move is legal
"""
return self.configuration[house_num] == house_num
def apply_move(self, house_num):
"""
Move all of the stones from house to lower/left houses
Last seed must be played in the store (house zero)
"""
i = 0
while i < house_num:
self.configuration[i] += 1
i += 1
self.configuration[house_num] = 0
def choose_move(self):
"""
Return the house for the next shortest legal move
Shortest means legal move from house closest to store
Note that using a longer legal move would make smaller illegal
If no legal move, return house zero
"""
seed_index = 1
for seeds in self.configuration[1:]:
if seed_index == seeds:
return seed_index
else:
seed_index += 1
return 0
def plan_moves(self):
"""
Return a sequence (list) of legal moves based on the following heuristic:
After each move, move the seeds in the house closest to the store
when given a choice of legal moves
Not used in GUI version, only for machine testing
"""
move_list = []
test_game = SolitaireMancala()
test_config = []
for seeds in self.configuration:
test_config.append(seeds)
test_game.set_board(test_config)
while not test_game.is_game_won() and test_game.choose_move() != 0:
move_list.append(test_game.choose_move())
test_game.apply_move(move_list[-1])
return move_list
# Create tests to check the correctness of your code
def test_mancala():
"""
Test code for Solitaire Mancala
"""
my_game = SolitaireMancala()
print "Testing init - Computed:", my_game, "Expected: [0]"
config1 = [0, 1, 1, 1, 3, 5, 0]
my_game.set_board(config1)
# print "Testing set_board - Computed:", str(my_game), "Expected:", str([0, 5, 3, 1, 1, 0, 0])
# print "Testing get_num_seeds - Computed:", my_game.get_num_seeds(1), "Expected:", config1[1]
# print "Testing get_num_seeds - Computed:", my_game.get_num_seeds(3), "Expected:", config1[3]
# print "Testing get_num_seeds - Computed:", my_game.get_num_seeds(5), "Expected:", config1[5]
# # add more tests here
# print "Testing is_legal_move - Computed:", my_game.is_legal_move(5), "Expected True"
# print "Testing is_legal_move - Computed:", my_game.is_legal_move(1), "Expected False"
# print "Testing is_game_won - Computed:", my_game.is_game_won(), "Expected False"
# print "Testing choose_move - Computed:", my_game.choose_move(), "Expected: 1"
# print "Testing plan_moves - Computed:", my_game.plan_moves(), "Expected: [1,5]"
print str(my_game) + "<< Store"
my_moves = my_game.plan_moves()
print "Move Plan: " + str(my_moves)
my_game.apply_move(my_moves[1])
print my_game
test_mancala()
#Import GUI code once you feel your code is correct
import poc_mancala_gui
poc_mancala_gui.run_gui(SolitaireMancala())
Comments