Копирование списка делается неправильно
Я решил ради потехи создать змейку в терминале python. И возникла проблема с отображением карты: есть список списков - поле размером width X height; я делаю копию списка в функции обновления карты и возвращаю обновлённую карту в главный цикл, где она и обрисовывается. Но почему-то переменная так называемой "чистой карты" переопределяется, хотя в коде этого нет.
Вот сам код:
import time
import os
class DevActions:
def __init__(self):
print("Инициализация действий разработчика . . .")
@staticmethod
def add_to_log(message: str, encoding: str = "utf-8"):
"""
Записывает данные в лог файл. Построчно (экранирование работает [\n, \r, \b])
:param message: сообщение записываемое в лог
:param encoding: кодировака
:return:
"""
with open(file = Settings.LOG_FILE, mode="a+", encoding=encoding) as log_file:
log_file.write(message + "\n")
class Settings:
EXTENSION_FOR_FILES = ".rqfile"
LOG_FILE = "log" + EXTENSION_FOR_FILES
class Snake:
def __init__(self):
self.__size = 5
self.direction_x = 1
self.direction_y = 0
self.__head = [9, 4]
self.snake_skin = "@"
self.speed_x = 1*self.direction_x
self.speed_y = 1*self.direction_y
self.__snake_cords = self.__create_snake()
def __create_snake(self):
snake_cords = []
for i in range(self.get_size()):
snake_cords.append([self.__head[0] - i, self.y_head()])
return snake_cords
def update(self):
pixel = [self.x_head() + self.speed_x, self.y_head() + self.speed_y]
self.__snake_cords.insert(0, pixel)
self.__snake_cords.pop(len(self.__snake_cords) - 1)
#print(self.__snake_cords)
self.__head = pixel
self.__redefine_directions()
def __redefine_directions(self):
"""
Переопределяет направления движения змейки.
Если змека двигается вверх она не может двигаться вправо\лево
И наоборот
:return:
"""
self.direction_x *= not self.direction_y
self.direction_y *= not self.direction_x
def change_direction(self, dir_x, dir_y) -> None:
self.direction_y = dir_y
self.direction_x = dir_x
def x_head(self) -> int:
return self.__head[0]
def y_head(self) -> int:
return self.__head[1]
def get_head_cords(self) -> list[int, int]:
return self.__head
def get_size(self) -> int:
return self.__size
def get_snake(self) -> list:
return self.__snake_cords
class Game:
def __init__(self):
self._dev = DevActions()
self.color = "0"
self.width = 32
self.height = 10
self.frame_update = None
self.snake = Snake()
self._origin_width_line = []
self.iter_per_second = 10
self.__iter_order = 0
self.sleep_time = 1/self.iter_per_second
self._map = []
self.game = True
self.pre_init()
def pre_init(self):
now_time = time.gmtime()
time_str = f"////{now_time.tm_mday}-{now_time.tm_mon}, {now_time.tm_hour+5}:{now_time.tm_min}////"
self._dev.add_to_log(time_str)
def init_map(self):
self._map = []
for j in range(self.width):
self._origin_width_line.append(self.color)
for i in range(self.height):
self._map.append(self._origin_width_line)
def update_map(self):
if self.snake.x_head() >= self.width or self.snake.y_head() >= self.height:
self.death()
map_cycle = None
map_cycle = self._map.copy()
for b in self._map:
print("".join(b))
print("Чистая карта вверху")
print(map_cycle)
for i in self.snake.get_snake():
i: list
y = i[1]
x = i[0]
map_cycle[y][x] = self.snake.snake_skin
#print(f"{type(_map[y])}, {type(_map[y][x])}") # отладка
self.snake.update()
return map_cycle
def death(self):
self.game = False
os.system("cls")
print("Вы проиграли")
self._dev.add_to_log("////Конец игры////")
time.sleep(0.5)
exit()
def __service_processing(self): # Служебная обработка цикла
self.__iter_order += 1
if self.__iter_order == self.iter_per_second + 1:
self.__iter_order = 1
mess_1 = f"Итерация#{self.__iter_order} \n"
mess_2 = f"snake_info:\n" \
f"size = {self.snake.get_size()}, \n" \
f"head_coord = ({self.snake.get_head_cords()})"
self._dev.add_to_log(f"{mess_1} {mess_2}")
def main_loop(self, game_loop=True):
self.game = game_loop
while self.game:
u_map = self.update_map()
for i in u_map:
print("".join(i))
# service_dev
self.__service_processing()
# -e
time.sleep(self.sleep_time)
os.system("cls")
if __name__ == '__main__':
game = Game()
game.init_map()
game.main_loop()
Ошибка либо в копировании списка, либо я не знаю тонкостей. Смотрите функции update_map, main_loop