Checkers算法:如何减少嵌套for循环

时间:2016-05-04 16:52:09

标签: python recursion nested-loops chess

我正在尝试构建一个播放草稿/跳棋的程序。目前我正在尝试制作这个功能,它允许计算机制作和评估动作。我的想法是让计算机看看它自己可能的所有移动,并且对于每个移动,看看可能的对手移动,然后对于每个移动,再次看看它自己可能的移动。

对于每一层,它将评估移动对于玩家的好坏,并分配点,最后它选择具有最高点的移动。

到目前为止,我已设法获得此版本的工作,但涉及许多嵌套for循环。代码是一团糟,目前不太可读,但这是一个相同概念的简单模型。新的列表只是乘以2而不是评估和生成更多列表。

counter = 0
    for x in list:
        counter += 1
        list_2 = [x * 2 for x in list]
        print 'list_2', list_2, counter
        for x in list_2:
            counter += 1
            list_3 = [x * 2 for x in list_2]
            print 'list_3',list_3, counter
            for x in list_3:
                counter += 1
                list_4 = [x * 2 for x in list_3]
                print 'list_4', list_4, counter

如果我运行此代码,我得到了我想要的东西,除了我不能轻易地控制搜索的深度而不需要复制更多for循环。我认为递归可能是这样做的一种方式,但我无法弄清楚如何在x级搜索深度之后停止递归。

是否有更好的方法从上面的代码中获取相同的输出,同时摆脱所有的for循环?如果我可以让它工作,我想我自己可以做其余的事。

2 个答案:

答案 0 :(得分:1)

  

我认为递归可能是一种方法,但我无法弄清楚如何在x级搜索深度后停止递归。

你的直觉是正确的,一个简单的方法是将一个递增的数字传递给每个级别。当递归获得最大值时,递归就完成了。下面是一个简单的例子来证明。

def countup(i=0):
  print(i)
  if i==MAX_COUNT: return
  countup(i+1)

对于您的算法,您需要一个值来表示电路板评估。例如,在[-1,1]范围内。如果评估为-1,则可以说玩家A获胜,如果评估为1,则玩家B获胜。递归算法可以如下。

def evaulate(board, player, depth=0):
  if depth==MAX_DEPTH: return hueristicEvaluation(board)
  bestMove = None
  if player==PLAYER_A:
    val=999 # some large value
    for move in get_moves():
      newboard = board.makeMove(move)
      eval, _ = evaluate(newboard, PLAYER_B, depth+1)
      if eval < val:
        bestMove = move
        val = eval
  elif player==PLAYER_B:
    val=-999 # some large negative value
    for move in get_moves():
      newboard = board.makeMove(move)
      eval, _ = evaluate(newboard, PLAYER_A, depth+1)
      if eval > val:
        bestMove = move
        val = eval
  return val, bestMove

这是抽象的,但这个想法就在那里。根据您代表boardplayer的方式进行调整。函数hueristicEvaluation可以简单到为每个玩家计算棋盘上的棋子以及它们与另一侧的距离。请记住,此函数需要在[-1,1]

之间返回一个数字

要考虑的边缘情况,我没有考虑到这一点:

  • 如果所有动作都获胜和/或失败
  • 如果NO在该位置移动,例如,如果你的棋子被对手的棋子全部挡住了

像这样的简单搜索存在许多改进。如果您有兴趣,请阅读:)

答案 1 :(得分:1)

这是一个使用递归的等效函数。它使用跟踪当前深度和最大深度的两个参数来控制递归。如果当前深度超过最大深度,它将立即返回,从而停止递归:

def evaluate(l, max_depth, cur_depth=0, counter=0):
    if cur_depth > max_depth:
        return counter

    for x in l:
        counter += 1
        l2 = [x * 2 for x in l]
        print cur_depth, l2, counter
        counter = evaluate(l2, max_depth, cur_depth + 1, counter)

    return counter

如果使用max_depth=2调用它将产生相同的输出,除了代替变量名称,打印当前深度。