-1

I am making a win checking function for a Connect 4 game. The grid is 7x6, and having 4 tiles in a row should cause the function to return True, otherwise it returns False. The relevant code is as follows:

grid=[[" O ","   ","   ","   ","   ","   "],["   "," O ","   ","   ","   ","   "],["   ","   "," O ","   ","   ","   "],["   ","   ","   "," O ","   ","   "],["   ","   ","   ","   "," O ","   "],["   ","   ","   ","   ","   "," O "],["   ","   ","   ","   ","   ","   "]]
#2D array for grid

typetofunct={"left":"x-1,y,'left'","right":"x+1,y,'right'","up":"x,y+1,'up'","down":"x,y-1,'down'","topleft":"x-1,y+1,'topleft'","topright":"x+1,y+1,'topright'","downleft":"x-1,y-1,'downleft'","downright":"x+1,y-1,'downright'"}
def check(x,y,checktype,count):
    if not ((x==0 and (checktype=="left" or checktype=="topleft" or checktype=="bottomleft")) or (x==6 and (checktype=="right" or checktype=="bottomright" or checktype=="topright")) or (y==0 and (checktype=="down" or checktype=="downleft" or checktype=="downright")) or (y==5 and (checktype=="up" or checktype=="topleft" or checktype=="topright"))): #doesn't check if it's on a boundary
        print("Checked {0}".format(checktype))
        if grid[x][y]!="   ":
            print(count)
            count+=1
            if count>=4:
                print("True reached")
                return True
            else:
                print("Looping")
                return exec("check({0},count)".format(typetofunct.get(checktype)))
                #recurs the function, has to get it from a dictionary according to string
        else:
            print("Grid was empty")
            return count>=4
    else:
        print("Out of bounds")
        return False
print(check(0,0,"topright",0))

This should be printing:

Checked topright
0
Looping
Checked topright
1
Looping
Checked topright
2
Looping
Checked topright
3
True reached
True

but what I get is:

Checked topright
0
Looping
Checked topright
1
Looping
Checked topright
2
Looping
Checked topright
3
True reached
None

As far as I can tell, this function should only ever return True or False. Please help.

2 Answers2

0

The return exec("check({0},count)".format(typetofunct.get(checktype))) is what's returning None.

>>> a = exec("print('ciao')")
ciao
>>> a is None
True
>>>
Fish11
  • 453
  • 3
  • 12
Gerardo Zinno
  • 1,518
  • 1
  • 13
  • 35
0

The issue is that the function exec does not return anything, even if the function inside it does. So the line:

return exec("check({0},count)".format(typetofunct.get(checktype)))

Will always return None.

Why not directly calling the function itself instead, without using exec?

return check(typetofunct.get(checktype),count)
Anis R.
  • 6,656
  • 2
  • 15
  • 37
  • The issue is that I'm getting multiple arguments from typetofunct, which is why I used exec() to add both arguments. eval() works, though. – BusterTornado Mar 12 '20 at 23:25
  • @BusterTornado I see. Then, why not using tuples instead of strings in your dictionary? This would make it much easier to access each element alone. – Anis R. Mar 12 '20 at 23:27
  • Because x and y are only defined within the function but not the dictionary, it throws an error when trying to define the dictionary at the start of the code. I could define the dictionary at the start of the function instead, but it would be more efficient to just use eval() in the function as opposed to re-defining a dictionary every time it loops. – BusterTornado Mar 12 '20 at 23:33