""" 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())