Advertisement
EdmundC

Untitled

Jul 25th, 2024 (edited)
39
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.37 KB | None | 0 0
  1. import curses
  2. import random
  3. import time
  4.  
  5. # Tetrimino shapes
  6. SHAPES = [
  7.     [[1, 1, 1, 1]],  # I
  8.     [[1, 1], [1, 1]],  # O
  9.     [[0, 1, 0], [1, 1, 1]],  # T
  10.     [[1, 0, 0], [1, 1, 1]],  # L
  11.     [[0, 0, 1], [1, 1, 1]],  # J
  12.     [[0, 1, 1], [1, 1, 0]],  # S
  13.     [[1, 1, 0], [0, 1, 1]]   # Z
  14. ]
  15.  
  16. PIECE_NAMES = ["I", "O", "T", "L", "J", "S", "Z"]
  17.  
  18. class Tetris:
  19.     def __init__(self, screen):
  20.         self.screen = screen
  21.         self.screen.nodelay(1)
  22.         self.screen.timeout(500)
  23.         curses.curs_set(0)
  24.        
  25.         self.width = 10
  26.         self.height = 20
  27.         self.board = [[0] * self.width for _ in range(self.height)]
  28.         self.current_piece = None
  29.         self.current_x = 0
  30.         self.current_y = 0
  31.         self.next_piece = None
  32.         self.score = 0
  33.         self.placed_pieces = []
  34.         self.layout_width = 8  # Width of the layout area for pieces
  35.         self.layout_height = 16  # Height of the layout area for pieces
  36.         self.layout_bottom = self.height - self.layout_height
  37.         self.new_piece()
  38.         self.last_time = time.time()
  39.         self.fall_speed = 0.5  # Speed of automatic fall in seconds
  40.  
  41.     def new_piece(self):
  42.         if self.next_piece is None:
  43.             self.current_piece = random.choice(SHAPES)
  44.         else:
  45.             self.current_piece = self.next_piece
  46.         self.next_piece = random.choice(SHAPES)
  47.         self.current_x = (self.width - self.layout_width) // 2 + len(self.current_piece[0]) // 2
  48.         self.current_y = -len(self.current_piece)  # Start above the screen
  49.         if self.check_collision(self.current_x, self.current_y, self.current_piece):
  50.             self.end_game()
  51.  
  52.     def rotate_piece(self):
  53.         self.current_piece = [list(row) for row in zip(*self.current_piece[::-1])]
  54.         if self.check_collision(self.current_x, self.current_y, self.current_piece):
  55.             # If rotation causes collision, revert rotation
  56.             self.current_piece = [list(row) for row in zip(*self.current_piece[::-1])][::-1]
  57.  
  58.     def check_collision(self, x, y, piece):
  59.         for i, row in enumerate(piece):
  60.             for j, cell in enumerate(row):
  61.                 if cell and (y + i >= self.height or x + j < 0 or x + j >= self.width or self.board[y + i][x + j]):
  62.                     return True
  63.         return False
  64.  
  65.     def fix_piece(self):
  66.         for i, row in enumerate(self.current_piece):
  67.             for j, cell in enumerate(row):
  68.                 if cell:
  69.                     self.board[self.current_y + i][self.current_x + j] = 1
  70.         piece_name = PIECE_NAMES[SHAPES.index(self.current_piece)]
  71.         self.placed_pieces.append(piece_name)
  72.         self.clear_lines()
  73.         self.new_piece()
  74.  
  75.     def clear_lines(self):
  76.         new_board = [row for row in self.board if any(cell == 0 for cell in row)]
  77.         lines_cleared = self.height - len(new_board)
  78.         if lines_cleared == 1:
  79.             self.score += 1
  80.         elif lines_cleared == 2:
  81.             self.score += 2
  82.         elif lines_cleared == 3:
  83.             self.score += 3
  84.         elif lines_cleared == 4:
  85.             self.score += 4
  86.         while len(new_board) < self.height:
  87.             new_board.insert(0, [0] * self.width)
  88.         self.board = new_board
  89.  
  90.     def move(self, dx, dy):
  91.         if not self.check_collision(self.current_x + dx, self.current_y + dy, self.current_piece):
  92.             self.current_x += dx
  93.             self.current_y += dy
  94.  
  95.     def drop(self):
  96.         if not self.check_collision(self.current_x, self.current_y + 1, self.current_piece):
  97.             self.current_y += 1
  98.         else:
  99.             self.current_y = self.layout_bottom + self.layout_height - len(self.current_piece)  # Stop at the bottom of the layout
  100.             self.fix_piece()
  101.  
  102.     def end_game(self):
  103.         self.screen.addstr(self.height // 2, self.width // 2 - 5, "Game Over!")
  104.         self.screen.refresh()
  105.         time.sleep(2)
  106.         curses.endwin()
  107.         exit(0)
  108.  
  109.     def draw(self):
  110.         self.screen.clear()
  111.        
  112.         # Calculate the start position for centering
  113.         max_y, max_x = self.screen.getmaxyx()
  114.         start_y = max_y // 2 - 12
  115.         start_x = max_x // 2 - 16
  116.  
  117.         # Draw the border and the layout
  118.         layout = [
  119.             " ┌───────────────┬──────┐ ",
  120.             " │SCORE:^^^^^^^^^│ NEXT │ ",
  121.             " ├───────────────┤      │ ",
  122.             " │               │ ~~~~ │ ",
  123.             " │               │ ~~~~ │ ",
  124.             " │               ├──────┤ ",
  125.             " │               │$$$$$$│ ",
  126.             " │               │$$$$$$│ ",
  127.             " │               │$$$$$$│ ",
  128.             " │               │$$$$$$│ ",
  129.             " │               │$$$$$$│ ",
  130.             " │               │$$$$$$│ ",
  131.             " │               │$$$$$$│ ",
  132.             " │               │$$$$$$│ ",
  133.             " │               │$$$$$$│ ",
  134.             " │               │$$$$$$│ ",
  135.             " │               │$$$$$$│ ",
  136.             " └───────────────┴──────┘ "
  137.         ]
  138.        
  139.         for i, line in enumerate(layout):
  140.             self.screen.addstr(start_y + i, start_x, line)
  141.        
  142.         # Draw the score
  143.         score_str = f"{self.score:^9}"
  144.         self.screen.addstr(start_y + 1, start_x + 8, score_str)
  145.        
  146.         # Draw the next piece
  147.         next_piece = self.next_piece
  148.         for i, row in enumerate(next_piece):
  149.             for j, cell in enumerate(row):
  150.                 if cell:
  151.                     self.screen.addstr(start_y + 4 + i, start_x + 19 + j, "X")
  152.        
  153.         # Draw the placed pieces names
  154.         for i, piece_name in enumerate(self.placed_pieces[-10:]):
  155.             self.screen.addstr(start_y + 7 + i, start_x + 19, piece_name)
  156.        
  157.         # Draw the board and current piece
  158.         for y, row in enumerate(self.board):
  159.             for x, cell in enumerate(row):
  160.                 if cell:
  161.                     if start_y + 6 + y < max_y and start_x + x < max_x:
  162.                         self.screen.addstr(start_y + 6 + y, start_x + x, "X")
  163.        
  164.         for i, row in enumerate(self.current_piece):
  165.             for j, cell in enumerate(row):
  166.                 if cell:
  167.                     draw_y = start_y + 6 + self.current_y + i
  168.                     draw_x = start_x + self.current_x + j
  169.                     if draw_y < max_y and draw_x < max_x and draw_y >= start_y and draw_x >= start_x:
  170.                         self.screen.addstr(draw_y, draw_x, "X")
  171.        
  172.         self.screen.refresh()
  173.  
  174.     def run(self):
  175.         while True:
  176.             current_time = time.time()
  177.             if current_time - self.last_time > self.fall_speed:
  178.                 self.drop()
  179.                 self.last_time = current_time
  180.  
  181.             self.draw()
  182.             event = self.screen.getch()
  183.             if event == curses.KEY_LEFT:
  184.                 self.move(-1, 0)
  185.             elif event == curses.KEY_RIGHT:
  186.                 self.move(1, 0)
  187.             elif event == curses.KEY_DOWN:
  188.                 self.drop()
  189.             elif event == curses.KEY_UP:
  190.                 self.rotate_piece()
  191.  
  192. def main(stdscr):
  193.     game = Tetris(stdscr)
  194.     game.run()
  195.  
  196. curses.wrapper(main)
  197.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement