0

So, I'm doing some minMax AI, and somehow during a recursive routine, a variable that is not written to is changing. I have attatched the whole code, but the issue seems to be contained within the populateChildren() subroutine. Each time, the 'sectors' array is somehow written to, my only idea is that perhaps 'sectors' is somehow becoming an alias to something else, or is being imported as an argument to something. I can't see the issue, but thanks in advance if anyone can tell me what I'm doing wrong.

class Node(object):

    def populateChildren(self,player,board):
        newBoard=board
        start=randomStart(board, player)
        if self.depth>-1:
            for i in board[start][4]: 
                print("1: ",sectors[0][3])  ##OUTPUTS "1: 0"
                newBoard[0][3]=1000000   ##This is not the actually intented process, but shows the issue
                print("2: ",sectors[0][3])  ##OUTPUTS "2: 1000000"
                self.children.append(Node((self.depth)-1,-self.player,newBoard,self.treeVal(newBoard)))
        else:
            print("RECURSION END")

    def treeVal(self,board):
        if checkWin(board)==True:
            return maxsize*self.player
        elif checkWin:
            return maxsize*-self.player
        return 0

    def __init__(self,depth,player,newBoard,value=0):
        self.depth=depth
        self.player=player
        self.value=value
        self.children=[]
        #self.board=board
        #print("pop conditions: ",player,newBoard)
        self.populateChildren(player,newBoard)
        #print("post-pop conditions: ",player,newBoard)

def minMax(node,depth,player):
    print("RUN Run Run run run \n\\n\n\n\n\n\n\ run ")
    if depth==0 or abs(node.value)==maxsize:
        print("DONE\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nDONE")
        return node.value
    bestValue=maxsize*-playerNum
    for i in range(0,5):
        child=node.children[i]
        value=MinMax(child,depth-1,-playerNum)
        if abs(maxsize*playerNum-value)<abs(maxsize*playerNum-bestValue):
            bestValue=value
    print(str(depth*playerNum)+")"+" "*depth+str(bestvalue))
    return bestValue

def AIMove(Node,sectors):
   temp=sectors
   newBoard=temp
   ##newBoard=sectors
   currentPlayer=-1
   depth=5
   print(depth)
   looks=0
   while looks<6:
      Node.player=-1
      node=Node(depth,currentPlayer,newBoard,value=0)
      bestChoice=-100
      bestValue=currentPlayer*maxsize
      for i in range(len(node.children)):
         child=node.children[i]
         value=minMax(child,depth,currentPlayer)
         if (abs(currentPlayer*maxsize-value)<=abs(currentPlayer*maxsize-bestValue)):
            bestValue=value
            bestChoice=i
      bestChoice+=1
      print("node: ",node.children[0].value)
      print("choice: ",bestChoice)
      looks+=1
W.Hunt
  • 31
  • 1
  • 2
  • 8

1 Answers1

1

So as I see it, in AIMove you set temp to sectors, then newBoard to temp and pass this into Node further down as the newBoard parameter. You pass this to populate children as board, which you assign to newBoard which you change, hence sectors changes. Phew! You're always just linking to the same location in memory and so new object name doesn't mean new object.

gboffi
  • 22,939
  • 8
  • 54
  • 85
  • Oh I see, awesome, thanks man :) How do you suggest I copy it to become a new variable (i.e: create a new baord that I can work on without changing the origional secotrs array)? – W.Hunt Feb 08 '17 at 10:30
  • So you need to make a deep copy, take a look at these questions: http://stackoverflow.com/questions/6431973/how-to-copy-data-from-a-numpy-array-to-another?rq=1 and http://stackoverflow.com/questions/19676538/numpy-array-assignment-with-copy. They should help :-) – Elliott Levi Feb 08 '17 at 10:35
  • Thanks so much! I've been trying to fix this issue for ages, I opted to use copy.deepcopy instead of numpy, but it seems to be working. Cheers – W.Hunt Feb 08 '17 at 16:42