コード例 #1
0
 def test_init_1_1(self):
     '''
     Test construction parameter and consistency with properties
     '''
     board = Board(1, 1)
     self.assertEqual(board._cell_free_count, 1)
     self.assertTrue(board.has_free_cell())
     self.assertEqual(board.cell_used_count, 0)
コード例 #2
0
    def test_has_free_cell(self):
        board = Board(3, 3)

        for x in range(3):
            for y in range(3):
                self.assertTrue(board.has_free_cell())
                self.assertTrue(board.add_token(Point(x, y), "X"))

        self.assertFalse(board.has_free_cell())
コード例 #3
0
 def test_equal_array(self):
     import numpy as np
     a = [1, 1, 1]
     b = [1, 1, 1]
     c = [0, 0, 0]
     d = np.full(3, 1)
     self.assertTrue(Board.array_equal(a, b))
     self.assertFalse(Board.array_equal(a, c))
     self.assertTrue(Board.array_equal(a, d))
コード例 #4
0
    def test_x_y_order(self):
        w, h = 5, 3
        board = Board(w, h)
        self.assertTrue(board.add_token(Point(2, 1), 'x'))
        self.assertTrue(board.add_token(Point(4, 0), 'x'))
        self.assertTrue(board.add_token(Point(4, 2), 'o'))
        self.assertTrue(board.add_token(Point(0, 2), 'u'))
#         print(board)
        self.assertEqual(board.column_count, w)
        self.assertEqual(board.row_count, h)
コード例 #5
0
    def test_get_diag_down(self):
        '''
        00|10|20|30|40|
        01|11|21|31|41|
        02|12|22|32|42|
        '''
        import numpy as np
        w, h = 5, 3
        board = Board(w, h)
        for y in range(h):
            for x in range(w):
                board.add_token(Point(x, y), str(x) + str(y))

        line = board.get_diag_down(0, 0)
        self.assertTrue(np.array_equal(line, ['00', '11', '22']))

        line = board.get_diag_down(3, 0)
        self.assertTrue(np.array_equal(line, ['30', '41']))

        line = board.get_diag_down(4, 2)
        self.assertTrue(np.array_equal(line, ['20', '31', '42']))

        line = board.get_diag_down(0, 1)
        self.assertTrue(np.array_equal(line, ['01', '12']))

        line = board.get_diag_down(1, 2)
        self.assertTrue(np.array_equal(line, ['01', '12']))
コード例 #6
0
    def test_anti_diag(self):
        import numpy as np
        w, h = 5, 3
        board = Board(w, h)
        for y in range(h):
            for x in range(w):
                board.add_token(Point(x, y), str(x) + str(y))

        line = np.flipud(board._grid).diagonal(0)
        self.assertTrue(np.array_equal(line, ['02', '11', '20']))

        line = np.flipud(board._grid).diagonal(1)
        self.assertTrue(np.array_equal(line, ['12', '21', '30']))

        line = np.flipud(board._grid).diagonal(-1)
        self.assertTrue(np.array_equal(line, ['01', '10']))
コード例 #7
0
    def test_undo(self):
        board = Board(4, 2)
        token = "X"

        # Add 2 token
        self.assertTrue(board.add_token(Point(0, 0), token))
        self.assertTrue(board.add_token(Point(1, 0), token))
        self.assertEqual(board.cell_used_count, 2)

        # Undo last one
        board.undo(Point(1, 0))
        self.assertEqual(board.cell_used_count, 1)

        # Check value in grid
        self.assertEqual(board.grid[0][0], token)
        self.assertEqual(board.grid[0][1], None)
コード例 #8
0
 def __init__(self, p1=None, p2=None, size=9, line_win_size=5):
     self._board = Board(size, size)
     self._line_win_size = line_win_size
     self._p1 = p1 if not p1 is None else Player("Player 1", Token.A)
     self._p2 = p2 if not p2 is None else Player("Player 2", Token.B)
     assert (not (self._p1.token == self._p2.token))
     self._current_player = self._p1
     self._winner_player = None
     self._is_over = False
     self._history = list()
     self._moves_remaining = set(
         [Point(x, y) for y in range(size) for x in range(size)])
     self._patterns = [
         np.full(self._line_win_size, token)
         for token in [Token.A, Token.B]
     ]
コード例 #9
0
    def test_deepcopy(self):
        w, h = 5, 3
        b = Board(w, h)

        cb = copy.deepcopy(b)

        self.assertFalse(b is cb)
        self.assertFalse(b._grid is cb._grid)
        self.assertFalse(b._moves is cb._moves)
コード例 #10
0
    def test_board_array_equal(self):

        setup = '''
from game_base.board import Board
a = ['x' for _ in range(10)]
b = ['o' for _ in range(10)]
'''
        stmt = '''
Board.array_equal(a,b)
Board.array_equal(a,a)
'''
        print("board:", timeit.timeit(setup=setup, stmt=stmt, number=100000))
コード例 #11
0
    def test_has_winner_diag_down(self):
        board = Board(7, 6)
        token = Token.A

        board.add_token(Point(0, 2), token)
        board.add_token(Point(1, 3), token)
        board.add_token(Point(2, 4), token)
        board.add_token(Point(3, 5), token)

        game = ConnectFour()
        self.assertEqual(game._has_winner_diagonal(board, Point(3, 5)),
                         (True, token))
コード例 #12
0
    def test_get_row(self):
        import numpy as np
        w, h = 5, 3
        board = Board(w, h)
        # len
        self.assertEqual(len(board.get_row(0)), w)

        # Default to None
        a = [None for i in range(w)]
        self.assertTrue(np.array_equal(board.get_row(0), a))

        # Insert
        a[4] = 'x'
        board.add_token(Point(4, 0), 'x')
        self.assertTrue(np.array_equal(board.get_row(0), a))

        # Exception
        board.get_row(0)
        board.get_row(1)
        board.get_row(2)

        with self.assertRaises(IndexError):
            board.get_row(3)
コード例 #13
0
 def test_add_token_on_used_cell(self):
     board = Board(2, 4)
     self.assertTrue(board.add_token(Point(0, 0), "X"))
     self.assertFalse(board.add_token(Point(0, 0), "X"))
コード例 #14
0
    def test_boundaries(self):

        board = Board(3, 3)
        self.assertFalse(board.add_token(Point(-1, 0), "X"))
        self.assertFalse(board.add_token(Point(-2, -3), "X"))
        self.assertFalse(board.add_token(Point(0, -4), "X"))

        with self.assertRaises(IndexError):
            board.add_token(Point(3, 0), "X")

        with self.assertRaises(IndexError):
            board.add_token(Point(3, 5), "X")

        with self.assertRaises(IndexError):
            board.add_token(Point(0, 5), "X")
コード例 #15
0
 def test_cell_used_count(self):
     board = Board(3, 5)
     self.assertEqual(board.cell_used_count, 0)
     self.assertTrue(board.add_token(Point(0, 0), "X"))
     self.assertEqual(board.cell_used_count, 1)
コード例 #16
0
    def test_get_column(self):
        import numpy as np
        w, h = 5, 3
        board = Board(w, h)
        # Len
        self.assertEqual(len(board.get_column(0)), h)

        # Default to None
        a = [None for i in range(h)]
        self.assertTrue(np.array_equal(board.get_column(0), a))

        # Insert
        a[2] = 'x'
        board.add_token(Point(0, 2), 'x')
        self.assertTrue(np.array_equal(board.get_column(0), a))

        # Exception
        board.get_column(0)
        board.get_column(1)
        board.get_column(2)
        board.get_column(3)
        board.get_column(4)

        with self.assertRaises(IndexError):
            board.get_row(5)
コード例 #17
0
    def test_get_diag_up(self):
        '''
        00|10|20|
        01|11|21|
        02|12|22|
        03|13|23|
        04|14|24|

        04|14|24|
        03|13|23|
        02|12|22|
        01|11|21|
        00|10|20|
        '''
        import numpy as np
        w, h = 3, 5
        board = Board(w, h)
        for y in range(h):
            for x in range(w):
                board.add_token(Point(x, y), str(x) + str(y))

        line = board.get_diag_up(0, 4)
        self.assertTrue(np.array_equal(line, ['04', '13', '22']))

        line = board.get_diag_up(0, 3)
        self.assertTrue(np.array_equal(line, ['03', '12', '21']))

        line = board.get_diag_up(0, 2)
        self.assertTrue(np.array_equal(line, ['02', '11', '20']))

        line = board.get_diag_up(0, 1)
        self.assertTrue(np.array_equal(line, ['01', '10']))

        line = board.get_diag_up(1, 4)
        self.assertTrue(np.array_equal(line, ['14', '23']))

        line = board.get_diag_up(2, 4)
        self.assertTrue(np.array_equal(line, ['24']))

        line = board.get_diag_up(1, 1)
        self.assertTrue(np.array_equal(line, ['02', '11', '20']))
コード例 #18
0
    def test_check_line_horizontal(self):

        w, h = 5, 3
        board = Board(w, h)
        token = 'x'

        # Check empty row
        for y in range(h):
            self.assertTrue(board.check_line_horizontal(0, y, [None]))
            self.assertTrue(board.check_line_horizontal(1, y, [None, None]))
            self.assertFalse(board.check_line_horizontal(2, y, [token]))
            self.assertTrue(board.check_line_horizontal(3, y, [None, None]))

        # |-|x|-|x|-|
        self.assertTrue(board.add_token(Point(1, 1), token))
        self.assertTrue(board.add_token(Point(3, 1), token))
        self.assertTrue(board.check_line_horizontal(1, 1, [token]))
        self.assertTrue(board.check_line_horizontal(3, 1, [token]))
        self.assertTrue(board.check_line_horizontal(
            1, 1, [token, None, token]))
        self.assertTrue(board.check_line_horizontal(
            2, 1, [token, None, token]))
        self.assertTrue(board.check_line_horizontal(
            3, 1, [token, None, token]))
        self.assertFalse(board.check_line_horizontal(2, 1, [token, token]))

        # |-|x|x|x|-|
        self.assertTrue(board.add_token(Point(2, 1), token))
        self.assertTrue(board.check_line_horizontal(
            2, 1, [token, token, token]))
        self.assertTrue(board.check_line_horizontal(
            3, 1, [token, token, token]))
        self.assertTrue(board.check_line_horizontal(
            1, 1, [token, token, token]))
コード例 #19
0
class Gomoku():
    def __init__(self, p1=None, p2=None, size=9, line_win_size=5):
        self._board = Board(size, size)
        self._line_win_size = line_win_size
        self._p1 = p1 if not p1 is None else Player("Player 1", Token.A)
        self._p2 = p2 if not p2 is None else Player("Player 2", Token.B)
        assert (not (self._p1.token == self._p2.token))
        self._current_player = self._p1
        self._winner_player = None
        self._is_over = False
        self._history = list()
        self._moves_remaining = set(
            [Point(x, y) for y in range(size) for x in range(size)])
        self._patterns = [
            np.full(self._line_win_size, token)
            for token in [Token.A, Token.B]
        ]

    @property
    def grid(self):
        return self._board.grid

    @property
    def is_over(self):
        return self._is_over

    @property
    def current_player(self):
        return self._current_player

    @property
    def winner(self):
        return self._winner_player

    @property
    def history(self):
        return self._history

    def generate_moves(self):
        '''
        @brief All legal moves minus already played moves'''
        return self._moves_remaining

    def play(self, point):
        if self._is_over:
            self._history.append(None)  # bad move
            return False

        if not self._board.add_token(point, self._current_player.token):
            self._history.append(None)  # bad move
            return False

        self._history.append(point)
        self._moves_remaining.remove(point)
        self._compute_ending()
        self._compute_next_player()

        return True

    def undo(self):
        move = self._history.pop()
        if move:
            self._board.undo(move)
            self._compute_next_player()
            self._moves_remaining.add(move)
        self._winner_player = None
        self._is_over = False

    def _compute_next_player(self):
        if self._current_player == self._p1:
            self._current_player = self._p2
        elif self._current_player == self._p2:
            self._current_player = self._p1
        else:
            assert False

    def _compute_ending(self):
        '''
        Decide if a game is over
        '''
        # First player need 5 turn to win
        if self._board.cell_used_count < (self._line_win_size * 2) - 1:
            return False

        # Horizontal
        has_winner, token = self._has_winner_horizontal(
            self._board, self._board.last_move)

        # Vertical
        if not has_winner:
            has_winner, token = self._has_winner_vertical(
                self._board, self._board.last_move)

        # Diagonal
        if not has_winner:
            has_winner, token = self._has_winner_diagonal(
                self._board, self._board.last_move)

        if has_winner:
            self._winner_player = self._p1 if token == self._p1.token else self._p2

        self._is_over = not self._board.has_free_cell() or has_winner
        return self._is_over

    def _has_winner_horizontal(self, board, move):
        x, y = move.point
        for pattern in self._patterns:
            if board.check_line_horizontal(x, y, pattern):
                return True, pattern[0]

        return False, None

    def _has_winner_vertical(self, board, move):
        x, y = move.point
        for pattern in self._patterns:
            if board.check_line_vertical(x, y, pattern):
                return True, pattern[0]

        return False, None

    def _has_winner_diagonal(self, board, move):
        x, y = move.point
        for pattern in self._patterns:
            if board.check_line_diag_down(x, y, pattern):
                return True, pattern[0]
            elif board.check_line_diag_up(x, y, pattern):
                return True, pattern[0]
        return False, None