Search code examples
pythonpython-3.xfunctionreturn

When returning a value from a function in python, it comes back empty


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.


Solution

  • 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]