Search code examples
pythonpython-3.xtkinterminesweeper

Trying to create the game minesweeper in python using Tkinter but have a problem finding the number of neighbors around a tile


The numbers show how many neighbors the tile has and should show: 3 neighbors on each corner, 5 on all four edges, and everything else 8. but for some reason the right edge shows 6 instead of five.

Here is an image of what I just done: image

from tkinter import *
from random import choice

root = Tk()
root.geometry("544x544")

# tile class
class Tile:
    def __init__(self, x, y, state=0):
        self.x = x
        self.y = y
        self.state = state
        self.button = Button(root,command=self.button_command, image=empty_block, height=28, width=28)
        self.listOfNeighbors = []
        self.neighbors = 0
    def button_command(self):
        print(self.x, self.y)
    def findNeighbors(self):
        self.listOfNeighbors.append(board[self.y-1][self.x])
        self.listOfNeighbors.append(board[self.y][self.x-1])
        self.listOfNeighbors.append(board[self.y-1][self.x-1])

        try: self.listOfNeighbors.append(board[self.y+1][self.x])
        except: pass
        try: self.listOfNeighbors.append(board[self.y+1][self.x-1])
        except: pass
        try: self.listOfNeighbors.append(board[self.y-1][self.x+1])
        except: pass
        try: self.listOfNeighbors.append(board[self.y+1][self.x+1])
        except: pass
        try: self.listOfNeighbors.append(board[self.y][self.x+1])
        except: pass

        self.sortNeighbors()

    def sortNeighbors(self):
        for i in self.listOfNeighbors:
            if self.y == 0:
                if i.y == 15: self.listOfNeighbors.remove(i);print(self.x, self.y," ", i.x, i.y)

            elif self.x == 0:
                if i.x == 15: self.listOfNeighbors.remove(i);print(self.x, self.y," ", i.x, i.y)

        self.neighbors = len(self.listOfNeighbors)
        self.button.config(image=neighbors_images[self.neighbors])


#variable
empty_block = PhotoImage(file="images/empty-block.png")
bomb_unclicked = PhotoImage(file="images/unclicked-bomb.png")
bomb_clicked = PhotoImage(file="images/bomb-at-clicked-block.png")
neighbors_images = [
    PhotoImage(file="images/0.png"),
    PhotoImage(file="images/1.png"),
    PhotoImage(file="images/2.png"),
    PhotoImage(file="images/3.png"),
    PhotoImage(file="images/4.png"),
    PhotoImage(file="images/5.png"),
    PhotoImage(file="images/6.png"),
    PhotoImage(file="images/7.png"),
    PhotoImage(file="images/8.png"),
]

board = []
for y in range(16):
    temp = []
    for x in range(16):
        temp.append(Tile(x, y))
        temp[-1].button.grid(row=y, column=x)
    board.append(temp)

for i in range(40):
    choice(choice(board)).state = 1

for y in board:
    for x in y:
        x.findNeighbors()

root.mainloop()

As far as I see, the problem comes from line 42 in which I trying to remove from the list of neighbors any Tile that is outside the board.


Solution

  • You are making it harder on yourself. I suggest being explicit and avoid adding and then removing unnecessary neighbours:

    def findNeighbors(self):
        NEIGHBOURS = [
            (-1, -1),
            (-1, 0),
            (-1, 1),
            (0, -1),
            (0, 1),
            (1, -1),
            (1, 0),
            (1, 1)
        ]
    
        for dx, dy in NEIGHBOURS:
            if 0 <= self.x + dx < len(board[0]) and 0 <= self.y + dy < len(board):
                self.listOfNeighbors.append(board[self.y + dy][self.x + dx])
    
        self.sortNeighbors()
    
    def sortNeighbors(self):
        self.neighbors = len(self.listOfNeighbors)
        self.button.config(image=neighbors_images[self.neighbors])