Esempio n. 1
0
def minimax_max_node(board, color):
    """
    Return the minimum score the MAX player can achieve 
    with any move starting at board. 
    """
    if not get_possible_moves(board, color):
        return compute_utility(board, color)

    alpha = -math.inf
    for i, j in get_possible_moves(board, color):
        new_board = play_move(board, color, i, j)
        utility = minimax_min_node(new_board, color)
        if utility > alpha:
            alpha = utility
    return alpha
def alphabeta_max_node(board, color, alpha, beta, limit, caching = 0, ordering = 0):
    if caching == 1:
        if board_mapping.get(board) != None:
            return None, board_mapping.get(board)

    myself = color
    return_move = tuple()
    
    possible_moves = get_possible_moves(board, myself)
    if len(possible_moves) == 0 or limit == 0:
        return None, compute_utility(board, myself)

    if ordering == 1:
        unsorted_score = {}
        sorted_score = {}
        for m in possible_moves:
            new_board = play_move(board, myself, m[0], m[1])
            unsorted_score.update({m:compute_utility(new_board, myself)})
        sorted_score = sorted(unsorted_score.items(), key=lambda i:i[1], reverse=True)
        possible_moves.clear()
        for i in sorted_score:
            possible_moves.append(i[0])

    old_score = float('-inf')
    for move in possible_moves:   
        new_board = play_move(board, myself, move[0], move[1])
        if(alpha < beta):
            score = alphabeta_min_node(new_board, myself, alpha, beta, limit-1, caching, ordering)
            if score[1] > old_score:
                old_score = score[1]
                alpha = old_score
                return_move = move

    if caching == 1:
        board_mapping.update({board : old_score})
    return return_move, old_score
Esempio n. 3
0
def alphabeta_max_node(board, color, beta, level, limit):
    if not get_possible_moves(board, color):
        return compute_utility(board, color)

    alpha = -math.inf
    for i, j in get_possible_moves(board, color):
        new_board = play_move(board, color, i, j)
        if level + 1 > limit:
            continue
        utility = alphabeta_min_node(new_board, color, alpha, level + 1, limit)
        if utility > alpha:
            alpha = utility
        if alpha > beta:
            return alpha
    return alpha
Esempio n. 4
0
def minmax_mode(maxi, board, color, limit, caching):
    use_heuristics = False  # default FALSE

    # CHECK CACHE
    if (caching and (board, color, maxi) in cache):
        return cache[board, color, maxi]

    test_color = color if maxi else next_color(color)

    # DEPTH LIMIT REACHED
    if limit == 0:
        if use_heuristics:
            return None, compute_heuristic(board, color)
        else:
            return None, compute_utility(board, color)

    moves = get_possible_moves(board, test_color)

    # TERMINAL STATE
    if len(moves) == 0:
        move_tup = (None, compute_utility(board, color))

        if (caching):
            cache[board, color, maxi] = move_tup

        return move_tup

    move_tups = []

    for move in moves:
        next_board = play_move(board, test_color, move[0], move[1])
        if maxi:
            move_util = minimax_min_node(next_board, color, limit - 1,
                                         caching)[1]
        else:
            move_util = minimax_max_node(next_board, color, limit - 1,
                                         caching)[1]
        move_tups.append((move, move_util))

    if maxi:
        goal_tup = max(move_tups, key=lambda t: t[1])
    else:
        goal_tup = min(move_tups, key=lambda t: t[1])

    if (caching):
        cache[board, color, maxi] = goal_tup

    return goal_tup
Esempio n. 5
0
def minimax_max_node(board,
                     color,
                     limit,
                     caching=0):  #returns highest possible utility

    # Determine the player color
    if color == 1:
        oppo_color = 2
    else:
        oppo_color = 1

    # the valid moved
    valid_moves = get_possible_moves(board, color)

    if (len(valid_moves) == 0):
        # no move valid and board is not cached
        return None, compute_utility(board, color)

    elif (limit == 0):
        return None, compute_utility(board, color)

    else:
        u_value_best = -1 * len(board) * len(
            board)  # set at max possible value
        move_best = None

        for move in valid_moves:
            new_board = play_move(board, color, move[0], move[1])

            # check if the new board is in the cache
            if new_board in cached and caching:
                new_move, u_value = cached[new_board]

            else:
                new_move, u_value = minimax_max_node(new_board, color,
                                                     limit - 1, caching)

                if (caching):
                    cached[new_board] = (new_move, u_value)

            # get the min value:
            if (u_value > u_value_best):
                u_value_best = u_value
                move_best = move

        return (move_best, u_value_best)

    return ((0, 0), 0)
Esempio n. 6
0
def alphabeta_max_node(board, color, alpha, beta, depth, maxdepth):
    if depth > maxdepth or len(get_possible_moves(board, color)) <= 0:
        if hash(board) not in seen_boards:
            seen_boards.add(hash(board))
            seen_boards_cost[hash(board)] = compute_utility(board, color)

        return seen_boards_cost[hash(board)]
    else:

        nowAlpha = alpha
        bestVal = -3000000000

        bestCheck = []

        for x in get_possible_moves(board, color):
            playedBoard = play_move(board, color, x[0], x[1])
            if playedBoard not in seen_boards_heuristic:
                seen_boards_heuristic.add(playedBoard)
                seen_boards_heuristic_cost[playedBoard] = get_heuristic(
                    playedBoard, color)
            #toCheck = alphabeta_max_node(playedBoard, color, switch_color(currentColor), alpha, nowBeta, depth + 1, maxdepth )
            bestCheck.append(
                (seen_boards_heuristic_cost[playedBoard], playedBoard))

        bestCheck.sort()
        bestCheck.reverse()

        for x, playedBoard in bestCheck:
            #playedBoard = play_move(board, currentColor, x[0], x[1])
            #toCheck = alphabeta_min_node(playedBoard, color, switch_color(currentColor), nowAlpha, beta, depth + 1, maxdepth )

            toCheck = 0
            if playedBoard not in seen_boards_min:
                seen_boards_min.add(playedBoard)
                seen_boards_min_cost[playedBoard] = alphabeta_min_node(
                    playedBoard, color, nowAlpha, beta, depth + 1, maxdepth)

            toCheck = seen_boards_min_cost[playedBoard]
            toCheck += random.randint(-volatile_level, volatile_level)
            if toCheck > bestVal:
                bestVal = toCheck
            if bestVal > nowAlpha:
                nowAlpha = bestVal
            if nowAlpha >= beta:
                break

        #return max(childrenNodes)
        return bestVal
Esempio n. 7
0
def minimax_min_node(board, color):
    #function MIN-VALUE(state) returns a utility value
    #if TERMINAL-TEST(state) then return UTILITY(state) v←∞
    #for each a in ACTIONS(state) do
    #v ← MIN(v, MAX-VALUE(RESULT(s, a))) return v
    moves = get_possible_moves(board, color)
    move = min(moves)
    #(col,row) tuples representing legal moves for player color
    results = play_move(board, color, move)
    #computes successor board state that results from player color playing move (a(col,row)tuple)
    if color.status == "FINAL":
        return color.compute_utility(board, color)
    v = inf
    for (a, s) in color.results(board):
        v = min(v, minimax_max_node(board, color))
    return v
Esempio n. 8
0
def select_move_alphabeta(board, color):
    moves = get_possible_moves(board, color)
    max_score = float("-inf")
    best_move = [0, 0]
    alpha = float("-inf")
    beta = float("inf")
    for move in moves:
        new_board = play_move(board, color, move[0], move[1])
        score = alphabeta_min_node(new_board, color, alpha, beta, 1, limit)
        if score > max_score:
            max_score = score
            best_move[0] = move[0]
            best_move[1] = move[1]
        alpha = max(alpha, max_score)

    return best_move[0], best_move[1]
def select_move_alphabeta(board, color): 
  
  max_utility = float("-inf")
  best_move = None

  for move in get_possible_moves(board, color):
    i,j = move
    new_board = play_move(board, color, i,j)
    utility = alphabeta_min_node(new_board, color, 0, float("-inf"), float("inf"), 24)
    # select the move that gives the highest utility
      
    if utility > max_utility:
      max_utility = utility
      best_move = (i, j)

  return best_move
Esempio n. 10
0
def minimax_max_node(board, color):
    if board in move_dictionary:
        return move_dictionary[board]
    else:
        max_next_nodes = get_possible_moves(board, color)
        utility_list = []
        if (len(max_next_nodes) == 0):
            return compute_utility(board, color)

        for items in max_next_nodes:
            successor_board = play_move(board, color, items[0], items[1])
            curr_utility = minimax_min_node(successor_board, color)
            utility_list.append(curr_utility)

        move_dictionary.update({board: min(utility_list)})
        return max(utility_list)
Esempio n. 11
0
def ordered_moves(board, moves, color, current_player):
    '''This is for ordering possible moves'''
    dic = dict()
    result = []
    for move in moves:
        (column, row) = move
        new_board = play_move(board, current_player, column, row)
        successor_utility = compute_utility(new_board, color)
        if successor_utility in dic and dic[successor_utility] != [move]:
            dic[successor_utility].append(move)
        else:
            dic[successor_utility] = [move]
    ordered_utility = sorted(list(dic.keys()), reverse=True)
    for utility in ordered_utility:
        result += dic[utility]
    return result
Esempio n. 12
0
def minimax_min_node(board, color):
    anti_color = 3 - color
    moves = get_possible_moves(board, anti_color)
    if not moves:
        return compute_utility(board, color)
    mini_score = float("inf")

    for move in moves:
        new_board = play_move(board, anti_color, move[0], move[1])

        score = minimax_max_node(new_board, color)

        if score < mini_score:
            mini_score = score

    return mini_score
Esempio n. 13
0
def minimax_min_node(board, color, depth, end_time):
    possible_moves = get_possible_moves(board, color)
    current_time = datetime.now()
    if possible_moves == [] or depth == 0 or current_time >= end_time:
        score = get_score_weighted(board)  # get_score(board)
        return score[color%2] - score[(color+1)%2]
    else:
        next_color = color % 2 + 1
        best_min_score = 1000000
        for move in possible_moves:
            new_board = play_move(board, color, move[0], move[1])
            move_score = minimax_max_node(new_board, next_color, depth - 1, end_time)
            if move_score < best_min_score:
                best_min_score = move_score
        return best_min_score
    return None
Esempio n. 14
0
def select_move_alphabeta(board, color):
    moves = get_possible_moves(board, color)

    best_move = None
    alpha = -math.inf
    for move in moves:
        if move == (0, 0) or move == (0, 7) or move == (7, 0) or move == (7,
                                                                          7):
            return move
        i, j = move
        new_board = play_move(board, color, i, j)
        score = alphabeta_min_node(new_board, color, alpha, 0, 4)
        if score > alpha:
            best_move = move
            alpha = score
        return best_move
Esempio n. 15
0
def alphabeta_min_node(board, color, alpha, beta, limit, caching = 0, ordering = 0):

    if caching:
        global cache
        if board in cache.keys():
            return cache[(board,color)]

    opponent_col = None
    if color == 1:
        opponent_col = 2
    else:
        opponent_col = 1

    list_of_moves = get_possible_moves(board, opponent_col)
    if list_of_moves == [] or limit == 0:
        return (None, compute_utility(board,color))

    children = []
    for move in list_of_moves:
        children.append(play_move(board, opponent_col, move[0], move[1]))

    if ordering:
        utilities = []
        for c in children:
            utilities.append(compute_utility(c, color))
        zipped = list(zip(utilities, children, list_of_moves))
        zipped.sort(key = lambda x: x[0])
        children = []
        list_of_moves = []
        for x, y, z in zipped:
            children.append(y)
            list_of_moves.append(z)

    ut_val = float("inf")
    values = []
    for c in children:
        ut_val = min(ut_val, alphabeta_max_node(c,color, alpha, beta, limit-1)[1])
        values.append(ut_val)
        beta = min(beta, ut_val)
        if beta <= alpha:
            return (None, ut_val)

    move = list_of_moves[values.index(ut_val)]

    if caching:
        cache[(board,color)] = (move, ut_val)
    return (move, ut_val)
Esempio n. 16
0
def alphabeta_max_node(board,
                       color,
                       alpha,
                       beta,
                       limit,
                       caching=0,
                       ordering=0):

    moves = get_possible_moves(board, color)
    if moves == [] or limit == 0:
        return (-1, -1), compute_utility(board, color)

    max_utility = -float('inf')
    successors = []

    for i in range(len(moves)):
        temp_board = play_move(board, color, moves[i][0], moves[i][1])
        successors.append((temp_board, compute_utility(temp_board, color)))

    if ordering == 1:
        successors.sort(key=takeSecond, reverse=True)

    for i in range(len(successors)):

        if caching == 1:
            if successors[i][0] in cached:
                temp_utility = cached[successors[i][0]]
            else:
                temp_move, temp_utility = alphabeta_min_node(
                    successors[i][0], color, alpha, beta, limit - 1, caching,
                    ordering)
                cached[successors[i][0]] = temp_utility
        else:
            temp_move, temp_utility = alphabeta_min_node(
                successors[i][0], color, alpha, beta, limit - 1, caching,
                ordering)

        if temp_utility > max_utility:
            max_utility = temp_utility
            max_move = moves[i]

        if alpha < max_utility:
            alpha = max_utility
            if beta <= alpha:
                break

    return max_move, max_utility
Esempio n. 17
0
def alphabeta_max_node(board,
                       color,
                       alpha,
                       beta,
                       limit,
                       caching=0,
                       ordering=0):
    #IMPLEMENT (and replace the line below)
    # Check cache
    if caching and (board, color) in cache:
        return cache[(board, color)]

    best_move = None
    max_utility = float('-inf')
    possible_moves = get_possible_moves(board, color)

    # Check if limit reached or end of game
    if limit == 0 or len(possible_moves) == 0:
        return None, compute_utility(board, color)

    # Order (move, board) tuples according to the utility successor states
    move_and_board = []
    for move in possible_moves:
        nxt_board = play_move(board, color, move[0], move[1])
        move_and_board.append((move, nxt_board))
    if ordering:
        move_and_board.sort(key=lambda move_and_board: compute_utility(
            move_and_board[1], color),
                            reverse=True)

    for (move, nxt_board) in move_and_board:
        # Compute next utility
        _, nxt_utility = alphabeta_min_node(nxt_board, color, alpha, beta,
                                            limit - 1, caching, ordering)
        if max_utility < nxt_utility:
            best_move = move
            max_utility = nxt_utility
        # Prune
        alpha = max(alpha, max_utility)
        if alpha >= beta:
            break

    # Cache the board
    if caching:
        cache[(board, color)] = (best_move, max_utility)

    return best_move, max_utility
Esempio n. 18
0
def minimax_min_node(board, color):

    if color == 2:
        opp_color = 1
    elif color == 1:
        opp_color = 2

    if not get_possible_moves(board, opp_color):
        return compute_utility(board, color)

    beta = math.inf
    for i, j in get_possible_moves(board, opp_color):
        new_board = play_move(board, opp_color, i, j)
        utility = minimax_max_node(new_board, color)
        if utility < beta:
            beta = utility
    return beta
Esempio n. 19
0
def minimax_max_node(board, color):
    possibleMoves = get_possible_moves(board, color)

    if not possibleMoves:
        return compute_utility(board, color)

    bestMove = None
    bestScore = -math.inf

    for y in possibleMoves:
        newBoard = play_move(board, color, y[0], y[1])
        score = minimax_min_node(newBoard, oppColor)
        if score > bestScore:
            bestMove = move
            bestScore = score

    return bestScore
def minimax_max_node(board, color):
    if board in minimax_cache.keys():
        return minimax_cache[board]
    opponent_color = 0
    if color == 1:
        opponent_color = 2
    else:
        opponent_color = 1
    possible_moves = get_possible_moves(board, color)
    if not possible_moves:
        return compute_utility(board, color)
    v = float("-inf")
    for move in possible_moves:
        new_board = play_move(board, color, move[0], move[1])
        v = max(v, minimax_min_node(new_board, opponent_color))
        minimax_cache[new_board] = v
    return v
Esempio n. 21
0
def select_move_minimax(board, color):
    """
  Given a board and a player color, decide on a move. 
  The return value is a tuple of integers (i,j), where
  i is the column and j is the row on the board.  
  """

    moves = get_possible_moves(board, color)
    bestMoveScore = -math.inf
    bestMove = (1, 1)
    for i in moves:
        newBoard = play_move(board, color, i[0], i[1])
        score = minimax_min_node(newBoard, color)
        if score > bestMoveScore:
            bestMoveScore = score
            bestMove = i
    return bestMove
Esempio n. 22
0
def select_move_minimax(board, color):
    """
    Given a board and a player color, decide on a move.
    The return value is a tuple of integers (i,j), where
    i is the column and j is the row on the board.
    """
    best_value = 0

    for (i, j) in get_possible_moves(board, color):
        next_board = play_move(board, color, i, j)
        value = minimax_min_node(next_board, color)

        if value > best_value:
            best_value = value
            x = i
            y = j
    return x, y
Esempio n. 23
0
def move_mobility_heuristic(board,color):
    '''
    A secondary heuristic to maximize the number of plays the AI can do. Intended to synergize with sweet 16.
    '''
    if color == 1:
        opposing_color = 2
    else:
        opposing_color = 1

    opposing_possible_moves = 0
    moves = get_possible_moves(board,color)
    for (column,row) in moves:
        new_board = play_move(board,color,column,row)
        if len(get_possible_moves(new_board,opposing_color)) > opposing_possible_moves:
            opposing_possible_moves = len(get_possible_moves(new_board,opposing_color))
    #sys.stderr.write('Move mobility: {}\n'.format(len(moves) - opposing_possible_moves))
    return len(moves) - opposing_possible_moves + random.randint(0,9)
Esempio n. 24
0
def select_move_alphabeta(board, color):
    dic = {}
    if color == 1:
        opponent_color = 2
    else:
        opponent_color = 1
    v = -inf

    #v = alphabeta_max_node(board, color, -inf, inf)
    for successor in get_possible_moves(board, color):
        new_board = play_move(board, color, successor[0], successor[1])
        v = max(v,
                alphabeta_min_node(new_board, opponent_color, -inf, inf, 1, 5))
        if v not in dic:
            dic.update({v: successor})

    return dic[v]
Esempio n. 25
0
def minimax_max_node(board, color, limit, caching = 0): #returns highest possible utility
    #IMPLEMENT (and replace the line belowS
    global cache 
    if color==1: other_color=2
    else: other_color=1
    limit-=1
    if caching==1:
        if board in cache:
            return cache[board]
    #iniitlazing a very low value for the node
    best_node = float("-Inf")
    #checking if we are at the end leaf
    if not get_possible_moves(board,color) or limit==0:
        return compute_utility(board,color)
    for move in get_possible_moves(board,color):
        best_node= max(best_node,minimax_min_node(play_move(board,color,move[0],move[1]),opponent,lim))
    return best_node
Esempio n. 26
0
def alphabeta_max_node(board, color, beta, level, limit):
    level += 1
    if level >= limit:
        return heuristic_evaluation(board, color)
    opp_color = 1 if color == 2 else 2
    moves = get_possible_moves(board, color)
    if not moves:
        return compute_utility(board, color)
    alpha = -math.inf
    for x in moves:
        one, two = x
        testBoard = play_move(board, color, one, two)
        minNode = alphabeta_min_node(testBoard, opp_color, alpha, level, limit)
        if minNode >= beta:
            return minNode
            alpha = max(alpha, minNode)
    return alpha
Esempio n. 27
0
def minimax_min_node(board, color, depth, temp_max_depth=max_depth):
    if depth >= max_depth:
        return compute_utility(board, color)
    moves = get_possible_moves(board, color)
    move_utility = {}

    if len(moves) != 0:
        for (column, row) in moves:
            new_board = play_move(board, color, column, row)
            #sys.stderr.write(str(new_board) + '\n')
            if not new_board in move_utility.values():
                utility = minimax_max_node(new_board, color, depth + 1)
                move_utility[utility] = new_board
            else:
                return compute_utility(new_board, color)
        return min(move_utility.keys())
    return compute_utility(board, color)
Esempio n. 28
0
def minimax_min_node(board, color, limit, caching=0):

    # Determine the player color
    if color == 1:
        oppo_color = 2
    else:
        oppo_color = 1

    # the valid moved
    valid_moves = get_possible_moves(board, oppo_color)

    if (len(valid_moves) == 0):
        # no move valid and board is not cached
        return None, compute_utility(board, color)

    elif (limit == 0):
        # reach search limit
        return None, compute_utility(board, color)

    else:
        u_value_best = float("Inf")  # inf as looking for small number
        move_best = None

        for move in valid_moves:
            new_board = play_move(board, oppo_color, move[0], move[1])

            # check if the new board is in the cache
            if new_board in cached and caching:
                new_move, u_value = cached[new_board]

            else:
                new_move, u_value = minimax_max_node(new_board, color,
                                                     limit - 1, caching)

                if (caching):
                    cached[new_board] = (new_move, u_value)

            # get the min value:
            if (u_value < u_value_best):
                u_value_best = u_value
                move_best = move

        return (move_best, u_value_best)

    return ((0, 0), 0)
Esempio n. 29
0
def minimax_min_node(board, color):

    # Get the color of the next player
    if color == 1:
        other_color = 2
    else:
        other_color = 1

    # Get the allowed moves
    all_moves = get_possible_moves(board, other_color)

    # If there are no moves left, return the utility
    if len(all_moves) == 0:
        return None, compute_utility(board, color)

    # Else if there are moves, get their utility and return the min
    else:
        # Get the maximum utility possible to use as a starting point for min
        min_utility = len(board) * len(board)
        min_move = None

        # For each possible move, get the max utiltiy
        for each in all_moves:

            # Get the next board from that move
            next_board = play_move(board, other_color, each[0], each[1])

            # First check the cache for the board
            if next_board in board_utilities:
                move, new_utiltiy = board_utilities[next_board]

            else:
                # If the new utility is less than the current min, update min_utiltiy
                move, new_utiltiy = minimax_max_node(next_board, color)
                board_utilities[next_board] = (move, new_utiltiy)

            if new_utiltiy < min_utility:
                min_utility = new_utiltiy
                min_move = each

        # After checking every move, return the minimum utility
        return min_move, min_utility

    # Default return - should never be called
    return None, None
Esempio n. 30
0
def select_move_alphabeta(board, color):

    best_utility = -math.inf
    beta = math.inf
    best_move = 0, 0
    new_color = 1 if color == 2 else 2
    # caching_states = get_cached_states(color)
    possible_moves = get_possible_moves(board, color)
    level = 0
    limit = 5
    if len(possible_moves) > 0:
        sorted_states_list = []
        for move in possible_moves:
            new_board = play_move(board, color, move[0], move[1])
            sort_utility = compute_utility(new_board, new_color)
            heappush(sorted_states_list, (sort_utility, new_board, move))

        sorted_states = [x[1] for x in sorted_states_list]
        moves = [x[2] for x in sorted_states_list]
        index = 0
        for board_state in sorted_states:
            if board_state in caching_states:
                utility = caching_states[board_state]
            else:
                utility = alphabeta_min_node(board_state, new_color,
                                             best_utility, beta, level + 1,
                                             limit)
                caching_states[board_state] = utility
            if utility > best_utility:
                best_utility = utility
                best_move = moves[index]
            index += 1
        """
        for move in possible_moves:
            new_board = play_move(board, color, move[0], move[1])
            if new_board in caching_states:
                utility = caching_states[new_board]
            else:
                utility = alphabeta_min_node(new_board, new_color, best_utility, beta, level + 1, limit)
                caching_states[new_board] = utility
            if utility > best_utility:
                best_utility = utility
                best_move = move
        """
    return best_move