I am making a minmax algorithm for a simple board game. When the findparent function returns data, sometimes it works fine, othertimes it comes back empty for some reason. Please help. Below is the malfunctioning part of the code.
from sys import maxsize
class Node(object):
def __init__(self,idepth,iplayernum,iboard):
self.idepth=idepth
self.iplayernum=iplayernum
self.iboard=iboard
self.children=[]
self.createchildren()
def createchildren(self):
if self.idepth>=0:
for x in range(0,4):
if self.iboard[x]>0:
for y in range(1,self.iboard[x]+1):
xiboard=self.iboard.copy()
xiboard[x]-=y
self.children.append(Node(self.idepth-1,-self.iplayernum,xiboard))
def checknodes(node,turn,ibestvalue,bestchoice):
for n in range(len(node.children)):
nchild=node.children[n]
childarr=[nchild,nchild.iboard]
for z in range(0,(idepth-nchild.idepth)):
childarr=findparent(childarr[0],inode)
print(childarr,'after return')
bestchoice=childarr[1]
if nchild.idepth>0:
checknodes(nchild,turn*-1,ibestvalue,bestchoice)
return(bestchoice)
def findparent(fnode,node):
for n in range(len(node.children)):
nhild=node.children[n]
if nhild==fnode and nhild.iboard==fnode.iboard:
print([node,node.iboard],'before return')
return [node,node.iboard]
elif nhild.idepth>0:
findparent(fnode,nhild)
iboardstart=[7,5,3,1]
idepth=3
icurplayer=1
row=int(input('The board is\n{}\n{}\n{}\n{}\nWhat row would you like to take from?'.format(iboardstart[0],iboardstart[1],iboardstart[2],iboardstart[3])))-1
amount=int(input('\nHow many would you like to take?'))
iboardstart[row]-=amount
icurplayer*=-1
inode=Node(idepth,icurplayer,iboardstart)
bestchoice=-100
ibestvalue=-icurplayer*maxsize
bestchoice=checknodes(inode,-1,ibestvalue,bestchoice)
iboardstart=bestchoice
print('Computer plays\n{}\n{}\n{}\n{}'.format(iboardstart[0],iboardstart[1],iboardstart[2],iboardstart[3]))
icurplayer*=-1
If you run it just input 1 for row and 1 for amount and see what it prints out. Hope you can help me guys, I would really appreciate it.
Your issue is that findparent
doesn't actually return anything from its recursive call.
However it's not as simple as return findparent(fnode,nhild)
as this has the possibility of returning None
if it's searching in the wrong branch. So you would need to get the value from the recursive call, check that the value exists, and then return it if it does.
You might try something like this:
def findparent(fnode, node):
value = None
for nchild in node.children:
if nchild is fnode and nchild.iboard == fnode.iboard:
print([node, node.iboard], 'before return')
value = [node, node.iboard]
elif nchild.idepth > 0:
value = findparent(fnode, nchild)
if value:
return value
As a side note, when looping through elements of a list, it's better to use
for nchild in node.children:
instead of
for n in range(len(node.children)):
nchild=node.children[n]