Динамически изменяется переменная в процедуре

Я делаю тетрис на питоне и столкнулся с одной проблемой.

Код:

import numpy as np
import time
import random
import os

class Tetris:
    def __init__(self):
        self.field = np.array([[0] * 12] + [[7] + [0] * 10 + [7]] * 20 + [[7] * 12])  # поле
        self.Tblock = {0: [1, 1], 1: [0, 0], 2: [0, 2], 3: [0, 1]}  # 1
        self.LbLock = {0: [0, 1], 1: [0, 0], 2: [1, 2], 3: [0, 2]}  # 2
        self.InvLblock = {0: [1, 1], 1: [0, 0], 2: [0, 2], 3: [0, 1]}  # 3
        self.Stick = {0: [1, 1], 1: [0, 0], 2: [0, 2], 3: [0, 1]}  # 4
        self.Zblock = {0: [1, 1], 1: [0, 0], 2: [0, 2], 3: [0, 1]}  # 5
        self.InvZblock = {0: [0, 1], 1: [0, 0], 2: [0, 2], 3: [0, 3]}  # 6
        self.DownCount = 1
        self.shift = 5
        self.nom = 1
        self.check = False
        self.block = []

    def rnd(self):
        if self.nom == 1:
            self.block = self.Tblock
        elif self.nom == 2:
            self.block = self.LbLock
        elif self.nom == 3:
            self.block = self.InvLblock
        elif self.nom == 4:
            self.block = self.Stick
        elif self.nom == 5:
            self.block = self.Zblock
        elif self.nom == 6:
            self.block = self.InvZblock

    def drafter(self):
        checker = False
        nom = self.nom * 10
        place = self.field
        while True:

            self.field = place


            for i in range(4):
                self.field[self.block[i][0] + self.DownCount, self.block[i][1] + self.shift] = nom
            os.system('cls')

            for i in range(4):
                b = self.field[self.block[i][0] + self.DownCount + 1, self.block[i][1] + self.shift]
                if b != nom:
                    if b != 0:
                        checker = True
                        break
            if checker:
                for i in range(4):
                    self.field[self.block[i][0] + self.DownCount, self.block[i][1] + self.shift] = nom / 10
                print(self.field)
                self.DownCount = 1
                break

            self.DownCount += 1

            print(self.field)
            time.sleep(1)

    def game_process(self):
        c = 0
        while True:
            self.rnd()
            self.drafter()

            for i in range(5, 9):
                if self.field[1][i] != 0:
                    c += 1
            if c >= 2:
                break
        print("Game  Over")


if __name__ == '__main__':
    game = Tetris()
    game.game_process()

Тут place = self.field я присваиваю переменной первоначальное состояние поля чтобы обнулить поле и отрисрвать блоки в другом месте self.field = place, однако получается так, что переменная place меняется вместе с self.field. Как можно это поравить?


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

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

На подобные вопросы тут много раз отвечали, но раз вы спрашиваете. Тут вы на самом деле копируете не объект, а ссылку на него:

place = self.field

Переменная place теперь указывает на тот же объект, что и self.field. Чтобы скопировать объект, нужно прямо так и написать "хочу копию объекта":

place = self.field.copy()

Теперь это два независимых объекта, которые можно менять, не затрагивая другой объект.

P.S. Обратное когда присваиваение делаете, тоже нужно, конечно, копировать:

self.field = place.copy()
→ Ссылка
Автор решения: Акакий мартенов

Сначала нужно импортировать

import copy

Потом скопировать

place = copy.copy(self.field)

И в цикле тоже необходимо копировать

self.field = copy.copy(place)
→ Ссылка