Exemple #1
0
    def test_figure_move_left(self):
        f = Figure()

        cells = f.move_left()
        for idx, cell in enumerate(f.cells):
            self.assertEqual(cells[idx][0] + 1, cell[0])
            self.assertEqual(cells[idx][1], cell[1])
Exemple #2
0
class GameLogic:
    def __init__(self, config):
        self.config = config
        self.falling_cycles = int(config.falling_rate / config.refresh_rate)
        self.current_cycle_count = 0
        self.tetromino = None
        self.score = 0
        self.game_ended = False

    def is_step_down_cycle(self):
        self.current_cycle_count = (self.current_cycle_count +
                                    1) % self.falling_cycles
        if self.current_cycle_count == 0:
            return True
        return False

    def set_game_ended(self, has_ended):
        self.game_ended = has_ended

    def get_score(self):
        return self.score

    def has_full_row(self):
        # start check with the bottom line
        reverse_grid = copy.deepcopy(self.config.grid)
        reverse_grid.reverse()
        for i, line in enumerate(reverse_grid):
            full_blocks = 0
            for block in line:
                if block == "X":
                    full_blocks += 1
            if full_blocks == len(line):
                self.score += 1
                del self.config.grid[len(self.config.grid) - i - 1]
                self.config.grid.insert(
                    0, [" " for _ in range(self.config.columns)])
                return True
        return False

    def do_logic(self, input_key):
        if not self.game_ended:
            self.has_full_row()

            if self.tetromino is None or self.tetromino.is_dead:
                self.tetromino = Figure(self.config.columns, self.config.line,
                                        self.config)
            else:
                if input_key == 100:
                    self.tetromino.move_right()
                if input_key == 97:
                    self.tetromino.move_left()
                if input_key == 115:
                    self.tetromino.move_to_bottom()
                if input_key == 119:
                    self.tetromino.rotate_right()

                if self.is_step_down_cycle():
                    self.tetromino.move_step_down()

                    if self.tetromino is not None and self.tetromino.y <= 0:
                        raise Exception("Initial collision")

        return self.tetromino.draw(copy.deepcopy(self.config.grid))
Exemple #3
0
class Game(Frame):
    """Game class"""
    def __init__(self, master=None, title="Application"):
        """init Game class"""
        Frame.__init__(self, master)
        self.bQuit = Button(self, text='Quit', command=self.quit)
        self.master.rowconfigure(0, weight=1)
        self.master.columnconfigure(0, weight=1)
        self.master.title(title)
        self.grid(sticky=N + E + S + W)
        self.best = 0
        self.score = 0
        self.lines = 0
        self.first_screen()

    def create_figure(self):
        """Create figure and next figure fu9nction"""
        if self.next_figure is not None:
            self.control.canvas_next.remove_figure(self.next_figure.shifted())
            self.current_figure = self.next_figure
        else:
            self.current_figure = Figure()

        # Draw next figure
        self.next_figure = Figure()
        self.control.canvas_next.hold_figure(self.next_figure.shifted())
        self.control.canvas_next.redraw()

    def gravity(self, event=None):
        """Move the figure one cell down and draw function"""
        self.control.canvas.remove_figure(self.current_figure)
        coords = self.current_figure.move_down()
        if self.control.canvas.is_valid_coords(coords):
            self.current_figure.cells = coords
        else:
            self.control.canvas.hold_figure(self.current_figure)
            lines = self.control.canvas.find_complete_lines(
                self.current_figure)
            self.lines += lines
            self.score += 4
            if self.score > self.best:
                self.best = self.score
            self.control.score_string.set(f"Score: {self.score}")
            self.control.best_string.set(f"Best: {self.best}")
            self.control.lines_string.set(f"Lines: {self.lines}")
            self.create_figure()
            if self.control.canvas.is_valid_coords(self.current_figure.cells):
                self.control.canvas.hold_figure(self.current_figure)
            else:
                self.game_over()
                return 0
        self.control.canvas.hold_figure(self.current_figure)
        return 1

    def move_left(self, event):
        """Move the figure one cell left and draw function"""
        self.control.canvas.remove_figure(self.current_figure)
        coords = self.current_figure.move_left()
        if self.control.canvas.is_valid_coords(coords):
            self.current_figure.cells = coords
        self.control.canvas.hold_figure(self.current_figure)
        self.control.canvas.redraw()

    def move_right(self, event):
        """Move the figure one cell right and draw function"""
        self.control.canvas.remove_figure(self.current_figure)
        coords = self.current_figure.move_right()
        if self.control.canvas.is_valid_coords(coords):
            self.current_figure.cells = coords
        self.control.canvas.hold_figure(self.current_figure)
        self.control.canvas.redraw()

    def rotate(self, event):
        """Rotate the figure clockwise and draw function"""
        self.control.canvas.remove_figure(self.current_figure)
        coords = self.current_figure.rotate()
        if self.control.canvas.is_valid_coords(coords):
            self.current_figure.cells = coords
        self.control.canvas.hold_figure(self.current_figure)
        self.control.canvas.redraw()

    def first_screen(self):
        """Start screen control"""
        self.control = Frame(borderwidth=3, relief="solid", bg="white")
        self.control.grid(row=0, column=0, sticky=N + E + S + W)

        header_im = PhotoImage(file="tetris.png")
        self.control.header = Label(self.control,
                                    image=header_im,
                                    borderwidth=3,
                                    relief="solid",
                                    width=400,
                                    bg="white")
        self.control.header.image = header_im
        self.control.header.grid(row=0, columnspan=3, sticky=N + E + S + W)

        self.control.canvas = CanvasGame(self.control,
                                         width=400,
                                         height=600,
                                         borderwidth=3,
                                         relief="solid",
                                         bg="white",
                                         rows=24,
                                         columns=16,
                                         cell=25)
        self.control.canvas.grid(row=1, column=0, rowspan=7)

        self.control.canvas_next = Canvas(self.control,
                                          width=150,
                                          height=200,
                                          borderwidth=3,
                                          relief="solid",
                                          bg="white")
        self.control.canvas_next.grid(row=1,
                                      column=1,
                                      columnspan=2,
                                      sticky=N + E + S + W)

        self.control = Frame(borderwidth=3, relief="solid", bg="white")
        self.control.grid(row=0, column=0, sticky=N + E + S + W)

        self.control.best_string = StringVar()
        self.control.best_string.set(f"Best: {self.best}")
        self.control.score_string = StringVar()
        self.control.score_string.set(f"Score: {self.score}")

        header_im = PhotoImage(file="tetris.png")
        self.control.header = Label(self.control,
                                    image=header_im,
                                    borderwidth=3,
                                    relief="solid",
                                    width=615,
                                    bg="white")
        self.control.header.image = header_im
        self.control.header.grid(row=0, columnspan=4, sticky=N + E + S + W)

        self.control.score = Label(self.control,
                                   textvariable=self.control.score_string,
                                   borderwidth=3,
                                   relief="solid",
                                   font=("Liberation Sans", 14),
                                   bg="white")
        self.control.score.grid(row=2,
                                column=1,
                                columnspan=2,
                                sticky=N + E + S + W)

        self.control.new_game = Button(self.control,
                                       text="New Game",
                                       command=self.second_screen,
                                       borderwidth=3,
                                       relief="solid",
                                       font=("Liberation Sans", 14),
                                       bg="white")
        self.control.new_game.grid(row=4,
                                   column=1,
                                   columnspan=2,
                                   sticky=N + E + S + W)

        self.control.best = Label(self.control,
                                  textvariable=self.control.best_string,
                                  borderwidth=3,
                                  relief="solid",
                                  font=("Liberation Sans", 14),
                                  bg="white")
        self.control.best.grid(row=6,
                               column=1,
                               columnspan=2,
                               sticky=N + E + S + W)

        self.control.quit = Button(self.control,
                                   text="Quit",
                                   command=self.quit,
                                   borderwidth=3,
                                   relief="solid",
                                   font=("Liberation Sans", 14),
                                   bg="white")
        self.control.quit.grid(row=8,
                               column=1,
                               columnspan=2,
                               sticky=N + E + S + W)

        self.control.grid_rowconfigure(1, minsize=100)
        self.control.grid_rowconfigure(3, minsize=50)
        self.control.grid_rowconfigure(5, minsize=50)
        self.control.grid_rowconfigure(7, minsize=50)
        self.control.grid_columnconfigure(0, minsize=35)

    def second_screen(self):
        """Game screen control"""
        self.score = 0
        self.lines = 0
        self.control = Frame(borderwidth=3, relief="solid")
        self.control.grid(row=0, column=0, sticky=N + E + S + W)

        self.control.best_string = StringVar()
        self.control.best_string.set(f"Best: {self.best}")
        self.control.score_string = StringVar()
        self.control.score_string.set(f"Score: {self.score}")
        self.control.lines_string = StringVar()
        self.control.lines_string.set(f"Lines: {self.lines}")

        header_im = PhotoImage(file="tetris.png")
        self.control.header = Label(self.control,
                                    image=header_im,
                                    borderwidth=3,
                                    relief="solid",
                                    width=400,
                                    bg="white")
        self.control.header.image = header_im
        self.control.header.grid(row=0, columnspan=3, sticky=N + E + S + W)

        self.control.canvas = CanvasGame(self.control,
                                         width=400,
                                         height=600,
                                         borderwidth=3,
                                         relief="solid",
                                         bg="white",
                                         rows=24,
                                         columns=16,
                                         cell=25)
        self.control.canvas.grid(row=1, column=0, rowspan=7)

        self.control.canvas_next = CanvasGame(self.control,
                                              width=200,
                                              height=200,
                                              borderwidth=3,
                                              relief="solid",
                                              bg="white",
                                              rows=8,
                                              columns=8,
                                              cell=25)
        self.control.canvas_next.grid(row=1,
                                      column=1,
                                      columnspan=2,
                                      sticky=N + E + S + W)

        self.control.lines = Label(self.control,
                                   textvariable=self.control.lines_string,
                                   borderwidth=3,
                                   relief="solid",
                                   font=("Liberation Sans", 14),
                                   bg="white")
        self.control.lines.grid(row=3,
                                column=1,
                                columnspan=2,
                                sticky=N + E + S + W)

        self.control.score = Label(self.control,
                                   textvariable=self.control.score_string,
                                   borderwidth=3,
                                   relief="solid",
                                   font=("Liberation Sans", 14),
                                   bg="white")
        self.control.score.grid(row=4,
                                column=1,
                                columnspan=2,
                                sticky=N + E + S + W)

        self.control.best = Label(self.control,
                                  textvariable=self.control.best_string,
                                  borderwidth=3,
                                  relief="solid",
                                  font=("Liberation Sans", 14),
                                  bg="white")
        self.control.best.grid(row=5,
                               column=1,
                               columnspan=2,
                               sticky=N + E + S + W)

        self.control.pause = Button(self.control,
                                    text="Pause",
                                    command=self.pause,
                                    borderwidth=3,
                                    relief="solid",
                                    font=("Liberation Sans", 14),
                                    bg="white")
        self.control.pause.grid(row=6, column=1, sticky=N + E + S + W)

        self.control.quit = Button(self.control,
                                   text="Quit",
                                   command=self.terminate,
                                   borderwidth=3,
                                   relief="solid",
                                   font=("Liberation Sans", 14),
                                   bg="white")
        self.control.quit.grid(row=6, column=2, sticky=N + E + S + W)

        self.control.canvas.draw()
        self.control.canvas_next.draw()
        self.next_figure = None
        self.create_figure()
        self._job = None
        self.bind_all("<Left>", self.move_left)
        self.bind_all("<Right>", self.move_right)
        self.bind_all("<Up>", self.rotate)
        self.bind_all("<Down>", self.gravity)
        self.tick()

    def tick(self):
        """Game timer"""
        flag = self.gravity()
        if flag == 0:
            return
        self.control.canvas.redraw()
        self._job = self.after(250, self.tick)

    def resume(self):
        """Resume game function"""
        self.control.pause.config(command=self.pause, text="Pause")
        self._job = self.after(250, self.tick)
        self.bind_all("<Left>", self.move_left)
        self.bind_all("<Right>", self.move_right)
        self.bind_all("<Up>", self.rotate)
        self.bind_all("<Down>", self.gravity)

    def pause(self):
        """Pause game function"""
        if self._job is not None:
            self.after_cancel(self._job)
            self._job = None

        self.unbind_all("<Left>")
        self.unbind_all("<Right>")
        self.unbind_all("<Up>")
        self.unbind_all("<Down>")

        self.control.pause.config(command=self.resume, text="Resume")

    def game_over(self):
        """Stop the game"""
        if self._job is not None:
            self.after_cancel(self._job)
            self._job = None
        self.unbind_all("<Left>")
        self.unbind_all("<Right>")
        self.unbind_all("<Up>")
        self.unbind_all("<Down>")

        self.control.pause.config(command=self.second_screen, text="Start")
        messagebox.showinfo("Info", "Game Over")

    def terminate(self):
        """Quit to start screen"""
        if self._job is not None:
            self.after_cancel(self._job)
            self._job = None
        self.first_screen()