簡體   English   中英

遞歸函數,用於連接Python中的四個可能的動作生成

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

我正在為我的學校項目編寫一個連接四個AI的程序。 但是首先,我想模擬6(row)* 7(column)上的所有可能移動,然后再編寫minimax算法以使電路板的每個階段都達到最佳移動。 而不是使用

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

我想用更整齊的方式做

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)

但這不能正常工作(我的意思是沒有錯誤,但是結果不正確)我真的不知道如何使用遞歸函數。請幫忙!

  • 您可以對狀態進行深層復制以計算進一步的移動。
  • 您為每個遞歸調用創建一個新的complete_set
  • 您永遠不會從recursive步驟中return任何內容。

因此,無法將嵌套步驟中計算的信息傳遞到調用步驟。

更新:狀態確實是通過遞歸步驟更新的: complete_set[...].append(...)執行此操作,因為complete_set是全局的。

嘗試考慮您要編寫的函數的類型。

例如,它需要一個狀態和一個整數深度級別。 它返回可能移動的列表,如果深度太大,則為空。

您可能真正想要的是一棵移動 ,列表中的每個元素都是一對: (move, [...]) 列表包含相同類型的對:一個動作及其后可能有一個動作子樹,依此類推。葉子上有一組空的可能動作。

您可能會在構建節點時考慮立即計算立即效用函數值。

如果您使計算變得懶惰(使用yield和generators),那么alpha-beta修剪也將變得易於實現。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM