Example #1
0
 def _setup(self):
     self.board = Board(dimension=self.board_dimension)
Example #2
0
class BaseGame(object):
    def __init__(self, board_dimension=BOARD_DIMENSION):
        self.board_dimension = board_dimension

        if not (MIN_BOARD_DIMENSION <= self.board_dimension <= MAX_BOARD_DIMENSION):
            raise ValueError('Board dimension must be from %s to %s.' % (MIN_BOARD_DIMENSION, MAX_BOARD_DIMENSION))

        self.turn_color = Color.black
        self.board = None
        self.past_boards = []
        self.board_states = set()
        self.last_player_passed = False

        self.invalid_moves = set()
        self.current_move = None

    def play(self):
        self._setup()
        self._run()
        self._end()

    def _setup(self):
        self.board = Board(dimension=self.board_dimension)

    def _run(self):
        try:
            while True:
                self._do_turn()
        except GameOver:
            pass

    def _end(self):
        territory_counts = self.board.calculate_territories()

        print('\n'.join([
            '',
            'The game has ended:',
            '',
            str(self.board),
            '',
            'Black territory: %s' % territory_counts[Color.black],
            'White territory: %s' % territory_counts[Color.white],
        ]))

        win_margin = abs(territory_counts[Color.black] - territory_counts[Color.white])
        if win_margin:
            winner_color = sorted(territory_counts.items(), key=itemgetter(1), reverse=True)[0][0]
            print('\n'.join([
                '',
                '%s wins by %s points!' % (winner_color.name.title(), win_margin),
                '',
            ]))
        else:
            print('\n'.join([
                '',
                'Black and White draw!',
                '',
            ]))

    def _do_turn(self):
        self._setup_turn()
        self._place_stone()
        self._remove_opponent_captured_stones()
        self._remove_player_captured_stones()

        try:
            self._complete_turn()
        except SuperKo:
            self.invalid_moves.add(self.current_move)
        else:
            self.invalid_moves = set()

        self.current_move = None

    def _setup_turn(self):
        self.past_boards.append(self.board.clone())

    def _place_stone(self):
        try:
            self.current_move = ComputerPlayer(self.turn_color, self.board, tuple(self.invalid_moves)).play()
        except PassTurn:
            if self.last_player_passed:
                raise GameOver()
            else:
                self.last_player_passed = True

    def _remove_opponent_captured_stones(self):
        self.board.remove_captured_stones(color=self._get_opponent_color())

    def _remove_player_captured_stones(self):
        self.board.remove_captured_stones(color=self.turn_color)

    def _complete_turn(self):
        new_board_state = self.board.get_state()
        if new_board_state in self.board_states:
            self.board = self.past_boards.pop(-1)
            raise SuperKo()
        else:
            self.board_states.add(new_board_state)
            self.turn_color = self._get_opponent_color()

    def _get_opponent_color(self):
        return Color.black if self.turn_color == Color.white else Color.white