Exemplo n.º 1
0
def two_player():
    # Initialize game
    cf = ConnectFour()
    prev_x = -2
    prev_y = -2
    firstClick = False
    while True:
        # Draw the board
        screen.fill(WHITE)
        draw_board(cf)
        highlight_piece(prev_x, prev_y)

        # quit events
        events = pygame.event.get()
        checkForQuit(events)

        if cf.winner == 0:
            draw_text(names[cf.whos_turn] + "'s turn",
                      (25, SCREEN_HEIGHT - 50), BRIGHTBLUE)
            # Get and draw the column the mouse is hovering
            (x, y) = pygame.mouse.get_pos()
            h_move = hovered_move(x)
            # Draw available moves
            moves = cf.board.available_moves()
            color = pieces[cf.whos_turn]
            draw_possible(moves, h_move, color)
            # If player is hovering a valid move check for click
            if moves[h_move] > 0:
                pygame.event.get()
                (m1, m2, m3) = pygame.mouse.get_pressed()
                if m1 and firstClick:
                    firstClick = False
                    # Makes the move
                    prev_y, prev_x = cf.make_move(h_move)
                if not m1:
                    firstClick = True
        # When someone has won the game
        else:
            pygame.draw.rect(screen, pieces[cf.winner],
                             [0, 0, SCREEN_WIDTH, vOffset])
            draw_text(names[cf.winner] + " Wins the game press r to reset",
                      (25, 25), BRIGHTBLUE)
        # Check for reset key being pressed
        for event in events:
            if event.type == pygame.KEYUP and event.key == pygame.K_r:
                cf.reset()
                return

        pygame.display.flip()
Exemplo n.º 2
0
    def __init__(self, **kwargs):
        super(MyBox, self).__init__(**kwargs)
        self.c4 = ConnectFour()

        self.block_touch = False

        # Bind touch on grid
        grid = self.ids['grid']
        grid.bind(on_touch_down=self.on_grid_touch)
        grid.bind(size=self.refresh)

        # Adapt size of the grid, so that the aspect ratio of the image is kept
        self.ids['grid_container'].bind(size=self.resize_grid)

        Clock.schedule_once(lambda dt: self.open_popup(), 0)
Exemplo n.º 3
0
async def connectfour(context, name):
    if "ConnectFour" in gamebot.games:
        await context.send(
            ':warning: A Connect Four game is already in progress')
        return

    opponent = None
    for member in context.message.channel.members:
        if member.name.startswith(name):
            opponent = member
            break
    if opponent is None:
        await context.send(':warning: No users matched name "' + name + '"')
        return

    await context.send('Starting a Connect Four game against ' +
                       opponent.mention)
    gamebot.games['ConnectFour'] = ConnectFour(
        gamebot, [context.message.author, opponent])
    await gamebot.games['ConnectFour'].start(context.message.channel)
Exemplo n.º 4
0
def one_player(player, bot, algorithm):
    cf = ConnectFour()
    prev_x = -2
    prev_y = -2
    firstClick = False
    firstRun = True
    decision = []
    if algorithm == "MCTS":
        agent = MCTS_Agent(400, bot)
    else:
        agent = Min_Max_Agent(5, bot)
    while True:
        # Draw the board, and get events
        screen.fill(WHITE)
        draw_board(cf)
        highlight_piece(prev_x, prev_y)
        events = pygame.event.get()
        checkForQuit(events)

        if cf.winner == 0:
            draw_text(names[cf.whos_turn] + "'s turn",
                      (25, SCREEN_HEIGHT - 50), BRIGHTBLUE)

            # Players turn
            if cf.whos_turn == player:
                # Determine which column the mouse is hovering over
                (x, y) = pygame.mouse.get_pos()
                h_move = hovered_move(x)
                # Draw available moves
                moves = cf.board.available_moves()
                color = pieces[cf.whos_turn]
                draw_possible(moves, h_move, color)
                # Check for mouse click, if player is hovering a valid move
                if moves[h_move] > 0:
                    (m1, m2, m3) = pygame.mouse.get_pressed()
                    if m1 and firstClick:
                        firstClick = False
                        prev_y, prev_x = cf.make_move(h_move)
                    if not m1:
                        firstClick = True
            else:
                # Begins the thread if not already
                if firstRun:
                    agentThread = threading.Thread(target=agentDecide,
                                                   args=(agent, cf, decision))
                    agentThread.start()
                    firstRun = False
                # Waiting for thread to finish
                elif decision != []:
                    prev_y, prev_x = cf.make_move(decision[0])
                    decision = []
                    firstRun = True
                # Plays the thinking animation
                else:
                    draw_thinking()
        # When someone has won the game
        else:
            pygame.draw.rect(screen, pieces[cf.winner],
                             [0, 0, SCREEN_WIDTH, vOffset])
            draw_text(names[cf.winner] + " Wins the game press r to reset",
                      (25, 25), BRIGHTBLUE)
        # Check for reset key being pressed
        for event in events:
            if event.type == pygame.KEYUP and event.key == pygame.K_r:
                cf.reset()
                return

        pygame.display.flip()
Exemplo n.º 5
0
def playGames(red, blue, games=1000):
    return numpy.array([ConnectFour(red, blue).play() for _ in range(games)])
Exemplo n.º 6
0
class MyBox(BoxLayout):
    def __init__(self, **kwargs):
        super(MyBox, self).__init__(**kwargs)
        self.c4 = ConnectFour()

        self.block_touch = False

        # Bind touch on grid
        grid = self.ids['grid']
        grid.bind(on_touch_down=self.on_grid_touch)
        grid.bind(size=self.refresh)

        # Adapt size of the grid, so that the aspect ratio of the image is kept
        self.ids['grid_container'].bind(size=self.resize_grid)

        Clock.schedule_once(lambda dt: self.open_popup(), 0)

    def resize_grid(self, grid_container, *args):
        # Adapt size of the grid, so that the aspect ratio of the image is kept
        container_size_x, container_size_y = self.ids['grid_container'].size
        container_ratio = container_size_x / container_size_y
        grid = self.ids['grid']
        if container_ratio > IMAGE_RATIO:
            # container is larger than the image
            grid.size_hint_x = IMAGE_RATIO / container_ratio
            grid.size_hint_y = 1
        else:
            grid.size_hint_x = 1
            grid.size_hint_y = container_ratio / IMAGE_RATIO

    def on_grid_touch(self, grid, touch):
        '''
        Deal with touch on grid.
        '''

        if grid.collide_point(*touch.pos) and not self.block_touch:
            # Click in the paint widget

            # Block touch (until computer finished playing next move)
            self.block_touch = True
            # Find corresponding column
            NCOL = 7
            col = int((touch.x - grid.pos[0]) / grid.size[0] * NCOL)

            c4 = self.c4
            message = self.ids['message']

            # It's the player turn to play and a coin can be added in the selected column
            if c4.get_state() == 0 and c4.add_coin(col):
                # Animation to make the coin fall
                anim, e = grid.fall_anim(*c4.last_pos, 3 - c4.player)

                self.check_game_end()

                if c4.get_state() == 0:
                    # Computer plays
                    message.text = "Computer computing next move..."
                    # Without the inner schedule_once, the animation is blocked
                    # before completion
                    anim.bind(on_complete=lambda x, y: Clock.schedule_once(
                        lambda dt: self.computer_plays(), 0))

                anim.start(e)
                return True

            self.block_touch = False

    def unblock_touch(self):
        self.block_touch = False

    def check_game_end(self):
        """
        Check if game is finished. If finished, update label accordingly.
        """
        # Check if game is finished
        state = self.c4.get_state()
        if state != 0:
            if state > 0:
                if self.computer_first:
                    state = 3 - state
                if state == 1:
                    winner = 'player'
                else:
                    winner = 'computer'
            else:
                winner = 'equality'

            self.open_end_popup(winner)

    def computer_plays(self):
        """
        Compute next move for computer. Update canvas and label accordingly.
        """
        c4 = self.c4
        message = self.ids['message']
        col = c4.get_next_col()
        c4.add_coin(col)

        # Coin fall animation
        anim, e = self.ids['grid'].fall_anim(*c4.last_pos, 3 - c4.player)
        # unblock touch once animation is finished
        anim.bind(on_complete=lambda x, y: Clock.schedule_once(
            lambda dt: self.unblock_touch(), 0))
        anim.start(e)

        message.text = "Computer played in column {}".format(col)
        self.check_game_end()

    def refresh(self, *args):
        """
        Draw current state of grid on canvas
        """
        grid_canvas = self.ids['grid']
        grid_canvas.clear_canvas()
        grid_canvas.draw_tab(tab=self.c4.grid)

    def start_game(self, level, computer_first):

        print(f'Starting a new game, computer first: {computer_first}')

        self.ids['message'].text = ''
        self.c4.clear()
        self.c4.update_level(level)
        self.computer_first = computer_first
        self.refresh()

        if self.computer_first:
            # computer plays first
            Clock.schedule_once(lambda dt: self.computer_plays(), 0)
        else:
            # Unblock touch on grid so that player can play
            self.unblock_touch()

    def clear(self):
        """
        Remove coins, message from main window.
        """
        self.ids['message'].text = ''
        self.c4.clear()
        self.refresh()

    def open_popup(self, *args):
        """
        Opens a popup to choose next game settings
        """
        # Clear grid and message
        self.clear()

        levels = [k for k, v in self.c4.LEVELS]
        current_level = self.c4.level_name
        self.popup = MyPopup(levels, current_level)
        self.popup.open()

    def open_end_popup(self, winner):
        popup = EndPopup(winner)
        popup.open()
Exemplo n.º 7
0
import random

from connectfour import ConnectFour

game = ConnectFour()


def random_heuristic(state=None):
    return random.randint(-100, 100)


def memoize(heuristic):
    memory = {}

    def helper(state):
        if str(state.board) not in memory:
            memory[str(state.board)] = heuristic(state)
        return memory[str(state.board)]

    return helper


@memoize
def best_move_heuristic(state=None):
    result = 0

    if state.utility == 1:
        return state.utility * 10000000
    if state.utility == -1:
        return state.utility * 5000000
 def setUp(self):
     self.c4 = ConnectFour()
class TestConnectFour(unittest.TestCase):
    def setUp(self):
        self.c4 = ConnectFour()

    def test_add_coin(self):
        # change of player
        previous_player = self.c4.player
        self.c4.add_coin(2)
        self.assertNotEqual(previous_player, self.c4.player,
                            'add_coin should change self.player')

        # We can exactly add NROW coins in a given column
        for i in range(NROW):
            self.assertTrue(self.c4.add_coin(3))
        self.assertFalse(self.c4.add_coin(3),
                         'We cannot add more than NROW coins in a given col')

        # Checking grid modifications
        self.c4.clear()
        player1 = self.c4.player
        for i in range(NROW):
            self.c4.add_coin(4)
        self.assertEqual(self.c4.grid[0, 4], player1)
        self.assertEqual(self.c4.grid[2, 4], player1)
        self.assertEqual(self.c4.grid[1, 4], 3 - player1)

    def test_get_state(self):
        # No one has won
        for i in range(NROW):
            self.c4.add_coin(3)
        self.assertEqual(self.c4.get_state(), 0, 'No one has won')

        # A player has won
        self.c4.clear()
        self.c4.grid[0:4, 1] = 1
        self.assertEqual(self.c4.get_state(), 1, 'player 1 has won')

        self.c4.clear()
        self.c4.grid[0, 1:5] = 2
        self.assertEqual(self.c4.get_state(), 2, 'player 2 has won')

        self.c4.clear()
        for i in range(4):
            self.c4.grid[i + 1, i] = 1
        self.assertEqual(self.c4.get_state(), 1, 'player 1 has won')

        self.c4.clear()
        for i in range(4):
            self.c4.grid[i + 1, i] = 1
        self.assertEqual(self.c4.get_state(), 1, 'player 1 has won')

        self.c4.clear()
        for i in range(4):
            self.c4.grid[4 - i, i] = 1
        self.assertEqual(self.c4.get_state(), 1, 'player 1 has won')
Exemplo n.º 10
0
    parser.add_argument('--games', type = int, default = 1000, help = 'Cantidad de juegos.')
    parser.add_argument('--players', type = str, nargs = 2, choices = players.keys(), default = ['qlearn', 'random'], help = 'Tipo de los jugadores.')
    args = parser.parse_args()

    args.player_types = [players[x] for x in args.players]
    return args

if __name__ == '__main__':
    args = parse_args()

    # Jugar entre un jugador que hace Q learning, y uno que juega al azar.
    a = args.player_types[0](ConnectFour.moves)
    b = args.player_types[1](ConnectFour.moves)

    # Acumular quien gana cada juego.
    c = Counter()
    game = ConnectFour(a, b)
    for num in range(args.games):
        if num & (num - 1) == 0:
            print('Juego #{}'.format(num))

        winner = game.play()
        c.update([winner.name])

        # Si este es el unico juego, imprimir el resultado.
        if args.games == 1:
            print(game.board.pretty_print())

    print(c)
    print('Red win ratio: {}'.format(c['red'] / args.games))