Search code examples
pythonpython-3.xtkinterminesweeper

Minesweeper miscalculation


I'm trying to implement Minesweeper in Python, using Tkinter to create the GUI. I'm having an issue with the functionality to count the mines adjacent to a square.

Here is the code where I set up the board as a list of lists. I assign the value 9 to indicate a mine.

from random import randint

# example values for testing
mines = 10
board = (10, 10)

mine_matrix = []
for line_number in range(board[1]):
        new_mine_line = []
        for column_number in range(board[0]):
            new_mine_line.append(0)
        mine_matrix.append(new_mine_line)

for mine in range(mines_amount):
    while True:
        mine_x = randint(0, board[1]-1)
        mine_y = randint(0, board[0]-1)
        if mine_matrix[mine_x][mine_y] < 8:
            mine_matrix[mine_x][mine_y] = 9
            break

Then I use this code to account for the number of adjacent mines. It should iterate over the field to look for the 9 values; when one is found, it should access the adjacent values (by iterating over values in control and adding them to the row and column indices) and add 1 to each.

control = -1, 0, 1
for line in range(board[1]):
    for column in range(board[0]):
        if mine_matrix[line][column] > 8:
            for line_control in control:
                for column_control in control:
                    try:
                        if (line == 0 or column == 0) and (line_control == -1 or column_control == -1): continue
                        mine_matrix[line+line_control][column+column_control] += 1
                    except: continue

I expect the if... continue code and the try/except logic to avoid problematic values (e.g. trying to subtract from the column index when looking at the left edge).

However, when I try running the code, some of the buttons have the wrong number on them.

For example, looking specifically at this part:

The middle square shows a 1, but there are two adjacent mines (marked in red).

What is wrong, and how do I fix the problem?


Solution

  • You need to make sure that both line+line_control and column+column_control are within valid range, then you don't need the try/except actually:

    control = (-1, 0, 1)
    for line in range(board[1]):
        for column in range(board[0]):
            if mine_matrix[line][column] > 8:
                for line_control in control:
                    for column_control in control:
                        if not (line_control == column_control == 0):
                            r, c = line+line_control, column+column_control
                            # make sure both r and c are within valid range
                            if (0 <= r < board[1]) and (0 <= c < board[0]):
                                mine_matrix[r][c] += 1