So I'm attempting to learn Python by way of Minesweeper. I've got experience with SDL, so I figured playing around with PyGame sounded like a fun way to learn the syntax of the language.
Anywho, I'm having an issue in uncovering adjacent open squares as you would in a normal game of Minesweeper. I click on a cell with 0 neighboring mines, and attempt to scan the top, left, right, and bottom to see if those also have 0 neighboring mines, and I do this recursively.
Here is the error that I receive:
RuntimeError: maximum recursion depth exceeded in cmp
And here is my algorithm:
#open up blank mines
def open_blank_cells(mines, cr, cc):
#top
if (cr > 0):
t_mine = mines[cr-1][cc]
t_mine.switch_state(3)
if (t_mine.neighbor_mines == 0):
open_blank_cells(mines, cr-1, cc)
#right
if (cc < 9):
r_mine = mines[cr][cc+1]
r_mine.switch_state(3)
if (r_mine.neighbor_mines == 0):
open_blank_cells(mines, cr, cc+1)
#bottom
if (cr < 9):
r_mine = mines[cr+1][cc]
r_mine.switch_state(3)
if (r_mine.neighbor_mines == 0):
open_blank_cells(mines, cr+1, cc)
#left
if (cc > 0):
l_mine = mines[cr][cc-1]
l_mine.switch_state(3)
if (l_mine.neighbor_mines == 0):
open_blank_cells(mines, cr, cc-1)
return
where mines
is my 2D array of cells, cr
is the index of the current row (first array index), and cc
is the index of the current column (second array index).
I thought that my algorithm was decently solid (but please tell me if I'm wrong there!!!), so I turned to the Internet and found that the default Python recursion limit of 1000 could be to blame. However, when I bump it higher with the call to sys.setrecursionlimit
the game either exhibits the same behavior, or simply crashes as the system kills it.
When I comment out 2 of the 4 recursive checks in the function, it will open up blank cells without any problem. 3 or more however breaks the algorithm.
Edit
As requested....
Calculation of neighbor_mines
# if not a mine, figure out how many surround it
for i in xrange(10):
for j in xrange(10):
if (mines[i][j].is_mine == False):
#check top 3
if (i > 0):
if (j > 0):
if (mines[i-1][j-1].is_mine == True):
mines[i][j].neighbor_mines += 1
if (mines[i-1][j].is_mine == True):
mines[i][j].neighbor_mines += 1
if (j < 9):
if (mines[i-1][j+1].is_mine == True):
mines[i][j].neighbor_mines += 1
#check left and right
if (j > 0):
if (mines[i][j-1].is_mine == True):
mines[i][j].neighbor_mines += 1
if (j < 9):
if (mines[i][j+1].is_mine == True):
mines[i][j].neighbor_mines += 1
#check bottom 3
if (i < 9):
if (j > 0):
if (mines[i+1][j-1].is_mine == True):
mines[i][j].neighbor_mines += 1
if (mines[i+1][j].is_mine == True):
mines[i][j].neighbor_mines += 1
if (j < 9):
if (mines[i+1][j+1].is_mine == True):
mines[i][j].neighbor_mines += 1
Switch_state
def switch_state(self, newstate):
self.state = newstate
#marked as mine
if (newstate == 1):
nf = "sq_mine_marked.png"
elif (newstate == 2):
nf = "sq_mine_question.png"
elif (newstate == 3):
nf = "sq_mine_open.png"
elif (newstate == 4):
nf = "sq_mine_mine.png"
else:
nf = "sq_mine.png"
oldrect = self.rect #save old rect as load_image overwrites it
self.image, self.rect = load_image(nf, (255,0,255))
self.rect = oldrect