2012-05-17 86 views
-2

在这些日子里,我一直在努力与minimax算法,我可以说我终于明白了(感谢另一篇文章在stackoverflow)。因此,我打开了我的编辑器,并试图将其实现为一个非常简单(不要责怪我的代码请:P)tic tac脚趾,只是为了尝试一下。一切正常,但电脑移动功能总是检索我-1。我不是要求你给我代码,只是“为什么”这样做。我已经搜遍了很多遍代码,但什么也没找到。该代码可能非常类似于我在网上找到的另一个代码。这里是我的代码:人类与机器井字游戏

# COMPUTER AI 

def computer_move(): 
    best_move = minimax_recurse(game_board,active_player, 0) 
    print "The best move is ", best_move 
    make_move(game_board,best_move, active_player) 


    print "COMPUTER MOVE DONE" 


def minimax_recurse(game_board,player,depth): 

    winner = is_winner(game_board) 
    if winner == active_player : 
     return 1 
    elif winner is not active_player : 
     return -1 
    elif len(get_move_list(game_board)) == 0 : 
     return 0 

    if player == player1 : 
     other_player = player2 
    other_player = player1 

    if player == active_player : 
     alpha = -1 
    alpha = 1 

    movelist = get_move_list(game_board) 

    for move in movelist : 
     board2 = game_board 

     make_move(board2,move,player) 

     subalpha = minimax_recurse(board2, other_player, depth + 1) 

     if player == active_player : 
      if depth == 0 and alpha <= subalpha: 
       best_move = move 

      alpha = max(alpha,subalpha) 
      return alpha 

     else : 
      alpha = min(alpha,subalpha) 
      return alpha 



# BOARD FUNCTIONS 
game_board = ([1,2,3],[4,5,6],[7,8,9]) 
def print_board(board) : 

    for row in board : 
     print row 

def make_move(game_board,player_move,active_player): 

    x = 0 
    y = 0 
    player_move = int(player_move) 
    if player_move == 1 : 
     x = 0 
     y = 0 
    elif player_move == 2 : 
     x = 0 
     y = 1 
    elif player_move == 3 : 
     x = 0 
     y = 2 
    elif player_move == 4 : 
     x = 1 
     y = 0 
    elif player_move == 5 : 
     x = 1 
     y = 1 
    elif player_move == 6 : 
     x = 1 
     y = 2 
    elif player_move == 7 : 
     x = 2 
     y = 0 
    elif player_move == 8 : 
     x = 2 
     y = 1 
    elif player_move == 9 : 
     x = 2 
     y = 2 
    elif player_move >= 10 : 
     print "value is too high" 
     skip = False 
     return board 

    if game_board[x][y] == "O" or game_board[x][y] == "X" : 
     print "move not avaiable" 
     return game_board 

    game_board[x][y] = active_player 
    return game_board 

def is_winner(board): 
    for i in range (0,3) : 
     if board[i][0] == player1 and board[i][1] == player1 and board[i][2] == player1 : 
      return player1 

     if board[i][0] == player2 and board[i][1] == player2 and board[i][2] == player2 : 
      return player2 

    # checking for obliqual, that's quite bad and slow check but it works 
    if board[0][0] == player1 and board[1][1] == player1 and board[2][2] == player1 : 
     return player1 
    if board[0][0] == player2 and board[1][1] == player2 and board[2][2] == player2 : 
     return player2 

    if board[2][0] == player1 and board[1][1] == player1 and board[0][2] == player1 : 
     return player1 
    if board[2][0] == player2 and board[1][1] == player2 and board[0][2] == player2 : 
     return player2 

    return None 


def get_move_list (game_board) : 

    move = [0] 

    for row in game_board : 
     for i in row : 
      if isinstance(i,int) == True : 
       move.append(i) 
    move.remove(0) 
    return move 



# Main Loop 
player1 = "X" 
player2 = "O" 
print_board(game_board) 
while True : 
    active_player = player1 
    # this is for player move 
    print get_move_list(game_board) 
    player_move = int(raw_input("Please insert your move >>> ")) 
    make_move(game_board,player_move,active_player) 
    print_board(game_board) 

    if is_winner(game_board) == player1 : 
     print "Player1 is the winner" 
     break 
    if is_winner(game_board) == player2 : 
     print "Player2 is the winner" 
     break 
    print get_move_list(game_board) 
    # computer time 
    active_player = player2 
    computer_move() 
    print_board(game_board) 

    if is_winner(game_board) == player1 : 
     print "Player1 is the winner" 
     break 
    if is_winner(game_board) == player2 : 
     print "Player2 is the winner" 
     break 

回答

2

无需调试所有的代码,一两件事看上去是错的是你使用“best_move”变量(全局未初始化)为-1/0既是对此举持有人以及持有人/ + 1 minimax_recurse的结果。所以它被你的minmax算法覆盖。你需要更多的变量,更清晰的初始化和一致的用法。

+0

这是真的,但算法仍然返回-1作为结果,我仍然不知道为什么... –

1

-1总是返回的根本原因是当winnerNonewinner is not active_player返回True。你可以使用一个变量来保留其他(非活动)播放器的曲目,或者您可以使用三元运算:elif winner is (player1 if player2 == active_player else player2)

虽然这不是唯一的问题:

if player == active_player :  
    alpha = -1  
alpha = 1 

这将始终设置阿尔法1直接在上面的线条有相同的问题。在另一个答案中指出的变量命名问题也是如此。

+0

哦是啊..我完全忘了两个检查...我用三元运算符,但它是给我一个非常奇怪的输出,你在你的机器上试过了吗?无论如何,我在考虑算法,它总是输出1或0或-1,它不会输出best_move,任何想法? –

+0

当你设置board2 = game_board然后修改board2时,你总是覆盖板子。这导致了很多问题。如果三元运算符不工作(也许你使用的是旧版本的Python),你可以尝试修正'other_player'的定义,并将其放在胜利检查之上。然后你可以使用'elif winner == other_player:' – CheeseWarlock