Esempio n. 1
0
def minimax(board, depth, alpha, beta, maximizingPlayer):
    if depth == 0 or endgame(board):
        return eval_func(board)

    if maximizingPlayer:
        max_eval = -infinity
        all_moves = board.get_legal_moves(Team.WHITE)
        random.shuffle(all_moves)
        for current_move in all_moves:
            new_board = board.copy_state()
            new_board.play_command(Command(current_move[0], current_move[1]))
            eval = minimax(new_board, depth - 1, alpha, beta, False)
            max_eval = max(max_eval, eval)
            alpha = max(alpha, eval)
            if beta <= alpha:
                break
        return max_eval

    else:
        min_eval = +infinity
        all_moves = board.get_legal_moves(Team.BLACK)
        random.shuffle(all_moves)
        for current_move in all_moves:
            new_board = board.copy_state()
            new_board.play_command(Command(current_move[0], current_move[1]))
            eval = minimax(new_board, depth - 1, alpha, beta, True)
            min_eval = min(min_eval, eval)
            beta = min(beta, eval)
            if beta <= alpha:
                break
        return min_eval
Esempio n. 2
0
def min_max(board, depth, team):

    if depth >= MAX_DEPTH:
        h = heuristic(board, team)
        return [h, None]
    moves = []

    for move in remove_bad_moves(board):  # changer de player une fois sur deux
        current_board = board.copy_state()
        current_board.play_command(Command(move[0], move[1]))
        if current_board.get_winner() is None:
            pass
        elif current_board.get_winner() == team:
            return [1000, move]
        else:
            return [-10000, move]
        m = min_max(current_board, depth + 1, team)
        m[1] = move
        moves.append(m)

    if depth % 2 == 0:
        move1 = [test[0] for test in moves]
        selection = []
        for i, e in enumerate(move1):
            if e == max(move1):
                selection.append(i)
        move = moves[random.choice(selection)]
    else:
        move1 = [test[0] for test in moves]
        selection = []
        for i, e in enumerate(move1):
            if e == min(move1):
                selection.append(i)
        move = moves[random.choice(selection)]
    return move
Esempio n. 3
0
def get_command(board):
    while True:
        time.sleep(0.05)
        if board.game_over():
            break  # Thread closes once the game is over

        team_to_play = board.get_turn()

        print('{} to play...'.format('White' if team_to_play == Team.WHITE else 'Black'))
        move_from_str = input('Move from: ')
        move_to_str = input('Move to: ')

        letters = string.ascii_lowercase

        move_from_ls = list(move_from_str)
        move_to_ls = list(move_to_str)

        try:
            move_from_ls[0] = letters.index(move_from_ls[0].lower())
            move_to_ls[0] = letters.index(move_to_ls[0].lower())
            move_from = Vec2I(int(move_from_ls[0]), int(move_from_ls[1]))
            move_to = Vec2I(int(move_to_ls[0]), int(move_to_ls[1]))
        except ValueError:
            print('Please specify a letter then a number with no space between them. Example: d0 and d3')
            continue

        command = Command(move_from, move_to)
        return command
Esempio n. 4
0
def read_game_file(path):
    """
    Reads a JSON game file and returns a board with a list of command to interpret.

    Example of a very low rating game file:

    {
      "date": "24/02/2021 11:45:20",
      "cols": 8,
      "rows": 8,
      "stack": 8,
      "white_queen": "4, 1",
      "black_queen": "5, 8",
      "moves": ["4, 1 -> 4, 8", "5, 8 -> 4, 8"]
    }

    :param path: The path to the file
    :return: A dictionary containing the date, width, height, stack, white_queen, black_queen and moves positions
    encoded in the game's classes
    """
    data_formatted = {}
    with open(path, 'r') as infile:
        data = json.load(infile)

        data_formatted['cols'] = data['cols']
        data_formatted['rows'] = data['rows']
        data_formatted['stack'] = data['stack']

        white_queen = data['white_queen'].split(', ')
        black_queen = data['black_queen'].split(', ')

        data_formatted['white_queen'] = Vec2I.parse_from_list(white_queen)
        data_formatted['black_queen'] = Vec2I.parse_from_list(black_queen)

        date_str = data.get('date')
        if date_str is not None:
            date = datetime.datetime.strptime(date_str, '%d/%m/%Y %H:%M:%S')
            data_formatted['date'] = date

        command_list = []
        moves_str = data['moves']
        for move in moves_str:
            move_split = move.split(' -> ')
            move_from_str = move_split[0].split(', ')
            move_to_str = move_split[1].split(', ')
            move_from = Vec2I.parse_from_list(move_from_str)
            move_to = Vec2I.parse_from_list(move_to_str)
            command = Command(move_from, move_to)
            command_list.append(command)

        data_formatted['moves'] = command_list

        return data_formatted
Esempio n. 5
0
def make_play(board, your_team, last_move):
    """
    Example of a very stupid AI. Don't do this at home.
    """
    global DP_white, DP_black

    all_moves = board.get_legal_moves(your_team)
    queen_ennemy_pos = board.search_queen(
        get_ennemy_team(your_team)).get_position()

    values = -1e10
    poss_move = []

    leafs_explored = [0]
    for possible_move in all_moves:
        f, to = possible_move
        x = to.x
        y = to.y
        if x == queen_ennemy_pos.x and y == queen_ennemy_pos.y:
            # print('CAPTURE')
            return possible_move
        else:
            current_board = board.copy_state()
            current_board.play_command(Command(f, to))

            v = minimax_alpha_beta(convert_board(
                current_board), your_team, your_team, 1, leafs_explored, alpha=-1e9, beta=1e9)

            # print(v)

            if v > values:
                poss_move = [possible_move]
                values = v
            elif v == values:
                poss_move.append(possible_move)

        # print(len(DP_white))

    choice = random.choice(poss_move)
    print('SCORE  : ', values)
    print(your_team, 'MOVE', choice, 'LEAFS = ', leafs_explored[0])
    return choice
Esempio n. 6
0
def make_play(board, your_team, last_move):

    global turn

    all_moves = board.get_legal_moves(your_team)
    all_final_positions = [move[1] for move in all_moves]
    all_double_moves = []
    random.shuffle(all_moves)

    for final_position in all_final_positions:
        if all_final_positions.count(final_position) >= 2:
            all_double_moves.append(final_position)

    enemy_positions, enemy_moves = [], []
    for move in board.get_legal_moves(enemy_moves):
        enemy_positions.append(move[0])
        enemy_moves.append(move[1])

    enemy_team = Team.WHITE if your_team == Team.BLACK else Team.BLACK
    queen_in_danger = False
    for move in board.get_legal_moves(enemy_team):
        if move[1] == board.search_queen(your_team).get_position():
            queen_in_danger = True
            break

    queen_moves = []
    for move in all_moves:  # lists all queen moves that don't immediately put her in danger
        if move[0] == board.search_queen(your_team).get_position():
            if move[1] in enemy_moves:  # removes all moves putting the queen in the line of fire
                all_moves.pop(all_moves.index(move))
            else:
                queen_moves.append(move)

    if turn < 2:
        for move in all_moves:  # checks all moves in the outer center circle
            if move[1] in tier_2:
                all_moves.insert(0, all_moves.pop(all_moves.index(move)))

        for move in all_moves:  # checks all moves in the inner center circle
            if move[1] in tier_1:
                all_moves.insert(0, all_moves.pop(all_moves.index(move)))

    if queen_in_danger:  # if queen is in danger, checks all possible queen moves first
        for move in queen_moves:
            all_moves.insert(0, all_moves.pop(all_moves.index(move)))

    for move in all_moves:
        if move[1] in all_double_moves:
            all_moves.insert(0, all_moves.pop(all_moves.index(move)))

    for move in all_moves:  # checks all moves capable of capturing enemy monkeys
        if move[1] in enemy_positions:
            all_moves.insert(0, all_moves.pop(all_moves.index(move)))

    for move in all_moves:  # checks all moves on an enemy path LAST
        if move[1] in enemy_moves:
            all_moves.append(all_moves.pop(all_moves.index(move)))

    best_move = all_moves[0]
    init_time = time.time()

    if your_team == Team.WHITE:
        best_val = -infinity
        for current_move in all_moves:
            new_board = board.copy_state()
            new_board.play_command(Command(current_move[0], current_move[1]))
            val = minimax(new_board, depth, alpha, beta, False)
            if val > best_val:
                best_val = val
                best_move = current_move
            curr_time = time.time()
            print(curr_time - init_time)
            if curr_time - init_time > time_limit:
                break

    else:
        best_val = +infinity
        for current_move in all_moves:
            new_board = board.copy_state()
            new_board.play_command(Command(current_move[0], current_move[1]))
            val = minimax(new_board, depth, alpha, beta, True)
            if val < best_val:
                best_val = val
                best_move = current_move
            curr_time = time.time()
            print(curr_time - init_time)
            if curr_time - init_time > time_limit:
                break

    turn += 1

    return best_move
Esempio n. 7
0
 def list_plays(self, player):
     legal_commands = []
     legal_moves = self._game.get_legal_moves(player)
     for move_pair in legal_moves:
         legal_commands.append(Command(move_pair[0], move_pair[1]))
     return legal_commands
Esempio n. 8
0
def make_play(board, your_team, last_move):
    current_board1 = board.copy_state()
    enemy_team = Team.WHITE if your_team == Team.BLACK else Team.BLACK
    print(enemy_team)
    enemy_queen = board.search_queen(enemy_team)

    noeud1 = 0
    score1 = []
    all_moves = board.get_legal_moves(your_team)
    for move in all_moves:
        board = current_board1.copy_state()
        enemy_queen = board.search_queen(enemy_team)
        if move[1] == enemy_queen.get_position():
            print("sortie1")
            return move
        move_command = Command(move[0], move[1])
        board.play_command(move_command)

        current_board2 = board.copy_state()
        noeud2 = 0
        score2 = []
        opponent_possible_responses = board.get_legal_moves()
        try:
            for opponent_possible_move in opponent_possible_responses:
                board = current_board2.copy_state()
                opponent_possible_move_command = Command(
                    opponent_possible_move[0], opponent_possible_move[1])
                board.play_command(opponent_possible_move_command)
                if opponent_possible_move[1] == enemy_queen.get_position():
                    print("ko")
                    break
                current_board3 = board.copy_state()
                noeud3 = 0
                enemy_queen = board.search_queen(enemy_team)
                responses = board.get_legal_moves()
                for response_move in responses:
                    board = current_board3
                    enemy_queen = board.search_queen(enemy_team)
                    try:
                        response_move_command = Command(
                            response_move[0], response_move[1])
                        board.play_command(response_move_command)
                        if board.game_over:
                            return move
                        score3 = 100 - 10 * getdistance(
                            response_move[1], enemy_queen)
                        noeud3 = score3 if score3 >= noeud3 else noeud3
                    except Exception:
                        pass
                score2.append(noeud3)
            noeud2 = min(score2)
        except Exception:
            pass

        score1.append(noeud2)

    if len(score1) == len(all_moves):
        noeud1 = max(score1)
        selected_move = all_moves[score1.index(noeud1)]
        return selected_move
    else:
        print(" y a un pépin kekpart :( ")
Esempio n. 9
0
def make_play(board, your_team, last_move):
    """
    Your AI entry point. This function gets called every time your AI is asked to make a play.
    The parameters contains all the information you need to picture the game state.

    The given lists of entities, queen information, etc... are a deep copy of the current game state, so don't try
    changing values there as this won't impact the game :p

    The execution time of this function is taken into account at each move, and a time limit is given to each team.

    :param board: the whole game state

    :param your_team: your team. Either Team.WHITE or Team.BLACK

    :param last_move: a tuple of two Vec2I (Vec2I(x_from, y_from), Vec2I(x_to, y_to)) of your opponent's last move.
    None if you are doing the first game move.

    :return: two objects Vec2I, Vec2I. The first object is the position of the piece you want to move, the second
    """

    # a list containing all the entities from all the teams (either Monkeys or Queens)
    entities = board.get_entities()

    # just like entities, but into a map (dictionary). The key is a Vec2I object containing the position where you
    # want to get the entity. Use entity_map.get(Vec2I(x, y)) instead of entity_map[Vec2I(x, y)] if you want to avoid
    # raising a KeyError. Vec2I is used for the positions
    entity_map = board.get_entity_map()

    # List all the possible legal moves
    all_possible_moves = board.get_legal_moves(your_team)

    # You can iterate over all the entities like so:
    for entity in entities:
        position = entity.get_position()
        team = entity.get_team()
        print('Entity at position {}, is from team {}'.format(position, team))

    # You can get other information from the board functions.
    your_queen = board.search_queen(your_team)

    # There are only two teams, either Team.WHITE or Team.BLACK
    enemy_team = None
    if your_team == Team.WHITE:
        enemy_team = Team.BLACK
    else:
        enemy_team = Team.WHITE

    # you can do the same with this one liner
    enemy_team = Team.WHITE if your_team == Team.BLACK else Team.BLACK

    # get the enemy queen info from the board
    enemy_queen = board.search_queen(enemy_team)

    # Get the position of an entity, for example, with this queen
    # This can also work with Monkeys
    your_queen_position = enemy_queen.get_position()

    # Get the queen stack (number of remaining monkeys)
    your_queen_stack = your_queen.get_stack()

    # Print the position information, positions use the object Vec2I, defined in the file src/game/geo.py
    print(your_queen_position.x, your_queen_position.y)

    # Get all the possible moves for your queen
    possible_moves = your_queen.get_legal_moves()

    # We want to move our queen one cell down
    your_queen_x = your_queen_position.x
    your_queen_y = your_queen_position.y

    # Again, the game uses the Vec2I object for the positions
    new_position = Vec2I(your_queen_x, your_queen_y + 1)

    # As the board is a DEEP COPY of the real board, you can use it to forecast the future, for example, if you
    # want to list all your enemy moves after the move you want to select

    # As said, you have to return a tuple of Vec2I from this function, but to make a play you have to put those
    # two Vec2I in a Command object
    move_command = Command(your_queen_position, new_position)

    # Make a copy of the current game state
    current_board = board.copy_state()

    # Plays the command, now the board is just like you have played your decised move
    board.make_play(move_command)

    # Forecast all the legal moves from your opponent
    opponent_possible_responses = board.get_legal_moves()

    # We check if the new position is a legal move
    if new_position in possible_moves:
        # We make this play by returning the new_position
        return your_queen_position, new_position
    else:
        new_position = random.choice(possible_moves)
        return your_queen_position, new_position
Esempio n. 10
0
from src.game.command import Command
from src.game.geo import Vec2I

ROWS = 8
COLS = 8

white_queen = Queen(Vec2I(3, 0), Team.WHITE, monkey_stack=8)
black_queen = Queen(Vec2I(4, 7), Team.BLACK, monkey_stack=8)

board = Board(cols=COLS, rows=ROWS)
board.add_entity(white_queen)
board.add_entity(black_queen)

board.draw()

while True:
    str_from = input('Piece from (x, y): ')
    str_from = str_from.split(',')
    pos_from = Vec2I.parse_from_list(str_from)

    str_to = input('Piece to (x, y): ')
    str_to = str_to.split(', ')
    pos_to = Vec2I.parse_from_list(str_to)

    command = Command(pos_from, pos_to)

    try:
        board.play_command(command)
    except GameException as exc:
        print(exc)
Esempio n. 11
0
def play_match(white_team, black_team, white_team_path, black_team_path):
    print('\033[1;36;40m Starting match {} vs {} \033[1;33;40m'.format(
        white_team, black_team))
    date = datetime.datetime.now()

    dict = {}
    dict['date'] = date.strftime('%d/%m/%Y %H:%M:%S')
    dict['white_team'] = white_team
    dict['black_team'] = black_team
    dict['stack'] = 12
    dict['cols'] = 8
    dict['rows'] = 8
    dict['white_queen'] = '3, 0'
    dict['black_queen'] = '4, 7'

    moves = []

    last_move = None

    winner = None

    reason = 'None'

    white_remaining_time_ms = 4 * 60 * 1000  # 3 minutes
    black_remaining_time_ms = 4 * 60 * 1000  # 3 minutes

    white_team_function = load_function(white_team_path)
    black_team_function = load_function(black_team_path)

    board = load_game()

    signal.signal(signal.SIGALRM, timeout_handler)

    while board.get_winner() is None:

        if len(board.get_legal_moves()) == 0:
            winner = Team.WHITE if board.get_turn(
            ) == Team.BLACK else Team.BLACK
            reason = 'out of legal moves'
            print(
                '\033[1;31;40m Game over. {} is out of legal moves.\033[1;37;40m'
                .format('black' if winner == Team.WHITE else 'white'))
            break

        board_copy = board.copy_state()
        start = datetime.datetime.now()

        if board.get_turn() == Team.WHITE:
            try:
                print('\033[1;32;40m White to play \033[1;37;40m')
                signal.alarm(int(white_remaining_time_ms / 1000))
                play = white_team_function(board_copy, Team.WHITE, last_move)
                signal.alarm(0)
                last_move = play

                end = datetime.datetime.now()
                diff = int((end - start).seconds * 1000)
                white_remaining_time_ms -= diff

                command = Command(play[0], play[1])
                board.play_command(command)
                moves.append('({}, {} -> {}, {})'.format(
                    play[0].x, play[0].y, play[1].x, play[1].y))
            except TimeOutException as tout:
                print(
                    '\033[1;31;40m Team {} timed out, dropping the game.\033[1;37;40m'
                    .format(white_team))
                reason = 'timeout'
                winner = Team.BLACK
                break
            except Exception as e:
                print(
                    '\033[1;31;40m Team: {} got exception: {}, dropping the game\033[1;37;40m'
                    .format(white_team, e))
                reason = 'exception'
                winner = Team.BLACK
                break
        else:
            try:
                print('\033[1;32;40m Black to play \033[1;37;40m')
                signal.alarm(int(black_remaining_time_ms / 1000))
                play = black_team_function(board_copy, Team.BLACK, last_move)
                signal.alarm(0)
                last_move = play

                end = datetime.datetime.now()
                diff = int((end - start).seconds * 1000)
                black_remaining_time_ms -= diff

                command = Command(play[0], play[1])
                board.play_command(command)
                moves.append('({}, {} -> {}, {})'.format(
                    play[0].x, play[0].y, play[1].x, play[1].y))
            except TimeOutException as tout:
                print(
                    '\033[1;31;40m Team {} timed out, dropping the game.\033[1;37;40m'
                    .format(black_team))
                reason = 'timeout'
                winner = Team.WHITE
                break
            except Exception as e:
                print(
                    '\033[1;31;40m Team: {} got exception: {}, dropping the game\033[1;37;40m'
                    .format(black_team, e))
                reason = 'exception'
                winner = Team.WHITE
                break

        print('Move player: {} from team {}. White time: {} Black time: {}'.
              format(last_move,
                     'white' if board.get_turn() == Team.BLACK else 'black',
                     white_remaining_time_ms, black_remaining_time_ms))

    if winner is None:
        print("\033[1;31;40mQueen captured!\033[1;37;40m")
        winner = board.get_winner()
        reason = 'queen captured'

    print('\033[1;31;40m Match {} vs {}, team {} wins\033[1;37;40m'.format(
        white_team, black_team,
        white_team if winner == Team.WHITE else black_team))
    dict['winner'] = 'white' if winner == Team.WHITE else 'black'
    dict['white_remaining_time'] = white_remaining_time_ms
    dict['black_remaining_time'] = black_remaining_time_ms
    dict['moves'] = moves
    dict['reason'] = reason

    return dict
Esempio n. 12
0
def minimax(board,
            your_team,
            enemy_team,
            max_depth,
            part,
            cut,
            root_move=None,
            score=0,
            depth=0,
            alpha=(-math.inf, None),
            beta=(math.inf, None),
            maximizingPlayer=True):
    if depth == max_depth:
        answer = (score, root_move)

    elif maximizingPlayer:
        maxEval = (-math.inf, root_move)
        pruning = False
        moves = board.get_legal_moves(your_team)
        if depth == 0:
            moves = moves[round(len(moves) / cut *
                                part):round(len(moves) / cut * (part + 1))]
        i = 0
        while i < len(moves) and not pruning:
            if depth == 0:
                root_move = moves[i]
            map = board.get_entity_map()

            sourceMove = Vec2I(moves[i][0].x, moves[i][0].y)
            targetMove = Vec2I(moves[i][1].x, moves[i][1].y)
            sourcePawn = map.get(sourceMove)
            targetPawn = map.get(targetMove)
            value = 0
            if targetPawn:
                if targetPawn.is_queen():
                    return (math.inf, root_move)
                else:
                    value += 1
            if sourcePawn:
                if sourcePawn.is_queen():
                    if not targetPawn:
                        value += 0.6
            new_move = Command(moves[i][0], moves[i][1])
            new_board = board.copy_state()
            new_board.play_command(new_move)
            evaluation = minimax(new_board, your_team, enemy_team, max_depth,
                                 part, cut, root_move, score + value,
                                 depth + 1, alpha, beta, False)
            if maxEval[0] != evaluation[0]:
                maxEval = max(maxEval, evaluation)
            if alpha[0] != evaluation[0]:
                alpha = max(alpha, evaluation)
            if beta[0] <= alpha[0]:
                pruning = True
            i = i + 1
        answer = maxEval

    else:
        minEval = (math.inf, root_move)
        pruning = False
        moves = board.get_legal_moves(enemy_team)
        i = 0
        while i < len(moves) and not pruning:
            map = board.get_entity_map()
            sourceMove = Vec2I(moves[i][0].x, moves[i][0].y)
            targetMove = Vec2I(moves[i][1].x, moves[i][1].y)
            sourcePawn = map.get(sourceMove)
            targetPawn = map.get(targetMove)
            value = 0
            if targetPawn:
                if targetPawn.is_queen():
                    return (-math.inf, root_move)
                else:
                    value -= 1
            if sourcePawn:
                if sourcePawn.is_queen():
                    if not targetPawn:
                        value -= 0.6
            new_move = Command(moves[i][0], moves[i][1])
            new_board = board.copy_state()
            new_board.play_command(new_move)
            evaluation = minimax(new_board, your_team, enemy_team, max_depth,
                                 part, cut, root_move, score + value,
                                 depth + 1, alpha, beta, True)
            if minEval[0] != evaluation[0]:
                minEval = min(minEval, evaluation)
            if beta[0] != evaluation[0]:
                beta = min(beta, evaluation)
            if beta[0] <= alpha[0]:
                pruning = True
            i = i + 1
        answer = minEval
    return answer