3

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.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
EK249
  • 29
  • 4
  • see: [understanding the minesweeper programming p.roblem](https://stackoverflow.com/a/40070891/2521214) – Spektre Jul 08 '20 at 16:19
  • If you just want to restrict your moves to horizontal and vertical, you could pre-specify a list with possible moves `moves = [(-1, 0), (0, -1), (1, 0), (0, 1)]` and iterate those instead of your two nested loops.for `i` and `j`. – Nico Schertler Jul 08 '20 at 16:42

1 Answers1

0

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.

Vedant36
  • 318
  • 1
  • 6