Minesweeper recursive dig function explanation

91 views Asked by At

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?

1

There are 1 answers

0
chomprrr On

In a recursive function, the functions calls are stacked something like this in the call stack:

enter image description here

So when you return from one particular call, you move on-to the next one until all the calls have been processed.