示例#1
0
def dijkstra(tiles, adversary_color, player):
    """Medium AI, makes a move that minimizes the other player's mobility"""
    # mobility is defined as the other player's possible moves

    print("{} is thinking...".format(
        othello.color(adversary_color, "Edsger Dijkstra")))
    time.sleep(2)

    potential_moves = []
    for index in range(64):
        if othello.is_valid_move(index, player, adversary=True,
                                 b=tiles) and tiles[index] == 0:
            potential_moves.append(index)

    best_move = 0
    worst_mobility = sys.maxsize
    for move in potential_moves:
        copy = [tile for tile in tiles]
        board = othello.propogate_flips(move, player, adversary=True, b=copy)
        other_player = 2 if player == 1 else 1
        mobility = len([
            index for index in range(64) if
            othello.is_valid_move(index, other_player, adversary=True, b=board)
            and board[index] == 0
        ])
        if mobility < worst_mobility:
            worst_mobility = mobility
            best_move = move

    print("{} moved to {}!".format(
        othello.color(adversary_color, "Edsger Dijkstra"),
        othello.get_coordinate_from_index(best_move)))
    time.sleep(2)
    return best_move
示例#2
0
def lovelace(tiles, adversary_color, player):
    """Easy AI, makes a move that maximizes its number of pieces on the board"""

    print("{} is thinking...".format(
        othello.color(adversary_color, "Ada Lovelace")))
    time.sleep(2)

    potential_moves = []
    for index in range(64):
        if othello.is_valid_move(index, player, adversary=True,
                                 b=tiles) and tiles[index] == 0:
            potential_moves.append(index)

    best_move = 0
    best_total = 0
    for move in potential_moves:
        copy = [tile for tile in tiles]
        board = othello.propogate_flips(move, player, adversary=True, b=copy)
        number_of_tiles = len([tile for tile in board if tile == 2])
        if number_of_tiles > best_total:
            best_total = number_of_tiles
            best_move = move

    print("{} moved to {}!".format(
        othello.color(adversary_color, "Ada Lovelace"),
        othello.get_coordinate_from_index(best_move)))
    time.sleep(2)
    return best_move
示例#3
0
def calculate_your_mobility(board, player):
    mobility = len([
        index for index in range(64) if othello.is_valid_move(
            index, player if player == 2 else 1, adversary=True, b=board)
        and board[index] == 0
    ])
    return mobility
示例#4
0
def euclid(tiles, adversary_color, player):
    """Simple AI, makes a random move from its potential moves"""

    print("{} is thinking...".format(othello.color(adversary_color, "Euclid")))
    time.sleep(2)

    potential_moves = []
    for index in range(64):
        if othello.is_valid_move(index, player, adversary=True,
                                 b=tiles) and tiles[index] == 0:
            potential_moves.append(index)

    print(
        [othello.get_coordinate_from_index(move) for move in potential_moves])
    input()

    move = random.choice(potential_moves)
    print("{} moved to {}!".format(othello.color(adversary_color, "Euclid"),
                                   othello.get_coordinate_from_index(move)))
    time.sleep(2)
    return move
示例#5
0
def turing(tiles, adversary_color, player):
    """Hard AI, makes a move that minimizes the other player's mobility, maximizes its own mobility, and avoids giving the other user corners"""

    # Priorities:
    #  1. If corner is available, take it
    #  2. If a move gives opponent a corner, don't consider it (unless necessary)
    #  3. Don't play in C Squares (unless necessary)
    #  4. Maximize our mobility
    #  5. Minimize opponent's mobility
    #  6. Control the sweet 16

    # If you wanted to improve this more, here are other, not currently, explicitly implemented considerations:
    #  - consider interior vs. frontior disks
    #  - consider A- and B-squares (prioritize taking wall moves more)
    #  - consider power moves/attacks for taking corners

    print("{} is thinking...".format(
        othello.color(adversary_color, "Alan Turing")))
    time.sleep(2)

    potential_moves = []
    for index in range(64):
        if othello.is_valid_move(index, player, adversary=True,
                                 b=tiles) and tiles[index] == 0:
            potential_moves.append(index)

    # STEP 1
    # determine if moves could give opponent a corner
    bad_corner_moves = []
    for move in potential_moves:
        copy = [tile for tile in tiles]
        board = othello.propogate_flips(move, player, adversary=True, b=copy)

        other_player = 2 if player == 1 else 1
        if not len([
                index for index in range(64) if othello.is_valid_move(
                    index, other_player, adversary=True, b=board)
                and board[index] == 0 and index in CORNERS
        ]) == 0:
            bad_corner_moves.append(move)

    # determine if can get a corner right now
    good_corner_moves = []
    for move in potential_moves:
        if move in CORNERS:
            good_corner_moves.append(move)

    # STEP 2
    # begin evaluating move candidates to find best move
    best_move = -1
    if not len(good_corner_moves) == 0:
        # we can take a corner
        most_tiles = 0
        best_move = good_corner_moves[0]
        for corner_move in good_corner_moves:
            copy = [tile for tile in tiles]
            board = othello.propogate_flips(move,
                                            player,
                                            adversary=True,
                                            b=copy)
            number_of_tiles = len([tile for tile in board if tile == player])
            if number_of_tiles > most_tiles:
                most_tiles = number_of_tiles
                best_move = corner_move
    else:
        # we can't take a corner
        good_moves = [
            move for move in potential_moves if not move in bad_corner_moves
            and not move in X_SQUARES and not move in C_SQUARES
        ]
        if len(good_moves) == 0:
            good_moves = [
                move for move in potential_moves
                if not move in bad_corner_moves and not move in X_SQUARES
            ]
            if len(good_moves) == 0:
                good_moves = [
                    move for move in potential_moves
                    if not move in bad_corner_moves
                ]
                if len(good_moves) == 0:
                    good_moves = potential_moves

        # begin mobility score calculation
        temp_mobility_scores = {}
        max_my_mobility = 0
        min_your_mobility = sys.maxsize
        max_sweet_score = 0

        # go through all moves and calculate increases in my mobility and decreases in your mobility
        for move in good_moves:
            copy = [tile for tile in tiles]
            board = othello.propogate_flips(move,
                                            player,
                                            adversary=True,
                                            b=copy)

            temp_my_mobility = calculate_my_mobility(board, player)
            max_my_mobility = temp_my_mobility if temp_my_mobility > max_my_mobility else max_my_mobility

            temp_your_mobility = calculate_your_mobility(board, other_player)
            min_your_mobility = temp_your_mobility if temp_your_mobility < min_your_mobility else min_your_mobility

            temp_sweet_score = calculate_sweet_16_score(board, player)
            max_sweet_score = temp_sweet_score if temp_sweet_score > max_sweet_score else max_sweet_score

            temp_mobility_scores[move] = (temp_my_mobility, temp_your_mobility,
                                          temp_sweet_score)

        # bound mobility scores between 0 and 1
        mobility_scores = {}
        for move, scores in temp_mobility_scores.items():
            if max_my_mobility == 0:
                my_mobility_score = 0
            else:
                my_mobility_score = (scores[0] / max_my_mobility)

            if min_your_mobility == sys.maxsize:
                your_mobility_score = 0
            else:
                your_mobility_score = (scores[1] / min_your_mobility)

            if max_sweet_score == 0:
                max_sweet = 0
            else:
                max_sweet = (scores[2] / max_sweet_score)
            mobility_scores[move] = (my_mobility_score, your_mobility_score,
                                     max_sweet)

        # give each move a final mobility score to rank them
        best_move = 0
        best_mobility_score = 0
        for move, scores in mobility_scores.items():
            # weighted sum: 50% my increased mobility, 25% your decreased mobility, 25% sweet 16 control increase
            mobility_score = (0.5 * scores[0]) + (0.25 * scores[1]) + (
                0.25 * scores[2])
            if mobility_score > best_mobility_score:
                best_move = move
                best_mobility_score = mobility_score

    if best_move == -1:
        print("ERROR: Alan Turing couldn't find a move!")
        sys.exit(0)

    print("{} moved to {}!".format(
        othello.color(adversary_color, "Alan Turing"),
        othello.get_coordinate_from_index(best_move)))
    time.sleep(2)
    return best_move