【问题标题】:Minimax algorithm returns tupleMinimax 算法返回元组
【发布时间】:2022-01-14 15:22:07
【问题描述】:

我试图为国际象棋创建一个极小极大算法,但它不起作用。它现在在第 118 行给出元组实例和浮点数之间不支持'NoneTypes。有人知道解决这个问题的方法吗?

import chess
from numpy import Infinity
import numpy as np
import random

board = chess.Board()

def random_board(max_depth=200): 
    board = chess.Board()
    depth = random.randrange(0, max_depth)

    for _ in range(depth):
        all_moves = list(board.legal_moves)
        random_move = random.choice(all_moves)
        board.push(random_move)
        if board.is_game_over():
            break

    return board

board = random_board()

pawn_square_value = np.array([0, 0, 0, 0, 0, 0, 0, 0, 5, 10, 10, -20, -20, 10, 10, 5, 5, -5, -10, 0, 0, -10, -5, 5, 0, 0, 0, 20, 20, 0, 0, 0, 5, 5, 10, 25, 25, 10, 5, 5, 10, 10, 20, 30, 30, 20, 10, 10, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0])

knight_square_value = np.array([-50,-40,-30,-30,-30,-30,-40,-50, -40,-20,  0,  5,  5,  0, -20, -40, -30,  5, 10, 15, 15, 10,  5, -30, -30,  0, 15, 20, 20, 15,  0,-30, -30,  5, 15, 20, 20, 15,  5,-30, -30,  0, 10, 15, 15, 10,  0,-30, -40,-20,  0,  0,  0,  0,-20,-40, -50,-40,-30,-30,-30,-30,-40,-50])

bishop_square_value = np.array([-20,-10,-10,-10,-10,-10,-10,-20, -10,  5,  0,  0,  0,  0,  5,-10,-10, 10, 10, 10, 10, 10, 10,-10, -10,  0, 10, 10, 10, 10,  0,-10, -10,  5,  5, 10, 10,  5,  5,-10,-10,  0,  5, 10, 10,  5,  0,-10, -10,  0,  0,  0,  0,  0,  0,-10, -20,-10,-10,-10,-10,-10,-10,-20])

rook_square_value = np.array([0,  0,  0,  5,  5,  0,  0,  0, -5,  0,  0,  0,  0,  0,  0, -5, -5,  0,  0,  0,  0,  0,  0, -5, -5,  0,  0,  0,  0,  0,  0, -5, -5,  0,  0,  0,  0,  0,  0, -5, -5,  0,  0,  0,  0,  0,  0, -5,  5, 10, 10, 10, 10, 10, 10,  5, 0,  0,  0,  0,  0,  0,  0,  0])

queen_square_value = np.array([-20,-10,-10, -5, -5,-10,-10,-20, -10,  0,  5,  0,  0,  0,  0,-10,-10,  5,  5,  5,  5,  5,  0,-10, -10,  5,  5,  5,  5,  5,  0,-10, -5,  0,  5,  5,  5,  5,  0, -5, -10,  0,  5,  5,  5,  5,  0,-10, -10,  0,  0,  0,  0,  0,  0,-10, -20,-10,-10, -5, -5,-10,-10,-20,])

king_square_value = np.array([20, 30, 10,  0,  0, 10, 30, 20, 20, 20,  0,  0,  0,  0, 20, 20, -10,-20,-20,-20,-20,-20,-20,-10, -20,-30,-30,-40,-40,-30,-30,-20, -30,-40,-40,-50,-50,-40,-40,-30, -30,-40,-40,-50,-50,-40,-40,-30, -30,-40,-40,-50,-50,-40,-40,-30, -30,-40,-40,-50,-50,-40,-40,-30])

def init_evaluation():
    wp = len(board.pieces(chess.PAWN, chess.WHITE))
    bp = len(board.pieces(chess.PAWN, chess.BLACK))
    wn = len(board.pieces(chess.KNIGHT, chess.WHITE))
    bn = len(board.pieces(chess.KNIGHT, chess.BLACK))
    wb = len(board.pieces(chess.BISHOP, chess.WHITE))
    bb = len(board.pieces(chess.BISHOP, chess.BLACK))
    wr = len(board.pieces(chess.ROOK, chess.WHITE))
    br = len(board.pieces(chess.ROOK, chess.BLACK))
    wq = len(board.pieces(chess.QUEEN, chess.WHITE))
    bq = len(board.pieces(chess.QUEEN, chess.BLACK))

    material = 100 *(wp-bp) + 320 * (wn-bn) + 330 * (wb-bb) + 500 * (wr-br) + 900 * (wq - bq)

    pawnsq = sum([pawn_square_value[i] for i in board.pieces(chess.PAWN, chess.WHITE)])
    pawnsq = pawnsq + sum([-pawn_square_value[chess.square_mirror(i)] 
                                    for i in board.pieces(chess.PAWN, chess.BLACK)])

    knightsq = sum([knight_square_value[i] for i in board.pieces(chess.KNIGHT, chess.WHITE)])
    knightsq = knightsq + sum([-knight_square_value[chess.square_mirror(i)] 
                                    for i in board.pieces(chess.KNIGHT, chess.BLACK)])

    bishopsq= sum([bishop_square_value[i] for i in board.pieces(chess.BISHOP, chess.WHITE)])
    bishopsq= bishopsq + sum([-bishop_square_value[chess.square_mirror(i)] 
                                    for i in board.pieces(chess.BISHOP, chess.BLACK)])

    rooksq = sum([rook_square_value[i] for i in board.pieces(chess.ROOK, chess.WHITE)]) 
    rooksq = rooksq + sum([-rook_square_value[chess.square_mirror(i)] 
                                    for i in board.pieces(chess.ROOK, chess.BLACK)])

    queensq = sum([queen_square_value[i] for i in board.pieces(chess.QUEEN, chess.WHITE)]) 
    queensq = queensq + sum([-queen_square_value[chess.square_mirror(i)] 
                                    for i in board.pieces(chess.QUEEN, chess.BLACK)])

    kingsq = sum([king_square_value[i] for i in board.pieces(chess.KING, chess.WHITE)]) 
    kingsq = kingsq + sum([-king_square_value[chess.square_mirror(i)]   
                                    for i in board.pieces(chess.KING, chess.BLACK)])
    
    boardvalue = material + pawnsq + knightsq + bishopsq + rooksq + queensq + kingsq

    return boardvalue

def evaluate_board():

    if board.is_checkmate() == True:
        if board.turn:
            return -9999
        else: 
            return 9999 
    
    elif board.is_stalemate() == True:
        return 0
    elif board.is_insufficient_material() == True:
        return 0 
    else: 
        return init_evaluation()


print(evaluate_board())
print(board)

board.legal_moves



#Een minimax met alpha-beta pruning: 
def minimax(bord, max_depth, depth, alpha, beta):
    if depth == max_depth or board.is_checkmate() == True: 
        return evaluate_board(), None

    best_move = None
    if board.turn == chess.WHITE:
        best_score = -Infinity
    else: 
        best_score = Infinity
    for move in board.legal_moves:
        newBoard = board.copy()
        newBoard.push(move)
        current_score = minimax(newBoard, max_depth, depth+1, alpha, beta)

        if board.turn == chess.WHITE:
            if current_score > best_score:
                best_score = current_score
                best_move = move

        else: 
            if current_score < best_score:
                best_score = current_score
                best_move = move

    return best_score, best_move  



def get_best_move():
    move = minimax(board, 3, 0, -Infinity, Infinity)
    return move

print(get_best_move())

【问题讨论】:

  • minimax 返回一个包含 2 个东西的元组。但是在current_score = minimax(...) 你只期待一个。如果您不需要第二个,请执行current_score, _ = minimax(...)
  • 我们在 StackOverflow 上看不到行号。当然,您可以创建一个不包含太多代码的minimal reproducible example
  • 您的极小值返回两个值,您将这两个值保存为当前分数。因此你得到一个元组。正如@TimRoberts 所说,您实际上需要将它们保存为两个单独的变量,以使用逗号分隔符来防止这种情况发生,或者在比较时只需访问current_score[0]

标签: python chess minimax


【解决方案1】:

您的 minimax 函数也返回 best_move。

如果您不需要,只需将其从退货中删除即可。

如果您以后需要使用它,只需像这样为另一个返回的变量赋值:

import chess
from numpy import Infinity
import numpy as np
import random

board = chess.Board()

def random_board(max_depth=200): 
    board = chess.Board()
    depth = random.randrange(0, max_depth)

    for _ in range(depth):
        all_moves = list(board.legal_moves)
        random_move = random.choice(all_moves)
        board.push(random_move)
        if board.is_game_over():
            break

    return board

board = random_board()

pawn_square_value = np.array([0, 0, 0, 0, 0, 0, 0, 0, 5, 10, 10, -20, -20, 10, 10, 5, 5, -5, -10, 0, 0, -10, -5, 5, 0, 0, 0, 20, 20, 0, 0, 0, 5, 5, 10, 25, 25, 10, 5, 5, 10, 10, 20, 30, 30, 20, 10, 10, 50, 50, 50, 50, 50, 50, 50, 50, 0, 0, 0, 0, 0, 0, 0, 0])

knight_square_value = np.array([-50,-40,-30,-30,-30,-30,-40,-50, -40,-20,  0,  5,  5,  0, -20, -40, -30,  5, 10, 15, 15, 10,  5, -30, -30,  0, 15, 20, 20, 15,  0,-30, -30,  5, 15, 20, 20, 15,  5,-30, -30,  0, 10, 15, 15, 10,  0,-30, -40,-20,  0,  0,  0,  0,-20,-40, -50,-40,-30,-30,-30,-30,-40,-50])

bishop_square_value = np.array([-20,-10,-10,-10,-10,-10,-10,-20, -10,  5,  0,  0,  0,  0,  5,-10,-10, 10, 10, 10, 10, 10, 10,-10, -10,  0, 10, 10, 10, 10,  0,-10, -10,  5,  5, 10, 10,  5,  5,-10,-10,  0,  5, 10, 10,  5,  0,-10, -10,  0,  0,  0,  0,  0,  0,-10, -20,-10,-10,-10,-10,-10,-10,-20])

rook_square_value = np.array([0,  0,  0,  5,  5,  0,  0,  0, -5,  0,  0,  0,  0,  0,  0, -5, -5,  0,  0,  0,  0,  0,  0, -5, -5,  0,  0,  0,  0,  0,  0, -5, -5,  0,  0,  0,  0,  0,  0, -5, -5,  0,  0,  0,  0,  0,  0, -5,  5, 10, 10, 10, 10, 10, 10,  5, 0,  0,  0,  0,  0,  0,  0,  0])

queen_square_value = np.array([-20,-10,-10, -5, -5,-10,-10,-20, -10,  0,  5,  0,  0,  0,  0,-10,-10,  5,  5,  5,  5,  5,  0,-10, -10,  5,  5,  5,  5,  5,  0,-10, -5,  0,  5,  5,  5,  5,  0, -5, -10,  0,  5,  5,  5,  5,  0,-10, -10,  0,  0,  0,  0,  0,  0,-10, -20,-10,-10, -5, -5,-10,-10,-20,])

king_square_value = np.array([20, 30, 10,  0,  0, 10, 30, 20, 20, 20,  0,  0,  0,  0, 20, 20, -10,-20,-20,-20,-20,-20,-20,-10, -20,-30,-30,-40,-40,-30,-30,-20, -30,-40,-40,-50,-50,-40,-40,-30, -30,-40,-40,-50,-50,-40,-40,-30, -30,-40,-40,-50,-50,-40,-40,-30, -30,-40,-40,-50,-50,-40,-40,-30])

def init_evaluation():
    wp = len(board.pieces(chess.PAWN, chess.WHITE))
    bp = len(board.pieces(chess.PAWN, chess.BLACK))
    wn = len(board.pieces(chess.KNIGHT, chess.WHITE))
    bn = len(board.pieces(chess.KNIGHT, chess.BLACK))
    wb = len(board.pieces(chess.BISHOP, chess.WHITE))
    bb = len(board.pieces(chess.BISHOP, chess.BLACK))
    wr = len(board.pieces(chess.ROOK, chess.WHITE))
    br = len(board.pieces(chess.ROOK, chess.BLACK))
    wq = len(board.pieces(chess.QUEEN, chess.WHITE))
    bq = len(board.pieces(chess.QUEEN, chess.BLACK))

    material = 100 *(wp-bp) + 320 * (wn-bn) + 330 * (wb-bb) + 500 * (wr-br) + 900 * (wq - bq)

    pawnsq = sum([pawn_square_value[i] for i in board.pieces(chess.PAWN, chess.WHITE)])
    pawnsq = pawnsq + sum([-pawn_square_value[chess.square_mirror(i)] 
                                    for i in board.pieces(chess.PAWN, chess.BLACK)])

    knightsq = sum([knight_square_value[i] for i in board.pieces(chess.KNIGHT, chess.WHITE)])
    knightsq = knightsq + sum([-knight_square_value[chess.square_mirror(i)] 
                                    for i in board.pieces(chess.KNIGHT, chess.BLACK)])

    bishopsq= sum([bishop_square_value[i] for i in board.pieces(chess.BISHOP, chess.WHITE)])
    bishopsq= bishopsq + sum([-bishop_square_value[chess.square_mirror(i)] 
                                    for i in board.pieces(chess.BISHOP, chess.BLACK)])

    rooksq = sum([rook_square_value[i] for i in board.pieces(chess.ROOK, chess.WHITE)]) 
    rooksq = rooksq + sum([-rook_square_value[chess.square_mirror(i)] 
                                    for i in board.pieces(chess.ROOK, chess.BLACK)])

    queensq = sum([queen_square_value[i] for i in board.pieces(chess.QUEEN, chess.WHITE)]) 
    queensq = queensq + sum([-queen_square_value[chess.square_mirror(i)] 
                                    for i in board.pieces(chess.QUEEN, chess.BLACK)])

    kingsq = sum([king_square_value[i] for i in board.pieces(chess.KING, chess.WHITE)]) 
    kingsq = kingsq + sum([-king_square_value[chess.square_mirror(i)]   
                                    for i in board.pieces(chess.KING, chess.BLACK)])
    
    boardvalue = material + pawnsq + knightsq + bishopsq + rooksq + queensq + kingsq

    return boardvalue

def evaluate_board():

    if board.is_checkmate() == True:
        if board.turn:
            return -9999
        else: 
            return 9999 
    
    elif board.is_stalemate() == True:
        return 0
    elif board.is_insufficient_material() == True:
        return 0 
    else: 
        return init_evaluation()


print(evaluate_board())
print(board)

board.legal_moves



#Een minimax met alpha-beta pruning: 
def minimax(bord, max_depth, depth, alpha, beta):
    if depth == max_depth or board.is_checkmate() == True: 
        return evaluate_board(), None

    best_move = None
    if board.turn == chess.WHITE:
        best_score = -Infinity
    else: 
        best_score = Infinity
    for move in board.legal_moves:
        newBoard = board.copy()
        newBoard.push(move)
        current_score, current_move = minimax(newBoard, max_depth, depth+1, alpha, beta)

        if board.turn == chess.WHITE:
            if current_score > best_score:
                best_score = current_score
                best_move = move

        else: 
            if current_score < best_score:
                best_score = current_score
                best_move = move

    return best_score, best_move  



def get_best_move():
    move = minimax(board, 3, 0, -Infinity, Infinity)
    return move

print(get_best_move())

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多