I am learning Python from scratch and went through the basics and now I started solving some online exercises for training and I came across the minesweeper game (coded by Kylie Ying: https://github.com/kying18/minesweeper).
I am reading the code and try to iterate it myself for a better understanding of how it works and came across the dig function that is responsible of digging all the cells surrounding a mine.
I am iterating the dig function one by one and I came across something that I don't understand.
This is a section of the code. I modified it to make it simpler.
class Board():
def __init__(self):
self.dim_size = 10
self.board = [
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 1, 1, 1, 0, 0],
[0, 0, 0, 0, 0, 1, '*', 1, 0, 0],
[0, 0, 0, 0, 1, 1, '*', 1, 1, 1],
[0, 1, 1, 1, 1, '*', '*', '*', '*', '*'],
[0, 1, '*', '*', '*', '*', '*', '*', '*', '*'],
[0, 1, '*', '*', '*', '*', '*', '*', '*', '*'],
]
self.dug = set()
def dig(self, row, col):
self.dug.add((row, col)) # keep track that we dug here
if self.board[row][col] == '*':
return False
elif self.board[row][col] > 0:
return True
r_range = range(max(0, row-1), min(self.dim_size-1, row+1)+1)
c_range = range(max(0, col-1), min(self.dim_size-1, col+1)+1)
for r in r_range:
for c in c_range:
if (r, c) in self.dug:
continue # don't dig where you've already dug
print("----------------")
self.dig(r, c)
panel = Board()
print(panel.dig(6, 3))
Initially I am supplying the cell (6, 3) as the starting point for digging.
The dig function will start digging the panel as follows:
(6, 3) (5, 2) (4, 1) (3, 0) (2, 0) (1, 0) (0, 0) (0, 1) (0, 2) (0, 3) (0, 4) (0, 5) (0, 6) (0, 7) (0, 8) (0, 9) (1, 8) (1, 7) (1, 6) (1, 5) (1, 4) (1, 3) (1, 2) (1, 1) (2, 1) (2, 2) (2, 3) (2, 4) (2, 5) (2, 6) (2, 7) (2, 8) (1, 9) (2, 9) (3, 8) (3, 7) (3, 6) (3, 5) (3, 4) (3, 3) (3, 2) (3, 1) (4, 0) (5, 0) (5, 1) (4, 2) (4, 3) (4, 4) (4, 5) (5, 3) (5, 4) (5, 5) (6, 4) (6, 5) (6, 2) (6, 1) (6, 0) (7, 0) (7, 1) (8, 0) (8, 1) (9, 0) (9, 1) (7, 2) (7, 3) (4, 6) (4, 7) (4, 8) (3, 9) (4, 9) (5, 8) (5, 7) (5, 9) (6, 8) (6, 9) (6, 7) (7, 4)
Now something strange happens when the dig function reaches the cell (4, 5) that contains a value 1.
According to the code segment:
elif self.board[row][col] > 0:
return True
the function should now return True and exit, but instead the code segment:
self.dig(r, c)
gets executed and the function is entered again.
Why is this happening?
In a recursive function, the functions calls are stacked something like this in the call stack:
So when you return from one particular call, you move on-to the next one until all the calls have been processed.