hi im vinzent
hi im vinzent

Reputation: 163

python: issue with return within a recursive function

For educational purpose I'm implementing a tic tac toe game in Python.

The function which is setting the players X or O is recursive:

def set_marker(player,board):
   print "\nplayer",player

   x = y = 3
   while(x not in range(0,3)):
       x = input("x: ")
   while(y not in range(0,3)):    
       y = input("y: ")

   if board[x][y] == 0:
       board[x][y]=player
       return board
   else:
       set_marker(player,board)
       # return board

Parameters:

board = 2dimensional list ( [[0, 0, 0], [0, 0, 0], [0, 0, 0]] )
player = int (value = '1' or '2')

If I set my 'X' to an already used field I'm calling the function again. When this case happens and I'm using 'board' in my main loop again the script is throwing following error:

Python: TypeError: 'NoneType' object has no attribute '__getitem__'

The type of board is in this case: none. I solved the problem by simply returning board also in the else: part.

Here goes my question:

Why do I have to return board also within else, as I'm calling the function until I return the proper board?

Upvotes: 0

Views: 774

Answers (2)

Nick is tired
Nick is tired

Reputation: 7055

set_marker(player,board)

should be:

return set_marker(player,board)

otherwise you've just recursively calling without passing the result up. Say on the first iteration it goes into the else, it will call set_marker, and then that may return board, at which point the outer call will have finished without returning anything, hence the TypeError.

Although it's probably better to not use recursion:

def set_marker(player,board):
    print "\nplayer",player

    x = y = 3
    while(x == 3 or board[x][y] != 0):
        while(x not in range(0,3)):
            x = input("x: ")
        while(y not in range(0,3)):    
            y = input("y: ")

        if board[x][y] == 0:
            board[x][y]=player
            return board

Upvotes: 2

natersoz
natersoz

Reputation: 1752

I would expect the following syntax:

   else:
       return set_marker(player,board)

When you make the call that results in the first part of the if statement, it will return 'board' but that return value needs to be propagated back through the call chain. If you do not return from the else block the value found in the recursive calls then nothing gets returned.

Upvotes: 0

Related Questions