Beispiel #1
0
 def __init__(self, ptype, mm):
     self.ptype = ptype
     if ptype > 0:
         print("create player minimax/alphabeta")
         self.tree = GameTree(mm)
     else:
         print("create player human")
Beispiel #2
0
def run_ai_mode():
    """ Run Connect 3 against AI on a 3x3 board """
    player = player_piece()

    rows = 3
    cols = 3

    game = Connect3Board(rows, cols)
    print(game)

    game_tree = GameTree(game)
    position = game_tree.get_root_position()

    while game.get_winner() is None:
        if game.get_whose_turn() == player:
            move = get_int(
                "Your turn. Choose column (0 to {}): ".format(cols - 1), 0,
                cols - 1)

            if game.can_add_token_to_column(move) is True:
                game.add_token(move)
                position = position.get_child(move)
                print(game)
            else:
                print("ERROR: Invalid move, please try again")
        else:
            children_scores = position.get_children_scores()
            child_index = None
            max_score = -2
            min_score = 2

            for i, child in enumerate(children_scores):
                if game.get_whose_turn() == game.TOKENS[0]:
                    if child is not None and child > max_score:
                        max_score = child
                        child_index = i
                else:
                    if child is not None and child < min_score:
                        min_score = child
                        child_index = i

            game.add_token(child_index)
            position = position.get_child(child_index)

            print("AI's turn")
            print(game)

    if game.get_winner() == Connect3Board.DRAW:
        print("This game has ended in a draw!")
    else:
        print("Player {} wins!".format(game.get_winner()))
Beispiel #3
0
class Player:

    nextmove = None
    gametree = None

    ptype = 0

    tree = None

    game = None

    i = 0

    def __init__(self, ptype, mm):
        self.ptype = ptype
        if ptype > 0:
            print("create player minimax/alphabeta")
            self.tree = GameTree(mm)
        else:
            print("create player human")

    def setGame(self, game):
        self.game = game
        if self.ptype > 0:
            self.tree.createTree(game)

    @threaded
    def nextMove(self):
        print("calc next move")
        realmove = -1
        count = 0
        while realmove == -1 and count < self.game.fields:
            if 0 > self.i:
                print("to small move number")
                self.i = 0
            elif self.i >= (self.game.allfields / 2) - 1:
                print("to big move number")
                self.i = 0
            else:
                count += 1
                if self.game.allbeans[self.i] > 0:
                    realmove = self.i
                    print("found move: " + str(realmove))
                else:
                    print("no beans next")
                    self.i += 1
                    count += 1
        time.sleep(5)
        self.game.do_move(self, realmove)
def main(m, n, k, depth_lim):
    game = MNKgame(m=m, n=n, k=k)
    gametree = GameTree(game)
    minimax_algorithm = Minimax_algorithm(game, gametree,
                                          depth_lim=depth_lim)
    me = Player(game, gametree, 1)
    enemy = Enemy(game, -1, policy=minimax_algorithm)
    turn = 0
    is_player_first = True
    while turn < game.n * game.m:
        if is_player_first:
            me.play()
            if game.winner != 0:
                break
            enemy.play()
        else:
            enemy.play()
            if game.winner != 0:
                break
            me.play()
        if game.winner != 0:
            break
        turn += 2
    if game.winner == 0:
        print("DRAW GAME")
Beispiel #5
0
def test_minmax_algorithm_play_optimal_game():
    field = [[1, -1, 0],
             [0, 1, 0],
             [0, -1, 0]]
    game = MNKgame(field=np.array(field))
    gametree = GameTree(game)
    minimax_algo = Minimax_algorithm(game, gametree)
    enemy = Enemy(game, -1, policy=minimax_algo)
    enemy2 = Enemy(game, 1, policy=minimax_algo)
    enemy.play()
    field_out = [[1, -1, 0],
                 [0, 1, 0],
                 [0, -1, -1]]
    assert np.array_equal(game.field, field_out)
    enemy2.play()
    field_out = [[1, -1, 0],
                 [0, 1, 0],
                 [1, -1, -1]]
    assert np.array_equal(game.field, field_out)
    enemy.play()
    field_out = [[1, -1, -1],
                 [0, 1, 0],
                 [1, -1, -1]]
    assert np.array_equal(game.field, field_out)
    enemy2.play()
    field_out = [[1, -1, -1],
                 [1, 1, 0],
                 [1, -1, -1]]
    assert np.array_equal(game.field, field_out)
Beispiel #6
0
def run_ai_mode():
    board = Connect3Board(3, 3)
    player_token = select_player_token()
    game_tree = GameTree(board)
    print(game_tree.count)
    position_tree = game_tree.get_root_position()

    while board.get_winner() == None:
        if board.get_whose_turn() == player_token:
            print(board)
            column_choice = get_int(
                "Player {}'s turn. Choose column ({} to {}):".format(
                    board.get_whose_turn(), 0,
                    board.get_columns() - 1))
            if board.can_add_token_to_column(column_choice):
                board.add_token(column_choice)
                # find the children from the tree based on the users selection
                position_tree = position_tree.get_child(column_choice)
            else:
                print("You cannot add a token at column {}".format(
                    column_choice))
        else:
            print("AI's turn")
            child_scores = position_tree.get_children_scores()

            # select the best child score from the children
            best_child = 0
            for index, score in enumerate(child_scores):
                # pick the score based on player selecting O token
                if score is not None and player_token != GameTree.MIN_PLAYER and score < GameTree.MAX_WIN_SCORE:
                    best_child = index

                    # pick the best score based on player selecting # token
                elif score is not None and player_token != GameTree.MAX_PLAYER and score > GameTree.MIN_WIN_SCORE:
                    best_child = index

            board.add_token(best_child)
            # navigate to the next child in the tree
            position_tree = position_tree.get_child(best_child)

    print(board)
    # Display the winner if its not a draw
    if board.get_winner() != board.DRAW:
        print("Player {} wins!".format(board.get_winner()))
    else:
        print(board.get_winner())
Beispiel #7
0
def test_enemy_cannot_place():
    field = [[-1, 1, -1],
             [1, -1, 1],
             [-1, 1, -1]]
    game = MNKgame(field=np.array(field))
    gametree = GameTree(game)
    minimax_algo = Minimax_algorithm(game, gametree)
    enemy = Enemy(game, -1, policy=minimax_algo)
    enemy.play()
Beispiel #8
0
def test_game_will_finish():
    field = [[1, -1, -1],
             [1, 1, 0],
             [-1, -1, 0]]
    game = MNKgame(field=np.array(field))
    gametree = GameTree(game)
    minimax_algo = Minimax_algorithm(game, gametree)
    enemy = Enemy(game, -1, policy=minimax_algo)
    enemy.play()
    assert game.winner == -1
Beispiel #9
0
def main():
    test = Connect3Board(3, 3)
    Tree = GameTree(test)
    print('Welcome to Connect 3 by Kevin Richards')
    mode = get_mode()
    while mode != 'Q':
        if mode == 'A':
            run_two_player_mode()
        elif mode == 'B':
            run_ai_mode(Tree)
        mode = get_mode()
Beispiel #10
0
def test_player_place_piece(mocker):
    field = [[0, 0, 0],
             [0, 0, 0],
             [0, 0, 0]]
    game = MNKgame(field=np.array(field))
    gametree = GameTree(game)
    player = Player(game, gametree, 1)
    mocker.patch("player.Player.receive_input", return_value=(0, 0))
    player.play()
    field_out = [[1, 0, 0],
                 [0, 0, 0],
                 [0, 0, 0]]
    assert np.array_equal(game.field, field_out)
Beispiel #11
0
def test_minmax_algorithm_chose_win():
    field = [[1, -1, -1],
             [1, 1, 0],
             [-1, -1, 0]]
    game = MNKgame(field=np.array(field))
    gametree = GameTree(game)
    minimax_algo = Minimax_algorithm(game, gametree)
    enemy = Enemy(game, -1, policy=minimax_algo)
    enemy.play()
    print(game.field)
    field_out = [[1, -1, -1],
                 [1, 1, 0],
                 [-1, -1, -1]]
    assert np.array_equal(game.field, field_out)
Beispiel #12
0
    def run_acquire_game(self, number_of_turns):
        """
        Arguments:
            number_of_turns - the list of turns for the game to play through

        Returns:
            a generator which lists all the turns in a game and the GameOverReason
            ex: [start_state, state_2 ... state_n-1, state_n, ALLSAFE]
        """
        gs = GameState(self._get_player_names(), handout=choice)
        gt = GameTree(gs)

        #send all initial player name/tile data to all players
        map(lambda (_, player): player.setup(deepcopy(gs)), self.players)

        yield gt.game_state

        turns_played = 0
        while turns_played < number_of_turns:
            # grab the current Player from the list of Players
            name, current_player = self.players[0]

            # is the game over? ie, can we play any tiles?
            if self.is_game_over(gt.game_state, True):
                self.send_scores(gt.game_state)
                yield self.is_game_over(gt.game_state, True)
                return

            sell_back = {}
            keeps_cheaters = []
            merger_happened = Box(False)
            current_player_cheated = Box(False)
            merger_placement = Box((None, None))
            def merger_function(tile, hotel):
                """
                Function handed to players to inform the administrator of a merge.

                Arguments:
                    tile, hotel - tile and acquiring hotel
                        Contract: Placing these results in a legal merge on the current game state.
                                  tile is owned by the current player
                Returns:
                    state, [GameStatePlayer] -
                        The GameState where other players have sold the stocks they intend to sell
                        and a list of players
                """
                state = deepcopy(gt.game_state)
                if merger_happened.get(): # this function has already been called
                    current_player_cheated.set(True)
                    return state, {} # kick!
                elif not state.board.valid_merge_placement(tile, hotel) or sell_back:
                    current_player_cheated.set(True)
                    return state, {} # kick!
                else:
                    merger_happened.set(True)
                    merger_placement.set((tile, hotel))

                acquirees = state.board.acquirees(tile, hotel)

                players_with_keeps = {}
                for _, p in self.players:
                    try:
                        players_with_keeps[p] = p.keep(deepcopy(state), acquirees)
                    except Exception as e:
                        keeps_cheaters.append(p)

                # Deal with cheaters (the jerks) # => local functions
                keeps_cheaters.extend([p for p, ks in players_with_keeps.items() if len(ks) != len(acquirees)])
                [remove_from_state(state, p) for p in keeps_cheaters]
                players_with_keeps = [(p, ks) for p, k in players_with_keeps.items() if p not in keeps_cheaters]

                # Function which given [True, False True] if acquirees are [C,A,T], returns [A]
                keeps_to_acquirees = lambda keeps: [h for h, k in zip(acquirees, keeps) if not k]

                # saves player keep data for the administrator
                for player, keeps in players_with_keeps:
                    sell_back[player.id] = keeps_to_acquirees(keeps)

                if current_player in keeps_cheaters:
                    current_player_cheated.set(True)
                    return state, {} # KICK!

                state.place_a_tile(tile, hotel)
                map(lambda p: state.sellback(p, sell_back[p], gt.game_state), sell_back.keys())

                return state, [state.player_with_name(p.id) for p, k in players_with_keeps if any(k)]

            try:
                tile, maybeHotel, shares = current_player.take_turn(deepcopy(gt.game_state), merger_function)
            except Exception as e:
                current_player_cheated = True

            for p in keeps_cheaters:
                print "cheating in keeps ", turns_played, p.id
                gt = self.kick(p, gt)

            # the current player is cheating! The bastard >:(
            # what to do in the case of the player trying to make an illegal merger
            # which causes other players to seem like they're cheating?
            # Also check that if player called merger placement
            if current_player_cheated.get() \
                    or (tile, maybeHotel) not in gt.get_tile_moves() \
                    or (merger_happened.get() and (tile, maybeHotel) != merger_placement.get()) \
                    or shares not in gt.get_share_moves(tile, maybeHotel, sell_back) \
                    or current_player in keeps_cheaters:
                print "cheating in take_turn", turns_played, current_player.id
                gt = self.kick(current_player, gt)
                continue

            new_tile = choice(gt.get_next_tiles())
            current_player.new_tile(new_tile)

            gt = gt.apply(tile, maybeHotel, sell_back, shares, new_tile)

            # finish the round and ensure that our list of Players
            # is in sync with gs's players
            yield gt.game_state

            # check to see if the game is over again,
            # now that the current player has taken his turn
            if self.is_game_over(gt.game_state, False):
                self.send_scores(gt.game_state)
                yield self.is_game_over(gt.game_state, False)
                return

            for _, p in copy(self.players):
                try:
                    p.inform(deepcopy(gt.game_state))
                except Exception as e:
                    gt = self.kick(p, gt)

            self.players.rotate(-1) # TODO: name this "CLOCKWISE"
            turns_played += 1

        self.send_scores(gt.game_state)
        yield GameOverReason.OUTOFTURNS
def main(ai: str) -> None:
    """
    This is the main function that allows for a user to play against an AI of their choice

    Preconditions:
        - ai == '1' or ai == '2'
    """
    board = Board()
    g = GameTree(board)
    p1 = HumanPlayer(g)
    p2 = Player(g)

    if ai == '1':
        p2 = RandomPlayer(g)
    elif ai == '2':
        p2 = MiniMaxPlayer(3, False)
    else:
        print('This is not a valid input')
        exit()

    while len(board.get_valid_moves()) != 0:
        board.draw_board(WIN)
        board.draw_pieces(WIN)
        pygame.display.update()
        # L Piece Red Move
        valid_moves = board.get_valid_moves()
        new_board = p1.make_move(valid_moves, board.board, 'red')
        board.previous_boards.append(board.board)
        board.move_type = 'black'
        board.board = new_board
        board.draw_pieces(WIN)
        pygame.display.update()

        # Neutral Piece Red Move
        yn = input(
            'Would you like to move a neutral piece? "Y" for yes, "N" for no')
        if yn == "Y":
            valid_moves = board.get_valid_moves()
            coords = p1.select_square()
            new_board = p1.move_neutral(valid_moves, board.board, coords)
            board.previous_boards.append(board.board)
            board.board = new_board
            board.draw_pieces(WIN)
            pygame.display.update()
        board.move_type = 'blue'

        # L Piece Blue Move
        valid_moves = board.get_valid_moves()
        new_board = p2.make_move(board)
        board.previous_boards.append(board.board)
        board.move_type = 'black'
        pygame.time.wait(1000)
        board.board = new_board
        board.draw_pieces(WIN)
        pygame.display.update()

        # Neutral Piece Blue Move
        valid_moves = board.get_valid_moves()
        new_board = p2.make_move(board)
        board.previous_boards.append(board.board)
        board.move_type = 'red'
        pygame.time.wait(1000)
        board.board = new_board
        board.draw_pieces(WIN)
        pygame.display.update()

    # Checks and prints winner
    if len(board.get_valid_moves()) == 0:
        winner = board.is_red_move
        if winner == 'red':
            print('Blue has won the game!')
        elif winner == 'blue':
            print('Red has won the game!')
Beispiel #14
0
def main():
    end = True
    firstMove = True
    tree = None
    grid = [['e' for x in range(0,15)] for x in range(0,15)]
    occupied = set()
    while (end):
        presenceGo()
        if os.path.exists("end_game"):
            end = False
            break
        opponent_move = read_move()

        if opponent_move is not None and firstMove is False:
            occupied.add((opponent_move[2], opponent_move[1]))
        if firstMove is True:
            firstMove = False
            tree = GameTree(True, 7, 7)
            grid[7][7] = 'o'
            write_move(7,7)
            occupied.add((7,7))
        else:
            best_value, chosen_state, actions = minimax(tree.root, -float('inf'), float('inf'), True, 2, occupied)
            x = 0
            y = 0

            heuristic3 = list()
            heuristic2 = list()
            heuristic1 = list()
            heuristic0 = list()
            move_coord = None
            for action in actions:
                x = action[0]
                y = action[1]
                new_grid = copy.deepcopy(grid)
                if new_grid[x][y] is 'e':
                    new_grid[x][y] = 'o'
                    heuristic, coordinate = evaluate(new_grid)
                    if heuristic > -1:
                        if heuristic is 0:
                            heuristic0.append(coordinate)
                        if heuristic is 1:
                            heuristic1.append(coordinate)
                        if heuristic is 2:
                            heuristic2.append(coordinate)
                        if heuristic is 3:
                            heuristic3.append(coordinate)
            if len(heuristic0) > 0:
                move_coord= heuristic0[0]
            if len(heuristic1) > 0:
                move_coord= heuristic1[0]
            if len(heuristic2) > 0:
                move_coord= heuristic2[0]
            if len(heuristic3) > 0:
                move_coord= heuristic3[0]

            break_flag = False
            if move_coord is None:
                for x in range(0, 15):
                    if break_flag is True:
                        break
                    for y in range(0, 15):
                        if grid[x][y] is 'e':
                            break_flag = True
                            write_move(x, y)
                            grid[x][y] = 'o'
                            break
            else:
                tree.root = chosen_state
                write_move(move_coord[0],move_coord[1])
                occupied.add((move_coord[0],move_coord[1]))
Beispiel #15
0
def parse_script(contents: str) -> GameTree:
    # TODO: this should parse multiple scenes.
    rest, scene = parse_scene(contents)
    if consume_space(rest) != '':
        raise ValueError('Malformed GameTree')
    return GameTree(scene)
Beispiel #16
0
 def __init__(self):
     random.seed()
     self.game_tree = GameTree()