class Game(object): NEXT_PLAYER = "NP" SAME_PLAYER_AGAIN = "SPA" GAME_OVER = "GO" def __init__(self): self.board = Board() self.catched_rule = LastGemInEmptyOwnPit(self.board) self.home_rule = LastGemInHomeRule(self.board) self.last_turn_player = None self.last_turn_status = None self.turn = 0 def make_turn(self, player, pit): self.turn += 1 self.last_turn_player = player self.last_turn_status = self._make_turn(player, pit) return self.last_turn_status def _make_turn(self, player, pit): last_gem_pos = self.board.take_and_put_gems(player, pit) assert last_gem_pos is not None # check for a catch if self.catched_rule.matches(player, last_gem_pos): self.board.catch_gems(player, last_gem_pos.pit) return Game.NEXT_PLAYER if self.home_rule.matches(player, last_gem_pos): return Game.SAME_PLAYER_AGAIN if self.board.all_pits_empty(): return Game.GAME_OVER return Game.NEXT_PLAYER @staticmethod def other_player(player): return Board.other_player(player) def get_next_player(self, current_player, turn_result): if turn_result == Game.NEXT_PLAYER: return self.other_player(current_player) elif turn_result == Game.SAME_PLAYER_AGAIN: return current_player elif turn_result == Game.GAME_OVER: return None return None def who_is_winner(self): gems_a = self.board.get_pit(Board.player_a, Board.home_pit) gems_b = self.board.get_pit(Board.player_b, Board.home_pit) if gems_a > gems_b: return Board.player_a elif gems_b > gems_a: return Board.player_b else: return None def trace(self): print "[turn %3d] player: %s => %s" % (self.turn, self.last_turn_player, self.last_turn_status) print self.board
def test_LastGemInHomeRule(self): r = LastGemInHomeRule(Board()) self.assertTrue(r.matches(Board.player_a, PlayerAndPit(Board.player_a, Board.home_pit))) self.assertFalse(r.matches(Board.player_a, PlayerAndPit(Board.player_a, 0))) self.assertFalse(r.matches(Board.player_a, PlayerAndPit(Board.player_b, Board.home_pit)))