递归函数正在改变它不应该的变量

时间:2015-01-06 03:31:49

标签: python recursion

我试图为tic tac toe实现一个机器人,它搜索每个可能的可用移动并执行它,然后再次搜索每个可能的移动,直到游戏结束,然后为赢得的游戏得分+1,-1对于一场失利的比赛,0平局。

该板是一个二维阵列 示例:[[0,0,0],[0,0,0],[0,0,0]]

对于玩家X,

1 -1为玩家O

僵尸程序由以下代码运行

get_best_move(board, toMove)

def get_best_move(board, bot_id):


    # Will evaluate each base move
    # For instance if there is currently 2 moves, will return a score for each move
    moves = get_list_moves(board)

    for key, values in moves.iteritems():
        total_score = 0
        dummy_board = board
        xy = moves[key]
        x = xy[0]
        y = xy[1]

        dummy_board[x][y] = bot_id
        if(check_winner(dummy_board)):
            # Someone Won
            winner = get_winner(dummy_board)
            if(winner == bot_id):
                total_score += 1
            elif(winner == 0):
                total_score += 0
            else:
                total_score -= 1
        else:
            print board # note 1
            total_score += get_best_move_not_main(board, bot_id*-1, bot_id)
            print board # note 2
        print "Key: " + str(key) + " - move: " + str(xy) + " score: " + str(total_score) + "end"

def get_best_move_not_main(board, whosMove, bot_id):
    # Will evaluate each base move
    # For instance if there is currently 2 moves, will return a score for each move
    moves = get_list_moves(board)
    total_score = 0

    for key, values in moves.iteritems():

        dummy_board = board
        xy = moves[key]
        x = xy[0]
        y = xy[1]

        dummy_board[x][y] = whosMove

        if(check_winner(dummy_board)):
            # Someone Won
            winner = get_winner(dummy_board)
            if(winner == bot_id):
                total_score += 1
            elif(winner == 0):
                total_score += 0
            else:
                total_score -= 1
        else:
            total_score += get_best_move_not_main(board, whosMove*-1, bot_id)

    return total_score

第一种方法get_best_move,将获得我们可以进行的所有当前动作,并且一旦探索了所有选项,将为每次移动输出分数

我的问题是在第一次迭代后第一次移动示例 - 0,0(在左上角移动)。董事会将永久改变

因此,例如当我在(get_best_move)中进行递归之前打印板(注释1)时,它显示[[-1,0,0],[0,0,0],[0,0,0] ]但是在递归之后(注2)。董事会现在被改变为一个完全全面的董事会。

我不确定我的get_best_move中的board数组是如何从单独的函数(get_best_move_not_main)中更改的。

github链接:https://github.com/konk353535/tictactoe

谢谢:)'

感谢所有答案,真的很有帮助!

2 个答案:

答案 0 :(得分:2)

正如@Barmar指出的那样,dummy_board = board不会复制电路板,它只是指相同的电路板。

我认为你想要的是:

 import copy
 dummy_board=copy.deepcopy(board)

任何分配都是如此;代码如:

a=1
b=a

b指的是完全相同的1作为a中的一个。您不会注意到数字,因为数字本身无法更改。你不能改变任何关于1的东西,它只是1.如果你改变a或b,你就会摆脱现有的价值,并在其中放置一个新值。

答案 1 :(得分:0)

dummy_board = board使dummy_board引用board完全相同的对象:通过一个名称进行的每项更改也会反映在另一个名称中。即使是简单的copy也不足以构建嵌套列表:您需要副本。即,

import copy
...
dummy_board = copy.deepcopy(board)