From 2a1e9a14cd8c26611722a1779fdddc51c977694d Mon Sep 17 00:00:00 2001 From: dan63047 Date: Sun, 23 May 2021 17:16:36 +0300 Subject: [PATCH] gravity update --- .gitignore | 3 +- test.py | 71 +------- tetris-main.py | 436 +++++++++++++++++++++++++++++++++---------------- 3 files changed, 299 insertions(+), 211 deletions(-) diff --git a/.gitignore b/.gitignore index 723ef36..139597f 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -.idea \ No newline at end of file + + diff --git a/test.py b/test.py index cf68d3d..aa9fb42 100755 --- a/test.py +++ b/test.py @@ -1,68 +1,5 @@ -def speed_and_lines_for_levels(level): - if level == 0: - return 48, 10 - elif level == 1: - return 43, 20 - elif level == 2: - return 38, 30 - elif level == 3: - return 33, 40 - elif level == 4: - return 28, 50 - elif level == 5: - return 23, 60 - elif level == 6: - return 18, 70 - elif level == 7: - return 13, 80 - elif level == 8: - return 8, 90 - elif level == 9: - return 6, 100 - elif 10 <= level <= 12: - return 5, 100 - elif level == 11: - return 5, 100 - elif level == 12: - return 5, 100 - elif level == 13: - return 43, 100 - elif level == 14: - return 43, 100 - elif level == 15: - return 43, 100 - elif level == 16: - return 43, 110 - elif level == 17: - return 43, 120 - elif level == 18: - return 43, 130 - elif level == 19: - return 43, 140 - elif level == 20: - return 43, 150 - elif level == 21: - return 43, 160 - elif level == 22: - return 43, 170 - elif level == 23: - return 43, 180 - elif level == 24: - return 43, 190 - elif level == 25: - return 43, 200 - elif level == 26: - return 43, 200 - elif level == 27: - return 43, 200 - elif level == 28: - return 1, 200 - else: - return 1, 200 +def curve(lvl): + return 1/(0.8-((lvl-1)*0.007))**(lvl-1)*0.016666 - -print(speed_and_lines_for_levels(9)) -print(speed_and_lines_for_levels(10)) -print(speed_and_lines_for_levels(11)) -print(speed_and_lines_for_levels(12)) -print(speed_and_lines_for_levels(13)) +for i in range(0, 30): + print(i, curve(i)) \ No newline at end of file diff --git a/tetris-main.py b/tetris-main.py index 987ab19..d8cf9f3 100755 --- a/tetris-main.py +++ b/tetris-main.py @@ -6,7 +6,7 @@ from string import Template BLOCK_SIZE = 30 FIELD_SIZE_X = 10 FIELD_SIZE_Y = 20 -GUIDELINES = ["NES like", "Current"] +GUIDELINES = ["Current", "NES like"] class Block: @@ -195,6 +195,7 @@ TETROMINOS = [ class DeltaTemplate(Template): delimiter = "%" + def strfdelta(tdelta, fmt): d = {"D": tdelta.days} hours, rem = divmod(tdelta.seconds, 3600) @@ -211,55 +212,6 @@ def strfdelta(tdelta, fmt): return t.substitute(**d) -def speed_and_lines_for_levels(level): - if level == 0: - return 48, 10 - elif level == 1: - return 43, 20 - elif level == 2: - return 38, 30 - elif level == 3: - return 33, 40 - elif level == 4: - return 28, 50 - elif level == 5: - return 23, 60 - elif level == 6: - return 18, 70 - elif level == 7: - return 13, 80 - elif level == 8: - return 8, 90 - elif level == 9: - return 6, 100 - elif 10 <= level <= 12: - return 5, 100 - elif 13 <= level <= 15: - return 4, 100 - elif level == 16: - return 3, 110 - elif level == 17: - return 3, 120 - elif level == 18: - return 3, 130 - elif level == 19: - return 2, 140 - elif level == 20: - return 2, 150 - elif level == 21: - return 2, 160 - elif level == 22: - return 2, 170 - elif level == 23: - return 2, 180 - elif level == 24: - return 2, 190 - elif 25 <= level <= 28: - return 2, 200 - else: - return 1, 200 - - class TetrisGameplay: def __init__(self, size_x=FIELD_SIZE_X, size_y=FIELD_SIZE_Y, level=0, buffer_zone=20, srs=True, lock_delay=True, seven_bag=True, ghost_piece=True, hold=True, hard_drop=True, handling=(167, 33), nes_mechanics=False, next_len=3): self.buffer_y = buffer_zone @@ -335,9 +287,9 @@ class TetrisGameplay: self.pieces[self.current_id] += 1 self.lock_delay_run = False self.lock_delay_frames = 30 - self.lines_for_level_up = speed_and_lines_for_levels(level)[1] - self.start_level = level self.level = level + self.lines_for_level_up = self.gravity_and_lines_table()[1] + self.start_level = level self.game_over = False def spawn_tetromino(self): @@ -378,6 +330,9 @@ class TetrisGameplay: def __str__(self): return f"size_x={len(self.FIELD[0])}, size_y={len(self.FIELD)}, buffer_y: {self.buffer_y}" + def gravity_and_lines_table(self): + return 1 / (0.8 - ((self.level - 1) * 0.007)) ** (self.level - 1) * 0.016666, self.level * 10 + 10 + def clear_lines(self): cleared = 0 frames_delay = 0 @@ -699,7 +654,7 @@ class TetrisGameplay: self.lock_delay_frames = 30 self.lock_delay_run = False - def move_down(self, by_player=False, instant=False): + def move_down(self, instant=False): if not self.collision(self.current_posx, self.current_posy + 1, self.current_id, self.current_spin_id): if instant: add_to_score = 0 @@ -712,8 +667,6 @@ class TetrisGameplay: else: self.current_posy += 1 self.spin_is_last_move = False - if by_player: - self.score[0] += 1 return True else: return False @@ -798,6 +751,265 @@ class TetrisGameplay: win.blit(FONT.render("LINES", 1, (255, 255, 255)), (5 + BLOCK_SIZE * FIELD_SIZE_X + 20 + BLOCK_SIZE * k1, 90 + BLOCK_SIZE * 7)) total_lines = sum(self.cleared_lines) + win.blit(FONT.render(f"{total_lines:03d}", 1, (255, 255, 255)), + (5 + BLOCK_SIZE * FIELD_SIZE_X + 20 + BLOCK_SIZE * k1, 115 + BLOCK_SIZE * 7)) + win.blit(FONT.render("LV", 1, (255, 255, 255)), + (5 + BLOCK_SIZE * FIELD_SIZE_X + 20 + BLOCK_SIZE * k1, 155 + BLOCK_SIZE * 7)) + win.blit(FONT.render(f"{self.level:02d}", 1, (255, 255, 255)), + (5 + BLOCK_SIZE * FIELD_SIZE_X + 20 + BLOCK_SIZE * k1, 180 + BLOCK_SIZE * 7)) + try: + pps = sum(self.pieces) / self.game_time + except ZeroDivisionError: + pps = 0 + win.blit(FONT.render("PPS", 1, (255, 255, 255)), + (5 + BLOCK_SIZE * FIELD_SIZE_X + 120 + BLOCK_SIZE * k1, 155 + BLOCK_SIZE * 7)) + if pps >= 1: + win.blit(FONT.render(f"{pps:1.1f}", 1, (255, 255, 255)), + (5 + BLOCK_SIZE * FIELD_SIZE_X + 120 + BLOCK_SIZE * k1, 180 + BLOCK_SIZE * 7)) + else: + win.blit(FONT.render(f".{int(pps*100):02d}", 1, (255, 255, 255)), + (5 + BLOCK_SIZE * FIELD_SIZE_X + 120 + BLOCK_SIZE * k1, 180 + BLOCK_SIZE * 7)) + win.blit(FONT.render("TIME", 1, (255, 255, 255)), + (5 + BLOCK_SIZE * FIELD_SIZE_X + 20 + BLOCK_SIZE * k1, 220 + BLOCK_SIZE * 7)) + if self.game_time < 10: + win.blit(FONT.render(strfdelta(datetime.timedelta(seconds=self.game_time), '%s.%Z'), 1, (255, 255, 255)), + (5 + BLOCK_SIZE * FIELD_SIZE_X + 20 + BLOCK_SIZE * k1, 245 + BLOCK_SIZE * 7)) + elif self.game_time < 60: + win.blit(FONT.render(strfdelta(datetime.timedelta(seconds=self.game_time), '%S.%z'), 1, (255, 255, 255)), + (5 + BLOCK_SIZE * FIELD_SIZE_X + 20 + BLOCK_SIZE * k1, 245 + BLOCK_SIZE * 7)) + elif self.game_time < 3600: + win.blit(FONT.render(strfdelta(datetime.timedelta(seconds=self.game_time), '%m:%S'), 1, (255, 255, 255)), + (5 + BLOCK_SIZE * FIELD_SIZE_X + 20 + BLOCK_SIZE * k1, 245 + BLOCK_SIZE * 7)) + else: + win.blit(FONT.render(strfdelta(datetime.timedelta(seconds=self.game_time), '%H:%M:%S'), 1, (255, 255, 255)), + (5 + BLOCK_SIZE * FIELD_SIZE_X + 20 + BLOCK_SIZE * k1, 245 + BLOCK_SIZE * 7)) + if self.game_over: + text_size_x = FONT.size("GAME")[0] + pygame.draw.rect(win, (0, 0, 0), ( + BLOCK_SIZE * (FIELD_SIZE_X / 2) - text_size_x, BLOCK_SIZE * FIELD_SIZE_Y / 2, text_size_x * 2 + 10, 60)) + win.blit(FONT.render("GAME", 1, (255, 255, 255)), + (5 + BLOCK_SIZE * FIELD_SIZE_X / 2 - text_size_x / 2, 5 + BLOCK_SIZE * FIELD_SIZE_Y / 2)) + win.blit(FONT.render("OVER", 1, (255, 255, 255)), + (5 + BLOCK_SIZE * FIELD_SIZE_X / 2 - text_size_x / 2, 5 + BLOCK_SIZE * FIELD_SIZE_Y / 2 + 25)) + pygame.display.update() + + def draw_game_stats(self, on_pause): + win.fill((25, 25, 25)) + if on_pause: + win.blit(FONT.render("GAME PAUSED", 1, (255, 255, 255)), (25, 25)) + else: + win.blit(FONT.render("STATISTIC", 1, (255, 255, 255)), (25, 25)) + total_score = sum(self.score) + win.blit(FONT.render(f"SCORE {total_score:16d}", 1, (255, 255, 255)), (25, 100)) + total_pieces = sum(self.pieces) + win.blit(FONT.render(f"PIECES {total_pieces:15d}", 1, (255, 255, 255)), (25, 130)) + total_lines = sum(self.cleared_lines) + win.blit(FONT.render(f"LINES {total_lines:16d}", 1, (255, 255, 255)), (25, 160)) + try: + pps = total_pieces / self.game_time + except ZeroDivisionError: + pps = 0 + win.blit(FONT.render(f"PIECES PER SECOND {pps:0.2f}", 1, (255, 255, 255)), (25, 190)) + win.blit(FONT.render(f"LEVELS {self.start_level:02d}-{self.level:02d}", 1, (255, 255, 255)), (25, 220)) + win.blit( + FONT.render(f"TIME {strfdelta(datetime.timedelta(seconds=self.game_time), '%H:%M:%S.%Z'):>17s}", 1, (255, 255, 255)), + (25, 250)) + win.blit(SMALL_FONT.render(f"BURNED TIMES LINES PIECES TABLE", 1, (255, 255, 255)), (25, 290)) + win.blit( + SMALL_FONT.render(f"SINGLE {self.cleared_lines[0]:5d} {self.cleared_lines[0]:5d} L {self.pieces[0]:<4d} J {self.pieces[1]:<4d}", 1, (255, 255, 255)), + (25, 310)) + double_times = int(self.cleared_lines[1] / 2) + win.blit(SMALL_FONT.render(f"DOUBLE {double_times:5d} {self.cleared_lines[1]:5d} S {self.pieces[2]:<4d} Z {self.pieces[3]:<4d}", 1, (255, 255, 255)), + (25, 325)) + triple_times = int(self.cleared_lines[2] / 3) + win.blit(SMALL_FONT.render(f"TRIPLE {triple_times:5d} {self.cleared_lines[2]:5d} T {self.pieces[4]:<4d} O {self.pieces[6]:<4d}", 1, (255, 255, 255)), + (25, 340)) + tetris_times = int(self.cleared_lines[3] / 4) + win.blit(SMALL_FONT.render(f"TETRIS {tetris_times:5d} {self.cleared_lines[3]:5d} I {self.pieces[5]:<10d}", 1, (255, 255, 255)), + (25, 355)) + win.blit(SMALL_FONT.render(f"SCORE TABLE", 1, (255, 255, 255)), (25, 380)) + win.blit(SMALL_FONT.render(f"SOFT DROPS {self.score[0]:14d}", 1, (255, 255, 255)), (25, 400)) + win.blit(SMALL_FONT.render(f"HARD DROPS {self.score[1]:14d}", 1, (255, 255, 255)), (25, 415)) + win.blit(SMALL_FONT.render(f"SINGLE {self.score[2]:18d}", 1, (255, 255, 255)), (25, 430)) + win.blit(SMALL_FONT.render(f"DOUBLE {self.score[3]:18d}", 1, (255, 255, 255)), (25, 445)) + win.blit(SMALL_FONT.render(f"TRIPLE {self.score[4]:18d}", 1, (255, 255, 255)), (25, 460)) + win.blit(SMALL_FONT.render(f"TETRIS {self.score[5]:18d}", 1, (255, 255, 255)), (25, 475)) + win.blit(SMALL_FONT.render(f"T-SPIN MINI NO L. {self.score[6]:7d}", 1, (255, 255, 255)), (25, 490)) + win.blit(SMALL_FONT.render(f"T-SPIN MINI SINGLE {self.score[7]:6d}", 1, (255, 255, 255)), (25, 505)) + win.blit(SMALL_FONT.render(f"T-SPIN MINI DOUBLE {self.score[8]:6d}", 1, (255, 255, 255)), (25, 520)) + win.blit(SMALL_FONT.render(f"T-SPIN NO LINES {self.score[9]:9d}", 1, (255, 255, 255)), (25, 535)) + win.blit(SMALL_FONT.render(f"T-SPIN SINGLE {self.score[10]:11d}", 1, (255, 255, 255)), (25, 550)) + win.blit(SMALL_FONT.render(f"T-SPIN DOUBLE {self.score[11]:11d}", 1, (255, 255, 255)), (25, 565)) + win.blit(SMALL_FONT.render(f"T-SPIN TRIPLE {self.score[12]:11d}", 1, (255, 255, 255)), (25, 580)) + win.blit(SMALL_FONT.render(f"COMBO BONUS {self.score[13]:13d}", 1, (255, 255, 255)), (25, 595)) + win.blit(SMALL_FONT.render(f"BACK-TO-BACK BONUS {self.score[14]:6d}", 1, (255, 255, 255)), (25, 610)) + pygame.display.update() + + +class NesLikeTetris(TetrisGameplay): + def __init__(self, size_x=FIELD_SIZE_X, size_y=FIELD_SIZE_Y, level=0): + super().__init__(size_x, size_y, level, 2, False, False, False, False, False, False, (267, 100), True, 1) + + def __str__(self): + ans = f"size_x={len(self.FIELD[0])}, size_y={len(self.FIELD)}, Field:" + for i in self.FIELD: + ans += f"\n{i}" + return ans + + def gravity_and_lines_table(self): + if self.level == 0: + return 1/48, 10 + elif self.level == 1: + return 1/43, 20 + elif self.level == 2: + return 1/38, 30 + elif self.level == 3: + return 1/33, 40 + elif self.level == 4: + return 1/28, 50 + elif self.level == 5: + return 1/23, 60 + elif self.level == 6: + return 1/18, 70 + elif self.level == 7: + return 1/13, 80 + elif self.level == 8: + return 1/8, 90 + elif self.level == 9: + return 1/6, 100 + elif 10 <= self.level <= 12: + return 1/5, 100 + elif 13 <= self.level <= 15: + return 1/4, 100 + elif self.level == 16: + return 1/3, 110 + elif self.level == 17: + return 1/3, 120 + elif self.level == 18: + return 1/3, 130 + elif self.level == 19: + return 1/2, 140 + elif self.level == 20: + return 1/2, 150 + elif self.level == 21: + return 1/2, 160 + elif self.level == 22: + return 1/2, 170 + elif self.level == 23: + return 1/2, 180 + elif self.level == 24: + return 1/2, 190 + elif 25 <= self.level <= 28: + return 1/2, 200 + else: + return 1, 200 + + def clear_lines(self): + cleared = 0 + frames_delay = 0 + height = None + y = len(self.FIELD) + for i in self.FIELD: + ic = 0 + for k in i: + if k is not None: + ic += 1 + if ic == FIELD_SIZE_X: + cleared += 1 + self.FIELD.remove(i) + new = list(range(FIELD_SIZE_X)) + x = 0 + while x != FIELD_SIZE_X: + new[x] = None + x += 1 + self.FIELD.insert(0, new) + y -= 1 + if ic > 0 and height is None: + height = y + frames_delay += 10 + (2 * int(height / 4)) + + if cleared >= 0: + self.cleared_lines[cleared - 1] += cleared + frames_delay += 18 + if cleared == 1: + self.score[2] += 40 * (min(self.level, 29) + 1) + elif cleared == 2: + self.score[3] += 100 * (min(self.level, 29) + 1) + elif cleared == 3: + self.score[4] += 300 * (min(self.level, 29) + 1) + elif cleared == 4: + self.score[5] += 1200 * (min(self.level, 29) + 1) + if sum(self.cleared_lines) >= self.lines_for_level_up: + self.level += 1 + self.lines_for_level_up += 10 + return frames_delay + + def draw_game(self): + win.fill((25, 25, 25)) + pygame.draw.rect(win, (0, 0, 0), + (5, (BLOCK_SIZE * 2 + 5), BLOCK_SIZE * FIELD_SIZE_X, BLOCK_SIZE * FIELD_SIZE_Y)) + x = 0 + y = -self.buffer_y + for i in self.FIELD: + for k in i: + window_x = 5 + BLOCK_SIZE * x + window_y = (BLOCK_SIZE * 2 + 5) + BLOCK_SIZE * y + if k is not None: + pygame.draw.rect(win, k.color, (window_x, window_y, BLOCK_SIZE, BLOCK_SIZE)) + pygame.draw.rect(win, (0, 0, 0), (window_x, window_y, BLOCK_SIZE, BLOCK_SIZE), width=2) + x += 1 + x = 0 + y += 1 + i1 = self.current_posy - self.buffer_y + k1 = self.current_posx + if self.current_id is not None: + for i in TETROMINOS[self.current_id][self.current_spin_id]: + for k in i: + if k is not None: + window_x = 5 + BLOCK_SIZE * k1 + window_y = (BLOCK_SIZE * 2 + 5) + BLOCK_SIZE * i1 + pygame.draw.rect(win, (int(k.color[0]*self.lock_delay_frames/30), int(k.color[1]*self.lock_delay_frames/30), int(k.color[2]*self.lock_delay_frames/30)), (window_x, window_y, BLOCK_SIZE, BLOCK_SIZE)) + pygame.draw.rect(win, (0, 0, 0), (window_x, window_y, BLOCK_SIZE, BLOCK_SIZE), width=2) + k1 += 1 + k1 = self.current_posx + i1 += 1 + x_offset = 0 + for q in range(0, self.next_length): + i1 = 0 + k1 = 0 + for i in TETROMINOS[self.next_queue[q]][0]: + for k in i: + if k is not None: + window_x = 5 + BLOCK_SIZE * FIELD_SIZE_X + 20 + BLOCK_SIZE * k1 + x_offset + window_y = (BLOCK_SIZE * 2 + 30) + BLOCK_SIZE * i1 + pygame.draw.rect(win, k.color, (window_x, window_y, BLOCK_SIZE, BLOCK_SIZE)) + pygame.draw.rect(win, (0, 0, 0), (window_x, window_y, BLOCK_SIZE, BLOCK_SIZE), width=1) + k1 += 1 + k1 = 0 + i1 += 1 + x_offset += 45 + if self.support_hold: + if self.hold_id is not None: + i1 = 0 + k1 = 0 + for i in TETROMINOS[self.hold_id][0]: + for k in i: + if k is not None: + window_x = 5 + BLOCK_SIZE * FIELD_SIZE_X + 20 + 10 * k1 + window_y = (BLOCK_SIZE * 2 + 75) + 10 * i1 + pygame.draw.rect(win, k.color, (window_x, window_y, 10, 10)) + pygame.draw.rect(win, (0, 0, 0), (window_x, window_y, 10, 10), width=1) + k1 += 1 + k1 = 0 + i1 += 1 + win.blit(FONT.render("SCORE", 1, (255, 255, 255)), + (5 + BLOCK_SIZE * FIELD_SIZE_X + 20 + BLOCK_SIZE * k1, 25 + BLOCK_SIZE * 7)) + total_score = sum(self.score) + win.blit(FONT.render(f"{total_score:06d}", 1, (255, 255, 255)), + (5 + BLOCK_SIZE * FIELD_SIZE_X + 20 + BLOCK_SIZE * k1, 50 + BLOCK_SIZE * 7)) + win.blit(FONT.render("LINES", 1, (255, 255, 255)), + (5 + BLOCK_SIZE * FIELD_SIZE_X + 20 + BLOCK_SIZE * k1, 90 + BLOCK_SIZE * 7)) + total_lines = sum(self.cleared_lines) win.blit(FONT.render(f"{total_lines:03d}", 1, (255, 255, 255)), (5 + BLOCK_SIZE * FIELD_SIZE_X + 20 + BLOCK_SIZE * k1, 115 + BLOCK_SIZE * 7)) win.blit(FONT.render("LV", 1, (255, 255, 255)), @@ -875,76 +1087,14 @@ class TetrisGameplay: win.blit(SMALL_FONT.render(f"TETRIS {tetris_times:5d} {self.cleared_lines[3]:5d} I {self.pieces[5]:<10d}", 1, (255, 255, 255)), (25, 355)) win.blit(SMALL_FONT.render(f"SCORE TABLE", 1, (255, 255, 255)), (25, 380)) - win.blit(SMALL_FONT.render(f"SOFT DROPS {self.score[0]:14d}", 1, (255, 255, 255)), (25, 400)) - win.blit(SMALL_FONT.render(f"HARD DROPS {self.score[1]:14d}", 1, (255, 255, 255)), (25, 415)) - win.blit(SMALL_FONT.render(f"SINGLE {self.score[2]:18d}", 1, (255, 255, 255)), (25, 430)) - win.blit(SMALL_FONT.render(f"DOUBLE {self.score[3]:18d}", 1, (255, 255, 255)), (25, 445)) - win.blit(SMALL_FONT.render(f"TRIPLE {self.score[4]:18d}", 1, (255, 255, 255)), (25, 460)) - win.blit(SMALL_FONT.render(f"TETRIS {self.score[5]:18d}", 1, (255, 255, 255)), (25, 475)) - win.blit(SMALL_FONT.render(f"T-SPIN MINI NO L. {self.score[6]:7d}", 1, (255, 255, 255)), (25, 490)) - win.blit(SMALL_FONT.render(f"T-SPIN MINI SINGLE {self.score[7]:6d}", 1, (255, 255, 255)), (25, 505)) - win.blit(SMALL_FONT.render(f"T-SPIN MINI DOUBLE {self.score[8]:6d}", 1, (255, 255, 255)), (25, 520)) - win.blit(SMALL_FONT.render(f"T-SPIN NO LINES {self.score[9]:9d}", 1, (255, 255, 255)), (25, 535)) - win.blit(SMALL_FONT.render(f"T-SPIN SINGLE {self.score[10]:11d}", 1, (255, 255, 255)), (25, 550)) - win.blit(SMALL_FONT.render(f"T-SPIN DOUBLE {self.score[11]:11d}", 1, (255, 255, 255)), (25, 565)) - win.blit(SMALL_FONT.render(f"T-SPIN TRIPLE {self.score[12]:11d}", 1, (255, 255, 255)), (25, 580)) - win.blit(SMALL_FONT.render(f"COMBO BONUS {self.score[13]:13d}", 1, (255, 255, 255)), (25, 595)) - win.blit(SMALL_FONT.render(f"BACK-TO-BACK BONUS {self.score[14]:6d}", 1, (255, 255, 255)), (25, 610)) + win.blit(SMALL_FONT.render(f"DROPS {self.score[0]:7d}", 1, (255, 255, 255)), (25, 400)) + win.blit(SMALL_FONT.render(f"SINGLE {self.score[2]:6d}", 1, (255, 255, 255)), (25, 415)) + win.blit(SMALL_FONT.render(f"DOUBLE {self.score[3]:6d}", 1, (255, 255, 255)), (25, 430)) + win.blit(SMALL_FONT.render(f"TRIPLE {self.score[4]:6d}", 1, (255, 255, 255)), (25, 445)) + win.blit(SMALL_FONT.render(f"TETRIS {self.score[5]:6d}", 1, (255, 255, 255)), (25, 460)) pygame.display.update() - -class NesLikeTetris(TetrisGameplay): - def __init__(self, size_x=FIELD_SIZE_X, size_y=FIELD_SIZE_Y, level=0): - super().__init__(size_x, size_y, level, 2, False, False, False, False, False, False, (267, 100), True, 1) - - def __str__(self): - ans = f"size_x={len(self.FIELD[0])}, size_y={len(self.FIELD)}, Field:" - for i in self.FIELD: - ans += f"\n{i}" - return ans - - def clear_lines(self): - cleared = 0 - frames_delay = 0 - height = None - y = len(self.FIELD) - for i in self.FIELD: - ic = 0 - for k in i: - if k is not None: - ic += 1 - if ic == FIELD_SIZE_X: - cleared += 1 - self.FIELD.remove(i) - new = list(range(FIELD_SIZE_X)) - x = 0 - while x != FIELD_SIZE_X: - new[x] = None - x += 1 - self.FIELD.insert(0, new) - y -= 1 - if ic > 0 and height is None: - height = y - frames_delay += 10 + (2 * int(height / 4)) - - if cleared >= 0: - self.cleared_lines[cleared - 1] += cleared - frames_delay += 18 - if cleared == 1: - self.score[2] += 40 * (min(self.level, 29) + 1) - elif cleared == 2: - self.score[3] += 100 * (min(self.level, 29) + 1) - elif cleared == 3: - self.score[4] += 300 * (min(self.level, 29) + 1) - elif cleared == 4: - self.score[5] += 1200 * (min(self.level, 29) + 1) - if sum(self.cleared_lines) >= self.lines_for_level_up: - self.level += 1 - self.lines_for_level_up += 10 - return frames_delay - - def draw_main_menu(selected, sel_lvl, sel_gl): win.fill((25, 25, 25)) win.blit(FONT.render("TETRIS by dan63047", 1, (255, 255, 255)), (25, 25)) @@ -960,7 +1110,7 @@ def main(): selected_level = 0 selected_gl = 0 ticks_before_stats = 180 - ticks_gone = 0 + g = 0 menu_select = 0 on_pause = False corrupt_hard_drop = False @@ -1000,36 +1150,36 @@ def main(): elif state == "pregameplay": ticks_before_stats = 300 if selected_gl == 0: - field = NesLikeTetris(level=selected_level) - elif selected_gl == 1: field = TetrisGameplay(level=selected_level) + elif selected_gl == 1: + field = NesLikeTetris(level=selected_level) pygame.key.set_repeat(field.handling[0], field.handling[1]) state = "gameplay" elif state == "gameplay": field.draw_game() - ticks_for_down = speed_and_lines_for_levels(field.level)[0] if not field.game_over: - if pygame.K_r in pressed_keys and ticks_gone >= 0: + if pygame.K_r in pressed_keys: state = "pregameplay" - if pygame.K_p in pressed_keys and ticks_gone >= 0: + if pygame.K_p in pressed_keys: on_pause = True state = "gameplay_stats" - if (pygame.K_UP in pressed_keys or pygame.K_x in pressed_keys) and ticks_gone >= 0: + if pygame.K_UP in pressed_keys or pygame.K_x in pressed_keys: field.spin() - if pygame.K_z in pressed_keys and ticks_gone >= 0: + if pygame.K_z in pressed_keys: field.spin(True) - if pygame.K_c in pressed_keys and ticks_gone >= 0 and field.support_hold and not field.hold_locked: + if pygame.K_c in pressed_keys and field.support_hold and not field.hold_locked: field.hold_tetromino() - if pygame.K_DOWN in pressed_keys and ticks_gone >= 0: - ticks_gone -= field.move_down(True) - if pygame.K_LEFT in pressed_keys and ticks_gone >= 0: + if pygame.K_DOWN in pressed_keys: + g += 1 + field.score[0] += 1 + if pygame.K_LEFT in pressed_keys: field.move_side(-1) - if pygame.K_RIGHT in pressed_keys and ticks_gone >= 0: + if pygame.K_RIGHT in pressed_keys: field.move_side(1) if pygame.K_SPACE in pressed_keys and not corrupt_hard_drop and field.can_hard_drop: - field.move_down(True, True) + field.move_down(True) field.save_state() - ticks_gone -= field.clear_lines() + field.clear_lines() field.spawn_tetromino() field.lock_delay_run = False field.lock_delay_frames = 30 @@ -1037,23 +1187,23 @@ def main(): field.game_time += clock.get_time()/1000 if field.game_over: ticks_before_stats -= 1 - ticks_gone += 1 - if ticks_gone >= ticks_for_down: - ticks_gone = 0 - if not field.game_over: + if not field.game_over: + g += field.gravity_and_lines_table()[0] + while g >= 1: if field.support_lock_delay: if not field.move_down(): field.lock_delay_run = True else: if not field.move_down(): field.save_state() - ticks_gone -= field.clear_lines() + ticks_gone = -field.clear_lines() field.spawn_tetromino() + g -= 1 if field.lock_delay_run: field.lock_delay_frames -= 1 if field.lock_delay_frames <= 0 or not field.support_lock_delay: field.save_state() - ticks_gone -= field.clear_lines() + field.clear_lines() field.spawn_tetromino() field.reset_lock_delay() if ticks_before_stats <= 0: