示例#1
0
    def test_get_oplimit_count(self):
        self.assertIsNone(tracer.get_opcode_limit())

        with tracer.limited_opcodes(100):
            self.assertEqual(tracer.get_opcode_limit(), 100)

        self.assertIsNone(tracer.get_opcode_limit())
示例#2
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)
示例#3
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)
示例#4
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)