@pavelermolenko

Как устранить ошибку генератора?

Здравствуйте. Я решил сделать цифровую версию настольной игры "Лабиринт" в целях развития навыков и для начала запланировал вывод через консоль. Я сейчас нахожусь на самых ранних этапах разработки и на данный момент занимаюсь генерацией лабиринта. Лабиринт представляет собой поле 7*7 из квадратов, на которых находится дорога одного из 3-х видов - угол, прямая или т-образная. На каждом поле может находиться какое-либо сокровище, или его там не может быть вовсе, но на данный момент это не столь важно. Вот класс, который я написал для описания одного квадратика:
class Square:
    def __init__(self, square_type, angle, treasure=None):
        self.square_type = square_type # может быть "angular", "straight" или "t-shaped"
        self.angle = angle # может быть 0, 90, 180 и 270
        self.treasure = treasure


Я предположил, что поле нужно описывать в двумерном массиве 7*7 из элементов класса Square. По правилам игры, все элементы, расположенные на позициях, имеющих оба индекса из множества четных чисел или 0, определены заранее и неподвижны. Их значения я добавил в массив поля сразу после определения массива:
from squares import Square

rows = 7
columns = 7
field = [[None for _ in range(columns)] for _ in range(rows)]
for i in range(rows):
    for j in range(columns):
        field[i][j] = Square

field[0][0] = Square("angular", 0)
field[0][2] = Square("t-shaped", 0, "skull")
field[0][4] = Square("t-shaped", 0, "sword")
field[0][6] = Square("angular", 90)

field[2][0] = Square("t-shaped", 270, "pouch")
field[2][2] = Square("t-shaped", 270, "keys")
field[2][4] = Square("t-shaped", 0, "emerald")
field[2][6] = Square("t-shaped", 90, "helmet")


field[4][0] = Square("t-shaped", 270,"book")
field[4][2] = Square("t-shaped", 180, "crown")
field[4][4] = Square("t-shaped", 90, "chest")
field[4][6] = Square("t-shaped", 90, "chandelier")

field[6][0] = Square("angular", 270)
field[6][2] = Square("t-shaped", 0, "map")
field[6][4] = Square("t-shaped", 0, "ring")
field[6][6] = Square("angular", 180)


Остальные незакреплённые квадратики также имеют определенные типы дорожек и сокровищ на них, но их позиции и угол определяются случайно перед началом игры. Вот их определение:
undefined_squares = []

for i in range(0, 12):
    undefined_squares.append(Square("straight", 0))


for i in range(12, 22):
    undefined_squares.append(Square("angular", 0))


undefined_squares.append(Square("angular", 0, "spider"))
undefined_squares.append(Square("angular", 0, "owl"))
undefined_squares.append(Square("angular", 0, "butterfly"))
undefined_squares.append(Square("angular", 0, "mouse"))
undefined_squares.append(Square("angular", 0, "lizard"))
undefined_squares.append(Square("angular", 0, "scarab"))
undefined_squares.append(Square("t-shaped", 0, "hobbit"))
undefined_squares.append(Square("t-shaped", 0, "ghost"))
undefined_squares.append(Square("t-shaped", 0, "bat"))
undefined_squares.append(Square("t-shaped", 0, "enchantress"))
undefined_squares.append(Square("t-shaped", 0, "jinn"))
undefined_squares.append(Square("t-shaped", 0, "dragon"))


А вот генератор, который я написал, чтобы пустые элементы поля заполнить квадратиками из массива undefined_squares:
from field import field
from squares import undefined_squares
import numpy.random as rand


def field_generator():
    for i in range(7):
        for j in range(7):
            if field[i][j] is None:
                field[i][j] = rand.choice(undefined_squares, replace=False)


Так как я хочу сделать для начала вывод в консоль, я создал переменные, которые соответствуют каждой комбинации типов дорожек и углов поворота, а затем написал словарь, чтобы вызывать эти переменные в соответствии со значениями элементов класса Square из массива Field игрового поля:
angular_0 = [
    "######",
    "##    ",
    "##  ##"
]

angular_90 = [
    "######",
    "    ##",
    "##  ##"
]

angular_180 = [
    "##  ##",
    "    ##",
    "######"
]

angular_270 = [
    "##  ##",
    "##    ",
    "######"
]

straight_0 = [
    "##  ##",
    "##  ##",
    "##  ##"
]

straight_90 = [
    "######",
    "      ",
    "######"
]

t_shaped_0 = [
    "##  ##",
    "      "
    "######"
]

t_shaped_90 = [
    "##  ##",
    "##    ",
    "##  ##"
]

t_shaped_180 = [
    "######",
    "      ",
    "##  ##"
]

t_shaped_270 = [
    "##  ##",
    "    ##",
    "##  ##"
]


from console_visual import (
    angular_0,
    angular_90,
    angular_180,
    angular_270,
    straight_0,
    straight_90,
    t_shaped_0,
    t_shaped_90,
    t_shaped_180,
    t_shaped_270,
)

templates = {
    ("angular", 0): angular_0,
    ("angular", 90): angular_90,
    ("angular", 180): angular_180,
    ("angular", 270): angular_270,
    ("straight", 0): straight_0,
    ("straight", 90): straight_90,
    ("t-shaped", 0): t_shaped_0,
    ("t-shaped", 90): t_shaped_90,
    ("t-shaped", 180): t_shaped_180,
    ("t-shaped", 270): t_shaped_270,
}


Я решил протестировать эти функции и написал просто код в мейне, который должен был сгенерировать лабиринт и вывести его:
from field_generator import field_generator, field
from templates import templates

field_generator()

for row in field:
    for square in row:
        template = templates.get((square.square_type, square.angle))

        if template:
            for line in template:
                print(line)


При выполнении кода выходит следующая ошибка:
######
##    
##  ##
Traceback (most recent call last):
  File "/Users/polina/PycharmProjects/labirynth_game/main.py", line 8, in <module>
    template = templates.get((square.square_type, square.angle))
AttributeError: type object 'Square' has no attribute 'square_type'

Process finished with exit code 1


Подскажите пожалуйста, в чем моя ошибка?
  • Вопрос задан
  • 112 просмотров
Пригласить эксперта
Ответы на вопрос 1
Maksim_64
@Maksim_64
Data Analyst
Ну что-то совершенно, не читабельное ты написал. В python генераторами принято называть функции которые возвращают итераторы используя yield. То есть любая функция которая содержит yield называется генератором.

Твой "генератор" пытается заполнить массив значениями и к генераторам не имеет отношения от слова совсем.

from field import field это не хорошо. Если тебе нужна переменная из другого модуля то import field затем field.field в том модуле куда импортировал.

Это я так глазами пробежался, если вникать много чего еще выйдет.

что касается непосредственно ошибки. То где то в коде ты вместо создания экземпляра класса создал ссылку на объект класса и затем у этого объекта пытаешься найти атрибут. Что бы было понятнее приведу пример.

class A:

    def __init__(self,x):
        self.x = x
a = A
print(a.x)
Выдаст точно такую ошибку. Нужно вместо a=A, написать a=A() со всеми параметрами, или на прямую ты обращаешься к объекту класса а атрибут у тебя экземпляра класса, то есть вот так.
class A:
    def __init__(self):
        self.x = 'Hello'
print(A.x)

Ищи где у тебя в коде такое, а лучше начни писать весь свой код заново.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы