Minesweeper algorithm that opens all the safe squares in contact with each other from the starting square

Viewed 173

I am cooding a minesweeper and I have to make a function that will look through all the squares around the starting square. It should then open these squares and keep checking around the newly opened squares until there are no more safe squares in contact with the safe ones. What I have until now is

safe = [(x, y)]
while safe != []:
    k, c = safe.pop(-1)
    field[c][k] = "1"
    for i in range(k - 1, k + 2):
        for j in range(c - 1, c  + 2):
            if 0 <= i < len(field[0]) and 0 <= j < len(field):
                if field[j][i] == "1":
                    pass
                elif field[j][i] != "x":    
                    field[j][i] = "1"
                    safe.append((i, j))

This does open the squares but It does so to squares in contact diagonally aswell giving me a result such as

this

The field I'm using is this

field = [
[" ", " ", " ", "x", " ", " ", " ", " ", " ", " ", " ", "x", " "], 
[" ", " ", "x", "x", " ", " ", " ", "x", " ", " ", " ", "x", " "], 
[" ", "x", "x", " ", " ", " ", " ", "x", " ", " ", "x", "x", " "], 
["x", "x", "x", "x", "x", " ", " ", "x", " ", "x", " ", " ", " "], 
["x", "x", "x", "x", " ", " ", " ", " ", "x", " ", "x", " ", " "], 
[" ", " ", "x", " ", " ", " ", " ", " ", " ", "x", " ", " ", " "]]

What should I do to stop this from happening? Also I know the safe squares are all marked as 1 but this is an excerise in a course that will help me code the game fully later so It's not meant to give correct number of mines yet.

1 Answers

Your code is iterating over all 8 surrounding 'tiles' on the board when you should only check for the 4 tiles(1 above, 1 below, 1 to the left and 1 to the right). This is a basic flood fill algorithm. You should use a single loop instead of the 2 loops you use and a list containing the positions/moves like Nico Schertler commented. Here is the fixed up code:

safe = [(x, y)]
moves = [(-1, 0), (0, -1), (1, 0), (0, 1)]
while safe != []:
  k, c = safe.pop(-1)
  field[c][k] = "1"
  for i in moves:
    if 0 <= i[0]+k < len(field[0]) and 0 <= i[1]+c < len(field):
      if field[i[1]+c][i[0]+k] == "1":
        pass
      elif field[i[1]+c][i[0]+k] != "x":    
        field[i[1]+c][i[0]+k] = "1"
        safe.append((i[0]+k, i[1]+c))

I hope it's clear. You could always learn more about flood fill algorithmby searching for it.

Related