Помогите решить проблемы с атрибутом

введите сюда описание изображения

from tkinter import *
import random
root = Tk()
root.title("Сапер")
class MineSweeper(Frame):
    """Класс с игрой Сапер"""

    # подготовка обьектов-изображений  вида ?.ppm
    images = {}
    for i in "012345678BFNSCT":
        images[i] = PhotoImage(file=i + ".png")

    # список приращений
    deltas = [(-1, -1), (-1, 0), (-1, -1), (0, -1), (0, 1), (1, -1), (1, 0),
              (1, 1)]

    def __init__(self, master, N=10, M=10, MINES=12):
        """Инициализация объекта-игры"""
        # вызываем конструктор базового класса
        Frame.__init__(self, master)
        assert 0 <= MINES < N * M
        self.MINES = MINES  # кол-во мин
        self.N, self.M = N, M  # размер поля
        ff = Frame(self)  # рамка с лицом
        ff.pack()
        bf = Frame(self)  #рамка с полем кнопок
        bf.pack()
        self.face = Button(ff, image=self.images["T"])  # кнопка лицо
        self.face.bind("<Button-2>", self.new_game)
        self.face.pack()
        self.button_field(bf)
        self.new_game()

    def open(self, button):
        """Открывает клетку, соответствующую кнопке button"""
        x, y = self.bfield[button]
        if self.field[(x, y)][0] == 0:
            self.field[x, y][0] = 1
            if self.field[(x, y)][1]:
                self.game_state = 1
            elif self.field[(x, y)][2] == 0:
                for dx, dy in self.deltas:
                    if self.bfield.has_key((x + dx, y + dy)):
                        self.open(self.bfield[(x + dx, y + dy)])
            self.visited = self.visited + 1
        self.draw_cell(x, y)
        self.ready()
        self.show_state()

    def step(self, event):
        """Реакция на щелчок по кнопке"""
        self.open(event.widget)

    def flag(self, event):
        """Пкм = установка и снятие флажка"""
        x, y = self.bfield[event.widget]
        if self.field[(x, y)][0] == 0:  # если нет флажка
            self.field[(x, y)][0] = 2  # устанавливаем флажок
            self.visited = self.visited + 1
            self.fragged = self.fragged + 1
        elif self.field[(x, y)][0] == 2:  # иначе снимаем
            self.field[(x, y)][0] = 0
            self.visited = self.visited - 1
            self.fragged = self.fragged - 1
        self.draw_cell(x, y)
        self.ready()
        self.show_state()

    def ready(self):
        """Проверяет готовность поля и устанавливает соответствующее состояние"""
        if self.game_state != 1 \
         and self.visited == self.N*self.M \
         and self.visited == self.MINES:
            self.game_state = 2

    def init_field(self):
        """подготовка поля к игре"""
        # Инициализация поля
        fld = {}
        for i in range(self.M):
            for j in range(self.N):
                fld[(i, j)] = [
                    0,  # 0 - нетронутый участок, 1 - открытый, 2 - с флажком
                    0,  # есть ли мина (0 или 1)
                    0
                ]  # кол-во мин вокруг (0-8)
        # установка мин
        nmines = 0
        while nmines < self.MINES:
            x = random.randrange(0, self.N)
            y = random.randrange(0, self.M)
            if fld[(x, y)][1] == 0:
                fld[(x, y)][1] = 1
                for dx, dy in self.deltas:
                    if fld.has_key((x + dx, y + dy)):
                        fld[(x + dx, y + dy)][2] = fld[(x + dx, y + dy)][2] + 1
                nmines += 1
        self.field = fld

    def draw_cell(
            self,
            X,
            Y,
    ):
        """Рисует Клетку поля"""
        b = self.bfield[(X, Y)]
        if self.bfield[(X, Y)][0] == 1:  # если участок открытый
            if self.bfield[(X, Y)] == 1:  # на нем мина
                img = self.images["B"]
            else:  # иначе пишем  кол-во мин у соседей
                img = self.images[str(self.bfield[(X, Y)][2])]
            b.config(relief=FLAT, image=img)
        else:
            if self.bfield[(X, Y)][0] == 0:  # если участок нетронутый
                img = self.images["0"]
            else:  # если на участке флажок
                img = self.images["F"]
            b.config(relief=RAISED, image=img)

    def draw_field(self):
        """рисует игровое поле"""
        for i in range(self.M):
            for j in range(self.N):
                self.draw_cell(i, j)
        self.show_state()

    def button_field(self, frame):
        """формирует полез из кнопок"""
        self.bfield = {}
        img = self.images["0"]
        for i in range(self.M):
            for j in range(self.N):
                b = Button(
                    frame,
                    image=img,
                    relief=RAISED,
                    highlightthickness=0,
                    borderwidth=1)
                b.grid(row=i, column=j)
                b.bind("<Button-1>", self.step)  #лкм
                b.bind("<Button-3>", self.flag)  #пкм
                # записываем в словарь координату
                self.bfield[i, j] = b  # кнопка по координатам
                self.bfield[b] = (i, j)  # координаты по кнопке

    def new_game(self, event=None):
        """Новая игра"""
        self.init_field()
        self.game_state = 0  # состояние игры # 0 - в процессе, 1 - проигрыш, 2 - выигрыш
        self.fragged = 0  # кол-во флажков
        self.visited = 0  # кол-во тронутый участков
        self.draw_field()


game = MineSweeper(root)
game.pack()
root.mainloop

Ответы (1 шт):

Автор решения: CrazyElf

In fact has_key() was removed in Python 3.x.

has_key() в Python 3 отсутствует, у вас, видимо, код написан под Python 2. Думаю, это будет далеко не единственная ошибка, но, в общем, вместо таких конструкций:

if self.bfield.has_key((x + dx, y + dy)):

Нужно использовать такие:

if (x + dx, y + dy) in self.bfield:
→ Ссылка