Exemple #1
0
def get_next_move(board, token):
    available_moves = game.available_moves(board)
    preferred_locaitons = [3, 2, 4, 1, 5, 0, 6]

    best_value = float('-inf')
    best_move = random.choice(available_moves)

    other_token = 'X' if token == 'O' else 'O'

    for move in available_moves:
        new_board = copy_board(board)
        game.make_move(new_board, move, token)
        if game.check_winner(new_board):
            return move

    for move in available_moves:
        new_board = copy_board(board)
        game.make_move(new_board, move, other_token)
        if game.check_winner(new_board):
            return move

    for move in preferred_locaitons:
        if move not in available_moves:
            continue
        return move

        # move_value = minimax(new_board, 0, False, token, other_token)
        # if move_value > best_value:
        #     best_move = move

    return best_move
Exemple #2
0
def get_next_move(board, token):
    available_moves = game.available_moves(board)
    available_positions = list(
        zip(available_moves, available_rows(available_moves, board)))

    other_token = define_other_token(token)

    #TODO pre-calculate those as part of the setup()
    available_lines_of_4 = [
        line for line in game.LINES_OF_4
        if not set(available_positions).isdisjoint(line)
    ]
    outcome = dict()

    smallest_tokens_missing = 5

    for line_of_4 in available_lines_of_4:
        token_missing = get_nb_token_missing(board, line_of_4)

        if smallest_tokens_missing > token_missing:
            outcome = defaultdict(
                list)  #was int in tournament but allows better debugging
            smallest_tokens_missing = token_missing
        if token_missing == smallest_tokens_missing and smallest_tokens_missing < 5:
            the_moves = list(set(line_of_4) & set(available_positions))
            for move in the_moves:
                outcome[move[0]].append(list)

    #Format changed for Clarity
    proposals = [
        Proposal(col=i, row=board[i].index('.'), nb=len(j))
        for i, j in outcome.items()
    ]

    if "DEBUG" in os.environ:
        print(f"==>From Athanase playing {token}")
        print(
            f"===>I had {len(available_moves)} available moves {available_moves}"
        )
        print(
            f"===>Those were part of  {len(available_lines_of_4)} lines of 4:")
        print(f"====>{available_lines_of_4}")
        print(
            f"===>I have select {len(proposals)} of then that have {smallest_tokens_missing} missing:"
        )
        print(f"====>{proposals}")

    try:
        outputs = [
            e.col for e in proposal if cut_fn(e) == max(
                cut_fn(x) for x in proposal)
        ]
        output = random.choice(outputs)
    except:
        output = random.choice(available_moves)
    return output
Exemple #3
0
def get_next_move(board, token):
    available_moves = game.available_moves(board)
    preferred_locations = [3, 2, 4, 1, 5, 0, 6]
    priority_locations = get_columns_with_space(board, token,
                                                preferred_locations)
    avoid_locations = []

    moves_played = get_moves_played(board)

    # best_value = float('-inf')
    # best_move = random.choice(available_moves)

    other_token = 'X' if token == 'O' else 'O'

    for move in available_moves:
        new_board = copy_board(board)
        game.make_move(new_board, move, token)
        if game.check_winner(new_board):
            return move

    for move in available_moves:
        new_board = copy_board(board)
        game.make_move(new_board, move, other_token)
        if game.check_winner(new_board):
            return move

    for move in available_moves:
        try:
            new_board = copy_board(board)
            game.make_move(new_board, move, token)
            game.make_move(new_board, move, other_token)
            if game.check_winner(new_board):
                avoid_locations.append(move)
        except:
            continue

    if moves_played == 1:
        # Don't go on top of the previous player
        avoid_locations.append(find_enemy_location(board, other_token))

    for move in priority_locations:
        if move not in available_moves or move in avoid_locations:
            continue
        return move

    for move in preferred_locations:
        if move not in available_moves or move in avoid_locations:
            continue
        return move

    return random.choice(available_moves)
Exemple #4
0
def minimax(board, depth, maxplayer, token, other_token):
    if depth == 0:
        return get_board_value(board, token)
    if maxplayer:
        value = float('-inf')
        for move in game.available_moves(board):
            new_board = copy_board(board)
            game.make_move(new_board, move, token)
            if game.check_winner(new_board):
                return float('inf')
            value = max(
                value, minimax(new_board, depth - 1, False, token,
                               other_token))
        return value
    else:
        value = float('inf')
        for move in game.available_moves(board):
            new_board = copy_board(board)
            game.make_move(new_board, move, other_token)
            if game.check_winner(new_board):
                return float('-inf')
            value = min(
                value, minimax(new_board, depth - 1, True, token, other_token))
        return value
def get_next_move(board, token):
    available_moves = game.available_moves(board)
    available_position = [(a, board[a].index('.')) for a in available_moves]
    available_play = available_position

    if token == 'X':
        other_token = 'O'
    else:
        other_token = 'X'

    possible = [
        line for line in game.LINES_OF_4
        if not set(available_position).isdisjoint(line)
    ]
    outcome = dict()

    best = 5

    for line in possible:
        remaining, letter = remaining_to_win(board, line, token)
        if remaining == 5:
            continue

        if best > remaining:
            outcome = defaultdict(int)
            outcome_assign = defaultdict()
            best = remaining

        if best == remaining:
            the_moves = list(set(line) & set(available_play))
            for move in the_moves:
                outcome[move[0]] += 1
                if letter == token:
                    outcome_assign[move[0]] = letter

    #tuple number of line_4, row, cols
    proposals = list((j, board[i].index('.'), i) for i, j in outcome.items())

    if best == 1:
        return select_for_victory(board, outcome_assign, proposals, token)

    traps = get_traps(board, game.LINES_OF_4, best, token)
    proposals_minus_traps = [
        prop for prop in proposals
        if not any((prop[2], prop[1] + 1) in trap for trap in traps)
    ]
    outputs = [
        e[2] for e in proposals_minus_traps if cut_fn(e) == max(
            cut_fn(x) for x in proposals_minus_traps)
    ]

    outputs = outputs or [
        avail[0] for avail in available_play if not any(
            (avail[0], avail[1] + 1) in trap for trap in traps)
    ]
    if len(outputs) == 0:
        deadly_traps = get_his_deadly_traps(board, game.LINES_OF_4, best,
                                            token)
        outputs = [
            avail[0] for avail in available_play if not any(
                (avail[0], avail[1] + 1) in trap for trap in deadly_traps)
        ]
    outputs = outputs or available_moves
    try:
        output = random.choice(outputs)
    except:
        output = random.choice(available_moves)
    return output
Exemple #6
0
def get_next_move(board, token):
    available_moves = game.available_moves(board)
    available_position = [(a, board[a].index('.')) for a in available_moves]
    available_play = available_position

    if token == 'X':
        other_token = 'O'
    else:
        other_token = 'X'

    possible = [
        line for line in game.LINES_OF_4
        if not set(available_position).isdisjoint(line)
    ]

    outcome = dict()

    best = 5

    for line in possible:
        remaining, letter = remaining_to_win(board, line, token)
        if remaining == 5:
            continue

        if best > remaining:
            outcome = defaultdict(int)
            outcome_assign = defaultdict()
            best = remaining

        if best == remaining:
            the_moves = list(set(line) & set(available_play))
            for move in the_moves:
                outcome[move[0]] += 1
                if letter == token:
                    outcome_assign[move[0]] = letter

    #tuple number of line_4, row, cols
    proposals = [(i, board[i].index('.'), 0, 0, j) for i, j in outcome.items()]

    if best == 1:
        return select_for_victory(board, outcome_assign, proposals, token)

    traps = get_traps(board, game.LINES_OF_4, best, token)

    #Do not fall in a trap.
    proposals_minus_traps = [
        prop for prop in proposals
        if not any((prop[0], prop[1] + 1) in trap for trap in traps)
    ]
    #We have a choice, let's see if we can set a trap
    if len(proposals_minus_traps) > 1:
        friendly_traps = get_his_deadly_traps(board, game.LINES_OF_4, best,
                                              other_token)
        available_traps = set(pos for trap in friendly_traps for pos in trap
                              if get_letter_of_pos(pos, board) == ".")
        trap_columns = set(pos[0] for pos in available_traps)
        the_existing = [
            e[0] for e in proposals_minus_traps
            if (e[0], e[1]) in available_traps
        ]
        board1 = copy.deepcopy(board)
        improved_proposals = list()

        for col, row, _, _, remaining in proposals_minus_traps:
            board1[col][row] = token
            new_friendly_traps = get_his_deadly_traps(board1,
                                                      (traps + possible), best,
                                                      other_token)
            all_new_traps = set(pos for trap in new_friendly_traps
                                for pos in trap
                                if get_letter_of_pos(pos, board1) == ".")
            new_traps = all_new_traps - available_traps
            above_each_other = len(
                [trap for trap in new_traps if trap[0] in trap_columns])
            improved_proposals.append(
                (col, row, above_each_other, len(new_traps), remaining))
            board1[col][row] = '.'
        if len(improved_proposals):
            proposals_minus_traps = improved_proposals

    outputs = [
        e[0] for e in proposals_minus_traps if cut_fn(e) == max(
            cut_fn(x) for x in proposals_minus_traps)
    ]

    outputs = outputs or [
        avail[0] for avail in available_play if not any(
            (avail[0], avail[1] + 1) in trap for trap in traps)
    ]
    if len(outputs) == 0:
        deadly_traps = get_his_deadly_traps(board, game.LINES_OF_4, best,
                                            token)
        outputs = [
            avail[0] for avail in available_play if not any(
                (avail[0], avail[1] + 1) in trap for trap in deadly_traps)
        ]
    outputs = outputs or available_moves
    try:
        output = random.choice(outputs)
    except:
        output = random.choice(available_moves)
    return output
Exemple #7
0
def get_next_move(board, token):
    board_columns_used = get_board_columns_used(board)
    available_moves = game.available_moves(board)
    preferred_locations = [3, 2, 4, 1, 5, 0, 6]
    preferred_locations = [x for x in preferred_locations if x in available_moves]
    priority_locations = get_columns_with_space(board, token, preferred_locations)
    opcode_limit = get_opcode_limit()
    losing_locations = set()
    skip_moves = set()

    # if state is None:
    #     state = {'opening_trap': False}

    moves_played = get_moves_played(board)

    other_token = 'X' if token == 'O' else 'O'

    for move in available_moves:
        board[move][board_columns_used[move]] = token
        if check_winner(board, move, board_columns_used[move]):
            print('MOVE: winning move')
            return move
        board[move][board_columns_used[move]] = '.'

    for move in available_moves:
        board[move][board_columns_used[move]] = other_token
        if check_winner(board, move, board_columns_used[move]):
            print('MOVE: blocking enemy win')
            return move
        board[move][board_columns_used[move]] = '.'

    for move in available_moves:
        if board_columns_used[move] > 4:
            continue
        board[move][board_columns_used[move]] = token
        board[move][board_columns_used[move] + 1] = other_token

        if check_winner(board, move, board_columns_used[move] + 1):
            losing_locations.add(move)

        board[move][board_columns_used[move]] = '.'
        board[move][board_columns_used[move] + 1] = '.'

    # Opening book
    if moves_played == 1:
        if board[3][0] == other_token:
            losing_locations.add(3)

    if moves_played == 2:
        if board[3][1] == other_token:
            # state['opening_trap'] = True
            return 2
        if board[2][0] == other_token:
            return 2
        if board[4][0] == other_token :
            return 4

    if moves_played == 4:
        if board[3][1] == other_token and board[1][0] == '.' and board[4][0] == '.':
            return 4

    # Take the move if you see a open-ended 3 way opportunity
    for move in available_moves:
        if move in losing_locations:
            continue
        if move_makes_3_horizontal_with_spaces(board, move, board_columns_used[move], token):
            print('MOVE: 3-way opportunity')
            return move

    # Block 2 adjacent tokens for the enemy
    for move in available_moves:
        if move_makes_3_horizontal_with_spaces(board, move, board_columns_used[move], other_token):
            print('MOVE: block 3-way opportunity')
            return move

    for move in available_moves:
        if move in losing_locations or board_columns_used[move] > 4:
            continue
        board[move][board_columns_used[move]] = token
        board[move][board_columns_used[move] + 1] = token

        if check_winner(board, move, board_columns_used[move] + 1, ignore_vertical=True):
            skip_moves.add(move)

        board[move][board_columns_used[move]] = '.'
        board[move][board_columns_used[move] + 1] = '.'

    print(get_opcode_count())

    # Look for forced wins
    for move in skip_moves:
        if move in losing_locations or board_columns_used[move] > 2:
            continue
        board[move][board_columns_used[move]] = token
        board[move][board_columns_used[move] + 1] = other_token
        board[move][board_columns_used[move] + 2] = token

        if check_winner(board, move, board_columns_used[move] + 2):
            print('MOVE: Force WIN')
            return move

        board[move][board_columns_used[move] + 2] = '.'
        board[move][board_columns_used[move] + 1] = '.'
        board[move][board_columns_used[move]] = '.'

    # # Look for a sure win:
    # for move in available_moves:
    #     print(f'sure {move}')
    #     if move in losing_locations or board_columns_used[move] > 2:
    #         continue
    #     copy_board = [x[:] for x in board]
    #     copy_board_columns_used = board_columns_used[:]
    #     copy_board[move][copy_board_columns_used[move]] = token
    #     # copy_board[move][copy_board_columns_used[move] + 1] = token
    #
    #     # if not check_winner(copy_board, move, board_columns_used[move] + 1):
    #     #     continue
    #
    #     # copy_board[move][copy_board_columns_used[move] + 1] = '.'
    #     copy_board_columns_used[move] += 1
    #
    #     result = results_in_a_winner(copy_board, copy_board_columns_used, token, other_token)
    #     print(f'sure result: {result}')
    #
    #     if result == token:
    #         print('MOVE: Sure WIN')
    #         return move
    #     elif result == other_token:
    #         losing_locations.add(move)

    # Look for opening opportunities
    for move in preferred_locations:
        move_score = {}
        if move in skip_moves or move in losing_locations or board_columns_used[move] == 0:
            continue

        score = move_opens_opportunities(board, move, board_columns_used[move], token)
        if score > 0:
            move_score[move] = score

        if move_score:
            sorted_score = sorted(move_score.items(), key=itemgetter(1))
            print('MOVE: making opportunities')
            return sorted_score[0][0]

    # Look for blocking opening opportunities
    for move in available_moves:
        move_score = {}
        if move in losing_locations:
            continue

        score = move_opens_opportunities(board, move, board_columns_used[move], other_token)
        if score > 0:
            move_score[move] = score

        if move_score:
            sorted_score = sorted(move_score.items(), key=itemgetter(1))
            print('MOVE: blocking enemy opportunities')
            return sorted_score[0][0]

    sorted_friendly_neighbours_score = None
    friendly_neighbours_score = {}

    for move in preferred_locations:
        if move in skip_moves or move in losing_locations or board_columns_used[move] == 0 or board_columns_used[move] == 0:
            continue
        friendly_neighbours = get_friendly_neighbours(board, move, board_columns_used[move], token)
        if friendly_neighbours > 1:
            friendly_neighbours_score[move] = friendly_neighbours

    if friendly_neighbours_score:
        sorted_friendly_neighbours_score = sorted(friendly_neighbours_score.items(), key=itemgetter(1))
        if sorted_friendly_neighbours_score[0][1] >= 3:
            print('MOVE: good friendlies')
            return sorted_friendly_neighbours_score[0][0]

    for move in preferred_locations:
        if move in skip_moves or move in losing_locations or board_columns_used[move] == 0 or board_columns_used[move] > 3:
            continue
        if not can_make_4_horizontal(board, move, board_columns_used[move], token):
            continue
        if move > 0:
            if board[move - 1][board_columns_used[move]] == token:
                print('MOVE: pair left')
                return move
        if move < 6:
            if board[move + 1][board_columns_used[move]] == token:
                print('MOVE: pair right')
                return move

    if sorted_friendly_neighbours_score:
        print('MOVE: weak neighbours')
        return sorted_friendly_neighbours_score[0][0]

    print(get_opcode_count())

    for move in priority_locations:
        if move not in available_moves or move in losing_locations or move in skip_moves:
            continue
        return move

    for move in preferred_locations:
        if move not in available_moves or move in losing_locations or move in skip_moves:
            continue
        return move

    for move in priority_locations:
        if move not in available_moves or move in losing_locations:
            continue
        return move

    for move in preferred_locations:
        if move not in available_moves or move in losing_locations:
            continue
        return move

    return random.choice(available_moves)
Exemple #8
0
def get_next_move(board, token):
    available_moves = game.available_moves(board)
    available_positions = list(
        zip(available_moves, available_rows(available_moves, board)))

    other_token = define_other_token(token)

    #TODO pre-calculate those as part of the setup()
    available_lines_of_4 = [
        line for line in game.LINES_OF_4
        if not set(available_positions).isdisjoint(line)
    ]
    outcome = dict()

    smallest_tokens_missing = 5

    for line_of_4 in available_lines_of_4:
        token_missing = get_nb_token_missing(board, line_of_4)

        if smallest_tokens_missing > token_missing:
            outcome = defaultdict(
                list)  #was int in tournament but allows better debugging
            smallest_tokens_missing = token_missing
        if token_missing == smallest_tokens_missing and smallest_tokens_missing < 5:
            the_moves = list(set(line_of_4) & set(available_positions))
            for move in the_moves:
                outcome[move[0]].append(list)

    #Format changed for Clarity
    proposals = [
        Proposal(col=i, row=board[i].index('.'), nb=len(j))
        for i, j in outcome.items()
    ]

    if smallest_tokens_missing > 1:
        #TODO include in initial loop to avoid going over game.LINES_OF_4 again?
        traps = get_traps(board, game.LINES_OF_4, smallest_tokens_missing)
    else:
        traps = list()

    if "DEBUG" in os.environ:
        print(f"==>From Athanase 'No Traps' playing {token}")
        print(
            f"===>I had {len(available_moves)} available moves {available_moves}"
        )
        print(
            f"===>Those were part of  {len(available_lines_of_4)} lines of 4:")
        print(f"====>{available_lines_of_4}")
        print(
            f"===>I have select {len(proposals)} of then that have {smallest_tokens_missing} missing:"
        )
        print(f"====>{proposals}")
        print(f"===>There were also {len(traps)} traps:")
        print(f"====>{traps}")

    try:
        proposals_not_traps = [
            prop for prop in proposals
            if not any((prop.col, prop.row + 1) in trap for trap in traps)
        ]

        outputs = [
            e.col for e in proposals_not_traps if cut_fn(e) == max(
                cut_fn(x) for x in proposals_not_traps)
        ]
        if "DEBUG" in os.environ:
            print(
                f"===>I had {len(proposals_not_traps)} proposals after filtering the traps out:"
            )
            print(f"====>{proposals_not_traps}")
            print(f"===>And those are the potential moves to select from:")
            print(f"====>{outputs}")

        outputs = outputs or [
            avail[0] for avail in available_play if not any(
                (avail, avail[1] + 1) in trap for trap in traps)
        ]
        if "DEBUG" in os.environ:
            print(
                f"===>If the previous selection was empty, I filter out traps from available moves:"
            )
            print(f"====>{outputs}")
        outputs = outputs or available_moves
        if "DEBUG" in os.environ:
            print(
                f"===>If the previous selection was empty, I just select from available moves:"
            )
            print(f"====>{outputs}")
        output = random.choice(outputs)
    except:
        output = random.choice(available_moves)
        if "DEBUG" in os.environ:
            print(f"===>Exception occured, select from available moves:")
            print(f"====>{outputs}")

    return output
def get_next_move(board, token):
    available_moves = game.available_moves(board)
    available_position = [(a, board[a].index('.')) for a in available_moves]
    available_play = available_position

    if token == 'X':
        other_token = 'O'
    else:
        other_token = 'X'

    possible = [
        line for line in game.LINES_OF_4
        if not set(available_position).isdisjoint(line)
    ]

    outcome = dict()

    best = 5

    for line in possible:
        remaining, letter = remaining_to_win(board, line, token)
        if remaining == 5:
            continue

        if best > remaining:
            outcome = defaultdict(list)
            outcome_assign = defaultdict()
            best = remaining

        if best == remaining:
            the_moves = list(set(line) & set(available_play))
            for move in the_moves:
                outcome[move[0]].append(list)
                if letter == token:
                    outcome_assign[move[0]] = letter

    #tuple number of line_4, row, cols
    proposals = [(i, board[i].index('.'), 9, 0, 0, len(j))
                 for i, j in outcome.items()]

    if best == 1:
        return select_for_victory(board, outcome_assign, proposals, token)

    traps = get_traps(board, game.LINES_OF_4, best, token)
    #Do not fall in a trap.
    proposals_minus_traps = [
        prop for prop in proposals
        if not any((prop[0], prop[1] + 1) in trap for trap in traps)
    ]
    friendly_traps = get_his_deadly_traps(board, game.LINES_OF_4, best,
                                          other_token)
    available_traps = set(pos for trap in friendly_traps for pos in trap
                          if get_letter_of_pos(pos, board) == ".")
    enemy_traps = get_his_deadly_traps(board, game.LINES_OF_4, best, token)
    available_enemy_traps = set(pos for trap in enemy_traps for pos in trap
                                if get_letter_of_pos(pos, board) == ".")

    print("outcome", outcome, outcome_assign, best)
    print("athanase => proposals ==>", proposals)
    print("athanase => traps ======>", traps)
    print("athanase => proposals_minus_traps =>", proposals_minus_traps)

    for move in available_moves:
        sequence_play = set([
            a[1] - board[a[0]].index('.') for a in available_traps
            if a[0] == move
        ])
        separation = len(set(a % 2 for a in sequence_play))
        no_enemy = True
        if len(
                set([
                    a[1] - board[a[0]].index('.')
                    for a in available_enemy_traps if a[0] == move
                ])):
            first_enemy = min(
                set([
                    a[1] - board[a[0]].index('.')
                    for a in available_enemy_traps if a[0] == move
                ]))
            print("+++++++++=+=>", min(sequence_play), first_enemy)
            print(enemy_traps)
            print("==============>", sequence_play)
            print(game.render_text(board))
            if min(sequence_play) == first_enemy:
                no_enemy = False
        if len(sequence_play) > 1 and separation == 2 and no_enemy:
            print("nailing it=======>", available_traps)
            print(enemy_traps)
            print("nailing it=======>", token, move)
            print("==============>", sequence_play)
            print(game.render_text(board))

            return move

    #We have a choice, let's see if we can set a trap
    if len(traps) > 1:
        board1 = copy.deepcopy(board)
        improved_proposals = list()
        only_him = set((row, col) for row, col in available_play if not any(
            (row, col + 1) in trap for trap in traps)) - set(
                (row, col) for row, col, _, _, _, _ in proposals)

        if len(enemy_traps) > 0 and len(friendly_traps) == 0:
            for col, row in only_him:
                board1[col][row] = other_token
                new_enemy_traps = get_his_deadly_traps(
                    board1, (enemy_traps + possible), best, token)
                all_new_traps = set(pos for trap in new_enemy_traps
                                    for pos in trap
                                    if get_letter_of_pos(pos, board1) == ".")
                new_traps = all_new_traps - available_enemy_traps
                if len(new_traps) > 0:
                    potential_traps = (
                        all_new_traps.union(available_enemy_traps))

                    sequence_play = [
                        a[1] - board[a[0]].index('.') for a in potential_traps
                    ]
                    if len(potential_traps) > 0:
                        next_one = min(sequence_play)
                    else:
                        next_one = 9
                    order = len(set(a % 2 for a in sequence_play))
                    improved_proposals.append(
                        (col, row, next_one, order, len(new_traps), 0))
                board1[col][row] = '.'

        for col, row, _, _, _, remaining in proposals_minus_traps:
            board1[col][row] = token
            new_friendly_traps = get_his_deadly_traps(board1,
                                                      (traps + possible), best,
                                                      other_token)
            all_new_traps = set(pos for trap in new_friendly_traps
                                for pos in trap
                                if get_letter_of_pos(pos, board1) == ".")
            new_traps = all_new_traps - available_traps
            potential_traps = (all_new_traps.union(available_traps))

            sequence_play = [
                a[1] - board[a[0]].index('.') for a in potential_traps
            ]
            if len(potential_traps) > 0:
                next_one = min(sequence_play)
            else:
                next_one = 9
            order = len(set(a % 2 for a in sequence_play))
            improved_proposals.append(
                (col, row, next_one, order, len(new_traps), remaining))
            board1[col][row] = '.'
        if len(improved_proposals):
            proposals_minus_traps = improved_proposals

    outputs = list()
    if len(proposals_minus_traps):
        outputs = [
            e[0] for e in proposals_minus_traps
            if e == max(proposals_minus_traps, key=cut_fn)
        ]
    if len(outputs) == 0:
        outputs = available_moves

    outputs = [
        move for move in outputs if not any(
            (move, board[move].index('.') + 1) in trap for trap in enemy_traps)
    ]
    print("athanase => outputs =>", outputs)
    try:
        output = random.choice(outputs)
    except:
        output = random.choice(available_moves)
    return output
Exemple #10
0
def get_next_move(board, token):
    board_columns_used = get_board_columns_used(board)
    available_moves = game.available_moves(board)
    preferred_locations = [3, 2, 4, 1, 5, 0, 6]
    preferred_locations = [
        x for x in preferred_locations if x in available_moves
    ]
    priority_locations = get_columns_with_space(board, token,
                                                preferred_locations)
    opcode_limit = get_opcode_limit()
    losing_locations = set()

    # if state is None:
    #     state = {'opening_trap': False}

    moves_played = get_moves_played(board)

    other_token = 'X' if token == 'O' else 'O'

    for move in available_moves:
        board[move][board_columns_used[move]] = token
        if check_winner(board, move, board_columns_used[move]):
            return move
        board[move][board_columns_used[move]] = '.'

    for move in available_moves:
        board[move][board_columns_used[move]] = other_token
        if check_winner(board, move, board_columns_used[move]):
            return move
        board[move][board_columns_used[move]] = '.'

    for move in available_moves:
        if board_columns_used[move] > 4:
            continue
        board[move][board_columns_used[move]] = token
        board[move][board_columns_used[move] + 1] = other_token

        if check_winner(board, move, board_columns_used[move] + 1):
            losing_locations.add(move)

        board[move][board_columns_used[move]] = '.'
        board[move][board_columns_used[move] + 1] = '.'

    # Opening book
    if moves_played == 1:
        if board[3][0] == other_token:
            losing_locations.add(3)

    if moves_played == 2:
        if board[3][1] == other_token:
            # state['opening_trap'] = True
            return 2
        if board[2][0] == other_token:
            return 2
        if board[4][0] == other_token:
            return 4

    if moves_played == 4:
        if board[3][1] == other_token and board[1][0] == '.' and board[4][
                0] == '.':
            return 4

    skip_moves = set()

    for move in available_moves:
        if board_columns_used[move] > 4:
            continue
        board[move][board_columns_used[move]] = token
        board[move][board_columns_used[move] + 1] = token

        if check_winner(board,
                        move,
                        board_columns_used[move] + 1,
                        ignore_vertical=True):
            skip_moves.add(move)

        board[move][board_columns_used[move]] = '.'
        board[move][board_columns_used[move] + 1] = '.'

    print(get_opcode_count())

    for move in preferred_locations:
        if move in skip_moves or move in losing_locations or board_columns_used[
                move] == 0 or board_columns_used[move] > 3:
            continue
        if move > 0:
            if board[move - 1][board_columns_used[move]] == token:
                return move
        if move < 6:
            if board[move + 1][board_columns_used[move]] == token:
                return move

    print(get_opcode_count())

    for move in priority_locations:
        if move not in available_moves or move in losing_locations or move in skip_moves:
            continue
        return move

    for move in preferred_locations:
        if move not in available_moves or move in losing_locations or move in skip_moves:
            continue
        return move

    for move in priority_locations:
        if move not in available_moves or move in losing_locations:
            continue
        return move

    for move in preferred_locations:
        if move not in available_moves or move in losing_locations:
            continue
        return move

    return random.choice(available_moves)
Exemple #11
0
def get_next_move(board, token):
    board_columns_used = get_board_columns_used(board)
    available_moves = game.available_moves(board)
    preferred_locations = [3, 2, 4, 1, 5, 0, 6]
    preferred_locations = [
        x for x in preferred_locations if x in available_moves
    ]
    priority_locations = get_columns_with_space(board, token,
                                                preferred_locations)
    opcode_limit = get_opcode_limit()
    losing_locations = set()
    skip_moves = set()

    # if state is None:
    #     state = {'opening_trap': False}

    moves_played = get_moves_played(board)

    other_token = 'X' if token == 'O' else 'O'

    for move in available_moves:
        board[move][board_columns_used[move]] = token
        if check_winner(board, move, board_columns_used[move]):
            return move
        board[move][board_columns_used[move]] = '.'

    for move in available_moves:
        board[move][board_columns_used[move]] = other_token
        if check_winner(board, move, board_columns_used[move]):
            return move
        board[move][board_columns_used[move]] = '.'

    for move in available_moves:
        if board_columns_used[move] > 4:
            continue
        board[move][board_columns_used[move]] = token
        board[move][board_columns_used[move] + 1] = other_token

        if check_winner(board, move, board_columns_used[move] + 1):
            losing_locations.add(move)

        board[move][board_columns_used[move]] = '.'
        board[move][board_columns_used[move] + 1] = '.'

    # Opening book
    if moves_played == 1:
        if board[3][0] == other_token:
            losing_locations.add(3)

    if moves_played == 2:
        if board[3][1] == other_token:
            # state['opening_trap'] = True
            return 2
        if board[2][0] == other_token:
            return 2
        if board[4][0] == other_token:
            return 4

    if moves_played == 4:
        if board[3][1] == other_token and board[1][0] == '.' and board[4][
                0] == '.':
            return 4

    # Take the move if you see a open-ended 3 way opportunity
    for move in available_moves:
        if move_makes_3_horizontal_with_spaces(board, move,
                                               board_columns_used[move],
                                               token):
            return move

    # Block 2 adjacent tokens for the enemy
    for move in available_moves:
        if move_makes_3_horizontal_with_spaces(board, move,
                                               board_columns_used[move],
                                               other_token):
            return move

    for move in available_moves:
        if board_columns_used[move] > 4:
            continue
        board[move][board_columns_used[move]] = token
        board[move][board_columns_used[move] + 1] = token

        if check_winner(board,
                        move,
                        board_columns_used[move] + 1,
                        ignore_vertical=True):
            skip_moves.add(move)

        board[move][board_columns_used[move]] = '.'
        board[move][board_columns_used[move] + 1] = '.'

    print(get_opcode_count())

    for move in preferred_locations:
        if move in skip_moves or move in losing_locations or board_columns_used[
                move] == 0 or board_columns_used[move] > 3:
            continue
        if not can_make_4_horizontal(board, move, board_columns_used[move],
                                     token):
            continue
        if move > 0:
            if board[move - 1][board_columns_used[move]] == token:
                return move
        if move < 6:
            if board[move + 1][board_columns_used[move]] == token:
                return move

    for move in preferred_locations:
        move_score = {}
        if move in skip_moves or move in losing_locations or board_columns_used[
                move] == 0 or board_columns_used[move]:
            continue
        friendly_neighbours = get_friendly_neighbours(board, move,
                                                      board_columns_used[move],
                                                      token)
        if friendly_neighbours > 1:
            move_score[move] = friendly_neighbours
        if move_score:
            sorted_score = sorted(move_score.items(), key=itemgetter(1))
            return sorted_score[0][0]

    print(get_opcode_count())

    for move in priority_locations:
        if move not in available_moves or move in losing_locations or move in skip_moves:
            continue
        return move

    for move in preferred_locations:
        if move not in available_moves or move in losing_locations or move in skip_moves:
            continue
        return move

    for move in priority_locations:
        if move not in available_moves or move in losing_locations:
            continue
        return move

    for move in preferred_locations:
        if move not in available_moves or move in losing_locations:
            continue
        return move

    return random.choice(available_moves)
Exemple #12
0
def get_next_move(board, token):

    test_board = test_make_board_from_string()

    print(f'Before check_winner:{get_opcode_count()}')
    game.check_winner(test_board)
    print(f'After check_winner:{get_opcode_count()}')

    board_columns_used = get_board_columns_used(board)

    print(f'Before available moves:{get_opcode_count()}')
    all_available_moves = game.available_moves(board)
    print(f'After available moves:{get_opcode_count()}')

    preferred_locations = [3, 2, 4, 1, 5, 0, 6]

    print(f'Before preferred locations:{get_opcode_count()}')
    priority_locations = get_columns_with_space(board, token, preferred_locations)
    print(f'After preferred locations:{get_opcode_count()}')

    losing_locations = set()
    # if state is None:
    #     state = {'opening_trap': False}

    print(f'Before board walk: {get_opcode_count()}')
    board[3][board_columns_used[3]] = token
    board[3][board_columns_used[3]] = '.'
    print(f'After board walk: {get_opcode_count()}')


    new_board = game.new_board()
    new_board[0][0] = 'X'
    new_board[1][1] = 'X'
    new_board[2][2] = 'X'
    new_board[3][3] = 'X'

    print(f'Before game.check_winner:{get_opcode_count()}')
    game.check_winner(new_board)
    print(f'After game.check_winner:{get_opcode_count()}')

    print(f'Before check_winner:{get_opcode_count()}')
    check_winner(board, 3, 3)
    print(f'After check_winner:{get_opcode_count()}')

    rO = re.compile(r'OOOO|O.{6}O.{6}O.{6}O|O.{7}O.{7}O.{7}O|O.{8}O.{8}O.{8}O')
    rX = re.compile(r'XXXX|X.{6}X.{6}X.{6}X|X.{7}X.{7}X.{7}X|X.{8}X.{8}X.{8}X')
    board_string = make_string_from_board(board)
    print(f'Before check_winner_regex:{get_opcode_count()}')
    board_string = board_string[:2 * 7 + 2] + 'X' + board_string[2 * 7 + 2:]
    check_winner_regex(board_string, 'X', r=rX)
    print(f'After check_winner_regex:{get_opcode_count()}')

    moves_played = get_moves_played(board)

    # best_value = float('-inf')
    # best_move = random.choice(available_moves)

    other_token = 'X' if token == 'O' else 'O'

    for move in all_available_moves:
        board[move][board_columns_used[move]] = token
        if check_winner(board, move, board_columns_used[move]):
            return move
        board[move][board_columns_used[move]] = '.'

    print(get_opcode_count())

    for move in all_available_moves:
        board[move][board_columns_used[move]] = other_token
        if check_winner(board, move, board_columns_used[move]):
            return move
        board[move][board_columns_used[move]] = '.'

    print(get_opcode_count())

    available_moves = set(all_available_moves)

    for move in all_available_moves:
        if board_columns_used[move] > 4:
            continue
        board[move][board_columns_used[move]] = token
        board[move][board_columns_used[move] + 1] = other_token

        if check_winner(board, move, board_columns_used[move] + 1):
            losing_locations.add(move)

        board[move][board_columns_used[move]] = '.'
        board[move][board_columns_used[move] + 1] = '.'

    print(get_opcode_count())

    skip_moves = set()

    for move in all_available_moves:
        if board_columns_used[move] > 4:
            continue
        board[move][board_columns_used[move]] = token
        board[move][board_columns_used[move] + 1] = token

        if check_winner(board, move, board_columns_used[move] + 1, ignore_vertical=True):
            skip_moves.add(move)

        board[move][board_columns_used[move]] = '.'
        board[move][board_columns_used[move] + 1] = '.'

    # for move in all_available_moves:
    #     board[move][board_columns_used[move]] = token
    #     if move_makes_opportunity(board, move, board_columns_used[move], token):
    #         return move


    print(get_opcode_count())

    if moves_played == 1:
        # Don't go on top of the previous player
        losing_locations.add(find_enemy_location(board, other_token))

    if moves_played == 2:
        if board[3][1] == other_token:
            return 2

    if moves_played == 4:
        if board[3][1] == other_token and board[1][0] == '.' and board[4][0] == '.':
            return 4

    priority_locations = [x for x in priority_locations if x not in skip_moves]

    for move in priority_locations:
        if move in losing_locations:
            continue
        return move

    for move in preferred_locations:
        if move in losing_locations:
            continue
        return move

    return random.choice(all_available_moves)
Exemple #13
0
def get_next_move(board, token, state):
    board_columns_used = get_board_columns_used(board)
    available_moves = game.available_moves(board)
    preferred_locations = [3, 2, 4, 1, 5, 0, 6]
    priority_locations = get_columns_with_space(board, token, preferred_locations)
    losing_locations = set()

    if state is None:
        state = {'opening_trap': False}

    moves_played = get_moves_played(board)

    other_token = 'X' if token == 'O' else 'O'

    for move in available_moves:
        board[move][board_columns_used[move]] = token
        if check_winner(board, move, board_columns_used[move]):
            return move, state
        board[move][board_columns_used[move]] = '.'

    for move in available_moves:
        board[move][board_columns_used[move]] = other_token
        if check_winner(board, move, board_columns_used[move]):
            return move, state
        board[move][board_columns_used[move]] = '.'

    for move in available_moves:
        if board_columns_used[move] > 4:
            continue
        board[move][board_columns_used[move]] = token
        board[move][board_columns_used[move] + 1] = other_token

        if check_winner(board, move, board_columns_used[move] + 1):
            losing_locations.add(move)

        board[move][board_columns_used[move]] = '.'
        board[move][board_columns_used[move] + 1] = '.'

    skip_moves = set()

    for move in available_moves:
        if board_columns_used[move] > 4:
            continue
        board[move][board_columns_used[move]] = token
        board[move][board_columns_used[move] + 1] = token

        if check_winner(board, move, board_columns_used[move] + 1, ignore_vertical=True):
            skip_moves.add(move)

        board[move][board_columns_used[move]] = '.'
        board[move][board_columns_used[move] + 1] = '.'

    print(get_opcode_count())

    if moves_played == 1:
        # Don't go on top of the previous player
        losing_locations.add(find_enemy_location(board, other_token))

    if moves_played == 2:
        if board[3][1] == other_token:
            state['opening_trap'] = True
            return 2, state

    if moves_played == 4:
        if state['opening_trap']:
            if board[1][0] == '.' and board[4][0] == '.':
                return 4, state

    for move in priority_locations:
        if move not in available_moves or move in losing_locations or move in skip_moves:
            continue
        return move, state

    for move in preferred_locations:
        if move not in available_moves or move in losing_locations or move in skip_moves:
            continue
        return move, state

    for move in priority_locations:
        if move not in available_moves or move in losing_locations:
            continue
        return move, state

    for move in preferred_locations:
        if move not in available_moves or move in losing_locations:
            continue
        return move, state

    return random.choice(available_moves), state
Exemple #14
0
def get_next_move(board, token):
    return random.choice(game.available_moves(board))