【问题标题】:Recursive function is altering a variable that it shouldn't be递归函数正在更改不应该更改的变量
【发布时间】:2015-01-06 03:31:49
【问题描述】:

我正在尝试为井字游戏实现一个机器人,它会搜索所有可能的动作并执行它,然后再次搜索所有可能的动作,直到游戏结束,然后它得分 +1 赢得比赛,-1输一场,平局为0。

棋盘是一个二维数组 示例:[[0,0,0],[0,0,0],[0,0,0]]

1 代表玩家 X -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 内部的板数组是如何从单独的函数 (get_best_move_not_main) 中改变的。

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

谢谢你:)'

谢谢大家的回答,真的很有帮助!

【问题讨论】:

  • dummy_board = board 不会复制该板。两个变量都指向同一个板。
  • 复制使用这个:dummy_board = copy.deepcopy(board)
  • 哦,这真的很奇怪,我认为 dummy_board 会创建一个设置为 board 的新变量,并且我可以独立于 board 操纵 dummy :( 我如何让 dummy_board 与 board 分开?谢谢
  • 感谢马尔辛的帮助

标签: python recursion


【解决方案1】:

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

我想你想要的是:

 import copy
 dummy_board=copy.deepcopy(board)

这对于任何分配都是一样的;对于像这样的代码:

a=1
b=a

b 指的是与 a 中的 1 完全相同的 1。对于数字,您不会注意到这一点,因为数字本身无法更改。您无法更改 1 的任何内容,它只是 1。如果您更改 a 或 b,您将摆脱现有值,并在其位置上放置一个新值。

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-10
      • 1970-01-01
      • 2020-10-02
      • 2016-11-03
      相关资源
      最近更新 更多