简体   繁体   English

递归函数,用于连接Python中的四个可能的动作生成

[英]Recursive function for connect four possible moves generation in Python

I am programming a connect four AI for my school project. 我正在为我的学校项目编写一个连接四个AI的程序。 But first I want to simulate every possible moves on the 6(row)*7(column) before I write the minimax algorithm to work the perfect move for each stage of board. 但是首先,我想模拟6(row)* 7(column)上的所有可能移动,然后再编写minimax算法以使电路板的每个阶段都达到最佳移动。 Instead of using 而不是使用

for a in range(7):
   place_player_disk()
   complete_set.append
   if check_win():
      continue
   for b in legal_move():
       place_AI_disk()
       complete_set.append
       if check_win()
          continue
       .... #repeat the nested for loop 42 times

I want to use a neater way of doing it 我想用更整齐的方式做

state0=[['','','','','','',''],['','','','','','',''],['','','','','','',''],['','','','','','',''],['','','','','','',''],['','','','','','',''],['','','','','','','']]
complete_set=[[],[],[],[],[],[]...]
import copy
def playerplacetoken(perimeter,location):
      count=0
      for row in range(6):
          if perimeter[row][location]=='X' or perimeter[row][location]=='Y':
              count+=1
      perimeter[5-count][location]='X'
def full(perimeter):
    free = []
    for column in range(7):
    if perimeter[0][column] == '':
            free.append(column)
    return free
def PlacingCPUToken(perimeter,location):
    count=0
    for row in range (6):
      if perimeter[row][location]=='X' or perimeter[row][location]=='Y':
              count+=1
    perimeter[5-count][location]='Y'
def CheckP(perimeter):
    changerow=[0,1,1]
    changecolumn=[1,0,1]
    Pwin=False
        for col in range(7):
          for row in range (6):
            for change in range (3):
                try:
                    consecutivecount=0
                    for nochange in range(4):
                        if perimeter[row+(changerow[change]*(nochange))]     [col+(changecolumn[change]*(nochange))]=='X':
                            consecutivecount+=1
                        if consecutivecount==4:
                            Pwin=True
                except:
                    continue
    return Pwin
def CheckC(perimeter):
    changerow=[0,1,1]
    changecolumn=[1,0,1]
    Cwin=False
    for col in range(7):
        for row in range (6):
            for change in range (3):
                try:
                    consecutivecount=0
                    for nochange in range(4):
                        if perimeter[row+(changerow[change]*(nochange))][col+(changecolumn[change]*(nochange))]=='Y':
                            consecutivecount+=1
                        if consecutivecount==4:
                            Cwin=True
                except:
                    continue
    return Cwin
def recursive(state,move): #state: the state of board, first starts with an empty board and as the function loops, the state changes Move: no of moves taken by both the player and the computer

 for a in full(state):  #full returns a list of legal moves, which means columns that are not full
    state1= copy.deepcopy(state)
    playerplacetoken(state1, a)
    complete_set[move].append(state1)
    if CheckP(state1): #Check p returns boolean, checking if the player has won
        continue
    for b in full(state1):
        state2= copy.deepcopy(state1)
        PlacingCPUToken(state2, b)
        complete_set[move+1].append(state2)
        if CheckC(state2): #Check C checks if the computer wins and return a boolean
            continue
        while move<44:
            move+=2
            recursive(state2,move)
recursive(state0,0)

but this doesn't work properly (I mean it has no error but the results are not correct) I dont really know how to use a recursive function.Please help! 但这不能正常工作(我的意思是没有错误,但是结果不正确)我真的不知道如何使用递归函数。请帮忙!

  • You do a deep copy of the state to compute further moves. 您可以对状态进行深层复制以计算进一步的移动。
  • You create a new complete_set for each recursive invocation. 您为每个递归调用创建一个新的complete_set
  • You never return anything from the recursive step. 您永远不会从recursive步骤中return任何内容。

Because of this, there's no way for information computed in the nested steps to trickle up to the calling step. 因此,无法将嵌套步骤中计算的信息传递到调用步骤。

UPDATE: the state is indeed updated by a recursive step: complete_set[...].append(...) does that, because complete_set is global. 更新:状态确实是通过递归步骤更新的: complete_set[...].append(...)执行此操作,因为complete_set是全局的。

Try to think about the type of the function you're trying to write. 尝试考虑您要编写的函数的类型。

Eg it takes a state and an integer depth level. 例如,它需要一个状态和一个整数深度级别。 It returns a list of possible moves, which is empty if the depth it too big. 它返回可能移动的列表,如果深度太大,则为空。

What you may actually want is a tree of moves, where each element of your list is a pair: (move, [...]) . 您可能真正想要的是一棵移动 ,列表中的每个元素都是一对: (move, [...]) The list contains pairs of the same type: a move with a subtree of moves possible after it, etc. The leaves have an empty set of possible moves. 列表包含相同类型的对:一个动作及其后可能有一个动作子树,依此类推。叶子上有一组空的可能动作。

You might consider calculating the immediate utility function value right when you're building the nodes. 您可能会在构建节点时考虑立即计算立即效用函数值。

If you make the calculation lazy (using yield and generators), alpha-beta pruning will become easy to implement, too. 如果您使计算变得懒惰(使用yield和generators),那么alpha-beta修剪也将变得易于实现。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM