def first_move():

    print(
        '|----------------------------------------------------------------------------|'
    )
    print(' TEST OBJECTIVE: choose the optimal first move\n')

    start_time = time()

    shape = (4, 5)
    game = DynamicGame(grid_shape=shape)

    print('\n', game)
    solver = Solver(game.gameState)
    game.step(solver.get_action())

    end_time = time()

    assert (game.gameState.board[17] == 1)

    print('\n TEST SUCCESSFUL:', solver.nodes_explored, 'nodes explored in ',
          round(end_time - start_time, 2), 'seconds.')
    print(
        '|----------------------------------------------------------------------------|'
    )
예제 #2
0
    def __init__(self, shape=(4, 5), human_first=True):

        # Game environment
        self.shape = shape
        self.env = DynamicGame(grid_shape=shape)

        self.WINDOW_DIMS = (shape[1] * self.CELL_SIZE,
                            shape[0] * self.CELL_SIZE)
        self.main_window = pg.display.set_mode(self.WINDOW_DIMS, 0, 32)
        self.main_window.fill((255, 255, 255))

        self.render(self.main_window)
        pg.display.update()

        while 1:

            # Check if AI plays first
            if not human_first:
                self.update_AI()
                # Check for draw
                if self.env.gameState.isEndGame:
                    break

            # Ask user for valid command
            event = self.choose_move()

            # User wishes to quit
            if event.type == pg.QUIT:
                pg.quit()
                sys.exit()

            # User selects a valid command
            elif event.type == pg.MOUSEBUTTONDOWN:
                try_again = self.update_player(event)
                while try_again:
                    event = self.choose_move()
                    try_again = self.update_player(event)

            if self.env.gameState.isEndGame:
                break

            # Check if AI plays second
            if human_first:
                self.update_AI()

            # Check for draw
            if self.env.gameState.isEndGame:
                break
def positive_alignments(shape=(6, 7)):

    print(
        '|----------------------------------------------------------------------------|'
    )
    print(' TEST OBJECTIVE: test all possible alignments in grid of', shape,
          'shape')

    # Start with an empty board and node
    game = DynamicGame(shape)
    solver = Solver(game.gameState)
    node = solver.root_node

    # Binary values leading to the victory of the first player or second
    winners = []

    index = np.flip(np.arange(0,
                              node.WIDTH * (node.HEIGHT + 1),
                              dtype=np.int64).reshape(
                                  (node.WIDTH, (node.HEIGHT + 1))),
                    axis=1).transpose()

    # Vertical alignments are possible
    if shape[0] >= 4:
        for col in range(node.WIDTH):
            for row in range(1, node.HEIGHT - 2):
                winners.append(
                    sum(map(lambda x: 2**x, index[row:row + 4, col])))

    # Horizontal alignments are possible
    if shape[1] >= 4:
        for row in range(node.HEIGHT):
            for col in range(node.WIDTH - 3):
                winners.append(
                    sum(map(lambda x: 2**x, index[row, col:col + 4])))

    # Diagonal alignments are possible
    if shape[0] >= 4 and shape[1] >= 4:

        for col in range(node.WIDTH - 3):
            for row in range(1, node.HEIGHT - 2):
                indexes = []
                for c in range(4):
                    indexes.append(index[row + c, col + c])
                winners.append(sum(map(lambda x: 2**x, indexes)))

        for col in range(node.WIDTH - 1, 2, -1):
            for row in range(node.HEIGHT - 3, 0, -1):
                indexes = []
                for c in range(4):
                    indexes.append(index[row + c, col - c])
                winners.append(sum(map(lambda x: 2**x, indexes)))

    for winner in winners:
        assert (node.alignment(winner))

    print('\n TEST SUCCESSFUL')
    print(
        '|----------------------------------------------------------------------------|'
    )
def counter_double_menace():

    print(
        '|----------------------------------------------------------------------------|'
    )
    print(' TEST OBJECTIVE: counter the double menace\n')

    start_time = time()

    shape = (4, 5)
    sequence = [18, 13, 17]

    game = DynamicGame(grid_shape=shape)

    for action in sequence:
        game.step(action)

    print('Initial state: \n', game)

    solver = Solver(game.gameState)
    game.step(solver.get_action())
    print('\n', game)

    end_time = time()

    assert (game.gameState.board[16] == -1)

    print('\n TEST SUCCESSFUL:', solver.nodes_explored, 'nodes explored in ',
          round(end_time - start_time, 2), 'seconds.')
    print(
        '|----------------------------------------------------------------------------|'
    )
def double_menace():

    print(
        '|----------------------------------------------------------------------------|'
    )
    print(' TEST OBJECTIVE: complete the double menace\n')

    start_time = time()

    shape = (4, 5)
    sequence = [18, 13, 17, 12]

    game = DynamicGame(grid_shape=shape)

    for action in sequence:
        game.step(action)

    print('Initial state: \n', game)

    total_nodes = 0

    for x in range(3):
        solver = Solver(game.gameState)
        game.step(solver.get_action())
        total_nodes += solver.nodes_explored
        print('\n', game)

    end_time = time()

    assert (game.gameState.board[15] == 1 and game.gameState.board[16] == 1
            or game.gameState.board[16] == 1 and game.gameState.board[19] == 1)

    print('\n TEST SUCCESSFUL:', total_nodes, ' nodes explored in ',
          round(end_time - start_time, 2), 'seconds.')
    print(
        '|----------------------------------------------------------------------------|'
    )
예제 #6
0
class LocalPlay:

    CELL_SIZE = 100

    def __init__(self, shape=(4, 5), human_first=True):

        # Game environment
        self.shape = shape
        self.env = DynamicGame(grid_shape=shape)

        self.WINDOW_DIMS = (shape[1] * self.CELL_SIZE,
                            shape[0] * self.CELL_SIZE)
        self.main_window = pg.display.set_mode(self.WINDOW_DIMS, 0, 32)
        self.main_window.fill((255, 255, 255))

        self.render(self.main_window)
        pg.display.update()

        while 1:

            # Check if AI plays first
            if not human_first:
                self.update_AI()
                # Check for draw
                if self.env.gameState.isEndGame:
                    break

            # Ask user for valid command
            event = self.choose_move()

            # User wishes to quit
            if event.type == pg.QUIT:
                pg.quit()
                sys.exit()

            # User selects a valid command
            elif event.type == pg.MOUSEBUTTONDOWN:
                try_again = self.update_player(event)
                while try_again:
                    event = self.choose_move()
                    try_again = self.update_player(event)

            if self.env.gameState.isEndGame:
                break

            # Check if AI plays second
            if human_first:
                self.update_AI()

            # Check for draw
            if self.env.gameState.isEndGame:
                break

    @staticmethod
    def choose_move():
        while True:
            event = pg.event.wait()
            if event.type == pg.QUIT:
                pg.quit()
                sys.exit()
            elif event.type == pg.MOUSEBUTTONDOWN:
                return event

    def render(self, main_window):

        for x in range(self.shape[1]):
            for y in range(self.shape[0]):
                pg.draw.rect(main_window, (255, 255, 255),
                             (x * self.CELL_SIZE, y * self.CELL_SIZE,
                              self.CELL_SIZE, self.CELL_SIZE))

        for x in range(self.shape[1]):
            pg.draw.line(main_window, (0, 0, 0), (x * self.CELL_SIZE, 0),
                         (x * self.CELL_SIZE, self.shape[0] * self.CELL_SIZE))
            pg.draw.line(main_window, (0, 0, 0), (0, x * self.CELL_SIZE),
                         (self.shape[1] * self.CELL_SIZE, x * self.CELL_SIZE))

        matrix = self.env.gameState.board.reshape(self.shape)

        for x in range(self.shape[1]):
            for y in range(self.shape[0]):
                if matrix[y, x] == 1:
                    pg.draw.circle(main_window, (255, 0, 0),
                                   (int((x + 0.5) * self.CELL_SIZE),
                                    int((y + 0.5) * self.CELL_SIZE)),
                                   self.CELL_SIZE // 2, 0)
                elif matrix[y, x] == -1:
                    pg.draw.circle(main_window, (0, 255, 0),
                                   (int((x + 0.5) * self.CELL_SIZE),
                                    int((y + 0.5) * self.CELL_SIZE)),
                                   self.CELL_SIZE // 2, 0)

    def update_player(self, event):
        x = event.pos[0] // self.CELL_SIZE
        y = event.pos[1] // self.CELL_SIZE
        action = y * self.shape[1] + x

        try_again = True
        if action in self.env.gameState.allowedActions:
            next_state, _, _, _ = self.env.step(action)
            try_again = False

        self.render(self.main_window)
        pg.display.update()

        return try_again

    def update_AI(self):
        solver = Solver(self.env.gameState)
        action = solver.get_action()
        self.env.step(action)

        self.render(self.main_window)
        pg.display.update()
def fill_position_mask(shape=(6, 7)):

    print(
        '|----------------------------------------------------------------------------|'
    )
    print(' TEST OBJECTIVE: test binary representation of grid of', shape,
          'shape')

    # Start with an empty board and node
    game = DynamicGame(grid_shape=shape)
    solver = Solver(game.gameState)
    node = solver.root_node

    # Node should be empty
    assert (node.position == 0 and node.mask == 0)

    # Every column should be playable
    for col in range(node.WIDTH):
        assert (node.can_play(col))

    # Move sequence (row, col)
    move_order_h = []
    move_order_v = []

    # Fill the board left to right, bottom to top
    for row in range(node.HEIGHT):
        for col in range(node.WIDTH):
            move_order_h.append((row, col))

    # Fill the board bottom to top, lef to right
    for col in range(node.WIDTH):
        for row in range(node.HEIGHT):
            move_order_v.append((row, col))

    for i in range(0, 2):

        solver = Solver(game.gameState)
        node = solver.root_node
        played_cells = []

        if i == 0:
            moves = move_order_h
        else:
            moves = move_order_v

        for row, col in moves:

            # Current player plays a move
            played_cells.append(col * (node.HEIGHT + 1) + row)
            node.play(col)

            # Compute what should be position of the current player
            expected_position = 0
            for idx, cell in enumerate(played_cells):

                # It is the starting players turn
                if node.total_moves % 2 == 0:
                    if idx % 2 == 0:
                        expected_position += 2**cell

                # It is the second players turn
                else:
                    if idx % 2 == 1:
                        expected_position += 2**cell

            # The value of the position is the sum of 2**cell for all cell played by the current player.
            assert (node.position == expected_position)

            # The value of the mask is the sum of 2**cell for all cell played.
            assert (node.mask == sum(map(lambda x: 2**x, played_cells)))

        # Node should be full at this point and have no legal moves left
        for col in range(node.WIDTH):
            assert (not node.can_play(col))

    print('\n TEST SUCCESSFUL')
    print(
        '|----------------------------------------------------------------------------|'
    )