Robert Howlett :: smart11.py (v1)

This bot has played 1000 games (389 wins / 116 draws / 495 losses).

Play against this bot as X or as O.

These bots have done best aganist smart11.py...

Bot P W D L Points Size From beginner One hit wonder Goldfish
Robert Seaman : : not_minimax.py (v25) 10 10 0 0 10 3501 False False True
Séverin Hatt : : romuald_no_last_check.py (v1) 10 10 0 0 10 1598 False False True
Jon Bannister : : anybot_r282.py (v5) 10 5 5 0 5 974 False False True
Ian Ozsvald : : ian12.py 10 5 5 0 5 943 False False True
Jordan Banting : : trololololol.py (v1) 10 5 5 0 5 402 False False True

...and these bots have done worst

Bot P W D L Points Size From beginner One hit wonder Goldfish
Joe Jordan : : jbot2.py (v4) 10 0 0 10 -10 719 False False False
Ronan Murphy : : loser.py 10 0 0 10 -10 105 False False True
Luke Spademan : : lossingbot.py (v3) 10 0 0 10 -10 129 False False True
house : : opportunist.py 10 0 0 10 -10 None None None None
Peter Inglesby : : random.py 10 0 0 10 -10 26 False True True

All standings against smart11.py

The code

      
# This bot looks one move ahead, and if possible it will make a move to
# block its opponent winning.  Otherwise, it picks a move at random.

from botany_connectfour import game


def board_copy(board):
    """
    Faster implementation of deepcopy for board
    :param board:
    :return:
    """
    return [row[:] for row in board]


def get_next_move(board, token):
    if token == 'X':
        other_token = 'O'
    else:
        other_token = 'X'

    available_moves = game.available_moves(board)
    ok_moves = []

    for col in available_moves:
        board1 = board_copy(board)
        game.make_move(board1, col, token)
        if game.check_winner(board1):
            # Winning move
            return col
        # Check if opponent can seize win
        try:
            game.make_move(board1, col, other_token)
        except AssertionError:
            pass
        if not game.check_winner(board1):
            # Maybe safe
            ok_moves.append(col)

    for col in ok_moves:
        board2 = board_copy(board)
        game.make_move(board2, col, other_token)
        if game.check_winner(board2):
            # forced move, as it blocks their win
            return col
    # Try to only give an ok move
    if ok_moves:
        return ok_moves[len(ok_moves) // 2]
    # just pick one
    return available_moves[len(available_moves) // 2]