Возможность отменить последнее действие, используя клавишу.

BlazeFireLord

Новичок
Пользователь
Мар 31, 2021
1
0
1
Подскажите пожалуйста. Как можно сделать так.чтобы по нажатию например клавиши "B" отменялся последний ход в игре?


Код:
# Импорты

import tkinter as tk

from tkinter import messagebox

import random



# Tech Stuff

class Grid:

    def __init__(self, n):

        self.size = n

        self.cells = self.generate_empty_grid()

        self.compressed = False

        self.merged = False

        self.moved = False

        self.current_score = 0



    def random_cell(self):

        cell = random.choice(self.retrieve_empty_cells())

        i = cell[0]

        j = cell[1]

        self.cells[j] = 2 if random.random() < 0.9 else 4



    def retrieve_empty_cells(self):

        empty_cells = []

        for i in range(self.size):

            for j in range(self.size):

                if self.cells[j] == 0:

                    empty_cells.append((i, j))

        return empty_cells



    def generate_empty_grid(self):

        return [[0] * self.size for i in range(self.size)]



    def transpose(self):

        self.cells = [list(t) for t in zip(*self.cells)]



    def reverse(self):

        for i in range(self.size):

            start = 0

            end = self.size - 1

            while start < end:

                self.cells[start], self.cells[end] = \

                    self.cells[end], self.cells[start]

                start += 1

                end -= 1



    def clear_flags(self):

        self.compressed = False

        self.merged = False

        self.moved = False



    def left_compress(self):

        self.compressed = False

        new_grid = self.generate_empty_grid()

        for i in range(self.size):

            count = 0

            for j in range(self.size):

                if self.cells[j] != 0:

                    new_grid[count] = self.cells[j]

                    if count != j:

                        self.compressed = True

                    count += 1

        self.cells = new_grid



    def left_merge(self):

        self.merged = False

        for i in range(self.size):

            for j in range(self.size - 1):

                if self.cells[j] == self.cells[j + 1] and \

                   self.cells[j] != 0:

                    self.cells[j] *= 2

                    self.cells[j + 1] = 0

                    self.current_score += self.cells[j]

                    self.merged = True



    def found_2048(self):

        for i in range(self.size):

            for j in range(self.size):

                if self.cells[j] >= 2048:

                    return True

        return False



    def has_empty_cells(self):

        for i in range(self.size):

            for j in range(self.size):

                if self.cells[j] == 0:

                    return True

        return False



    def can_merge(self):

        for i in range(self.size):

            for j in range(self.size - 1):

                if self.cells[j] == self.cells[j + 1]:

                    return True

        for j in range(self.size):

            for i in range(self.size - 1):

                if self.cells[j] == self.cells[i + 1][j]:

                    return True

        return False



    def set_cells(self, cells):

        self.cells = cells



    def print_grid(self):

        print('-' * 40)

        for i in range(self.size):

            for j in range(self.size):

                print('%d\t' % self.cells[j], end='')

            print()

        print('-' * 40)



# Косметика

class GamePanel:

    CELL_PADDING = 10

    BACKGROUND_COLOR = '#92877d'

    EMPTY_CELL_COLOR = '#9e948a'

    CELL_BACKGROUND_COLOR_DICT = {

        '2': '#eee4da',

        '4': '#ede0c8',

        '8': '#f2b179',

        '16': '#f59563',

        '32': '#f67c5f',

        '64': '#f65e3b',

        '128': '#edcf72',

        '256': '#edcc61',

        '512': '#edc850',

        '1024': '#edc53f',

        '2048': '#edc22e',

        'beyond': '3c3a32'

    }

    CELL_COLOR_DICT = {

        '2': '#776e65',

        '4': '#776e65',

        '8': '#f9f6f2',

        '16': '#f9f6f2',

        '32': '#f9f6f2',

        '64': '#f9f6f2',

        '128': '#f9f6f2',

        '256': '#f9f6f2',

        '512': '#f9f6f2',

        '1024': '#f9f6f2',

        '2048': '#f9f6f2',

        'beyond': '#f9f6f2'

    }

    FONT = ('Verdana', 24, 'bold')

    UP_KEYS = ('w', 'W', 'Up')

    LEFT_KEYS = ('a', 'A', 'Left')

    DOWN_KEYS = ('s', 'S', 'Down')

    RIGHT_KEYS = ('d', 'D', 'Right')



# Magic shit

    def __init__(self, grid):

        self.grid = grid

        self.root = tk.Tk()

        self.root.title('Game 2048')

        self.background = tk.Frame(self.root, bg=GamePanel.BACKGROUND_COLOR)

        self.cell_labels = []

        for i in range(self.grid.size):

            row_labels = []

            for j in range(self.grid.size):

                label = tk.Label(self.background, text='',

                                 bg=GamePanel.EMPTY_CELL_COLOR,

                                 justify=tk.CENTER, font=GamePanel.FONT,

                                 width=4, height=2)

                label.grid(row=i, column=j, padx=10, pady=10)

                row_labels.append(label)

            self.cell_labels.append(row_labels)

        self.background.grid()



    def paint(self):

        for i in range(self.grid.size):

            for j in range(self.grid.size):

                if self.grid.cells[j] == 0:

                    self.cell_labels[j].configure(

                         text='',

                         bg=GamePanel.EMPTY_CELL_COLOR)

                else:

                    cell_text = str(self.grid.cells[j])

                    if self.grid.cells[j] > 2048:

                        bg_color = GamePanel.CELL_BACKGROUND_COLOR_DICT.get('beyond')

                        fg_color = GamePanel.CELL_COLOR_DICT.get('beyond')

                    else:

                        bg_color = GamePanel.CELL_BACKGROUND_COLOR_DICT.get(cell_text)

                        fg_color = GamePanel.CELL_COLOR_DICT.get(cell_text)

                    self.cell_labels[j].configure(

                        text=cell_text,

                        bg=bg_color, fg=fg_color)



#

# Main Game stuff

class Game:

    def __init__(self, grid, panel):

        self.grid = grid

        self.panel = panel

        self.start_cells_num = 2

        self.over = False

        self.won = False

        self.keep_playing = False



    def is_game_terminated(self):

        return self.over or (self.won and (not self.keep_playing))



    def start(self):

        self.add_start_cells()

        self.panel.paint()

        self.panel.root.bind('<Key>', self.key_handler)

        self.panel.root.mainloop()



    def add_start_cells(self):

        for i in range(self.start_cells_num):

            self.grid.random_cell()



    def can_move(self):

        return self.grid.has_empty_cells() or self.grid.can_merge()



    def key_handler(self, event):

        if self.is_game_terminated():

            return



        self.grid.clear_flags()

        key_value = event.keysym

        print('{} key pressed'.format(key_value))

        if key_value in GamePanel.UP_KEYS:

            self.up()

        elif key_value in GamePanel.LEFT_KEYS:

            self.left()

        elif key_value in GamePanel.DOWN_KEYS:

            self.down()

        elif key_value in GamePanel.RIGHT_KEYS:

            self.right()

        else:

            pass



        self.panel.paint()

        print('Score: {}'.format(self.grid.current_score))

        if self.grid.found_2048():

            self.you_win()

            if not self.keep_playing:

                return



        if self.grid.moved:

            self.grid.random_cell()



        self.panel.paint()

        if not self.can_move():

            self.over = True

            self.game_over()

# Итоги

    def you_win(self):

        if not self.won:

            self.won = True

            print('You Win!')

            if messagebox.askyesno('2048', 'How have you reached this?!Nevermind.You Win!\n'

                                       'Are you going to continue the 2048 game?'):

                self.keep_playing = True



    def game_over(self):

        print('Game over!')

        messagebox.showinfo('2048', 'Oops!\n'

                                    'Game over! Try another time,тефтеля.')



# Мувмент

    def up(self):

        self.grid.transpose()

        self.grid.left_compress()

        self.grid.left_merge()

        self.grid.moved = self.grid.compressed or self.grid.merged

        self.grid.left_compress()

        self.grid.transpose()



    def left(self):

        self.grid.left_compress()

        self.grid.left_merge()

        self.grid.moved = self.grid.compressed or self.grid.merged

        self.grid.left_compress()



    def down(self):

        self.grid.transpose()

        self.grid.reverse()

        self.grid.left_compress()

        self.grid.left_merge()

        self.grid.moved = self.grid.compressed or self.grid.merged

        self.grid.left_compress()

        self.grid.reverse()

        self.grid.transpose()



    def right(self):

        self.grid.reverse()

        self.grid.left_compress()

        self.grid.left_merge()

        self.grid.moved = self.grid.compressed or self.grid.merged

        self.grid.left_compress()

        self.grid.reverse()



if __name__ == '__main__':

    size = 4

    grid = Grid(size)

    panel = GamePanel(grid)

    game2048 = Game(grid, panel)

    game2048.start()
 
Последнее редактирование:

Форум IT Специалистов