summaryrefslogtreecommitdiff
path: root/cameltris/screens/in_game.py
diff options
context:
space:
mode:
Diffstat (limited to 'cameltris/screens/in_game.py')
-rw-r--r--cameltris/screens/in_game.py221
1 files changed, 6 insertions, 215 deletions
diff --git a/cameltris/screens/in_game.py b/cameltris/screens/in_game.py
index 46450aa..bed8643 100644
--- a/cameltris/screens/in_game.py
+++ b/cameltris/screens/in_game.py
@@ -1,229 +1,17 @@
import contextlib
from functools import partial
-import random
import sys
-from typing import Callable, NoReturn, Optional
+from typing import Callable, NoReturn
import pygame
from ..color import Color
+from ..controller import Input, KeyboardController, JoystickController
from .base_screen import Screen
-from ..piece import *
-from ..playfield import PlayField
-from ..controller import Input, Controller, KeyboardController, JoystickController
+from ..player import Player, WouldCollide
from ..misc import Pause
-class WouldCollide(Exception):
- pass
-
-
-class PlayerQuit(Exception):
- pass
-
-right_pane_canvas = pygame.Surface((300, 1000))
-right_pane_canvas.fill((255, 255, 255))
-
-class Player:
- def __init__(self, controller: Controller, starting_level: int):
- self.controller = controller
- self.playfield = PlayField()
-
- self.current_piece, self.current_piece_position = self.generate_piece()
- self.next_piece, self.next_piece_position = self.generate_piece()
-
- self.level = self.starting_level = starting_level
- self.score = 0
-
- self.lines_burnt = 0
-
- self.das = 0
- self.pressing_down_countdown: Optional[int] = None
-
- self.piece_drop_frames = 0
-
- self.grid_canvas = pygame.Surface((500, 1000))
- self.piece_preview_canvas = pygame.Surface((200, 200))
- self.score_canvas = pygame.Surface((296, 50))
- self.level_canvas = pygame.Surface((296, 50))
-
- def generate_piece(self) -> tuple[Piece, list[int]]:
- # We may want to make this a function outside the class
- piece = random.choice((TPiece, SPiece, IPiece, ZPiece, SquarePiece, LPiece, JPiece))()
-
- for row_id, row in enumerate(piece.elements):
- if list(filter(lambda x: x is not None, row)):
- break
-
- initial_y_position = -row_id
- initial_x_position = (len(self.playfield.grid[0]) // 2) - (len(piece.elements[0]) // 2)
-
- return (piece, [initial_y_position, initial_x_position])
-
- def lock_piece(self) -> None:
- if self.has_collision(self.current_piece_position[0], self.current_piece_position[1]):
- raise WouldCollide()
-
- for row_id, row in enumerate(self.current_piece.elements):
- for col_id, element in enumerate(row):
- if element is None:
- continue
- self.playfield.grid[row_id + self.current_piece_position[0]][col_id + self.current_piece_position[1]] = element
-
- count = self.playfield.burn_rows()
-
- if count == 1:
- print("Single")
- rate = 1.
- elif count == 2:
- print("Double")
- rate = 2.5
- elif count == 3:
- print("Triple")
- rate = 7.5
- elif count == 4:
- print("Tetris!")
- rate = 30.
- else:
- rate = 0.
-
- self.lines_burnt += count
-
- self.score += int(self.level * 40 * rate)
-
- if self.lines_burnt >= self.level * 10:
- self.level += 1
- self.current_piece, self.current_piece_position = self.next_piece, self.next_piece_position
- self.next_piece, self.next_piece_position = self.generate_piece()
- self.refresh_piece_preview_canvas()
-
- def has_collision(self, y: int, x: int) -> bool:
- try:
- for row_id, row in enumerate(self.current_piece.elements):
- for col_id, element in enumerate(row):
- if element is None:
- continue
-
- if row_id + y < 0:
- continue
-
- if col_id + x < 0:
- return True
-
- if self.playfield.grid[row_id + y][col_id + x] is not None:
- return True
-
- except IndexError:
- return True
-
- return False
-
- def move_piece_down(self) -> None:
- if not self.has_collision(self.current_piece_position[0] + 1, self.current_piece_position[1]):
- self.current_piece_position[0] += 1
- else:
- raise WouldCollide()
-
- def move_piece_up(self) -> None:
- if not self.has_collision(self.current_piece_position[0] - 1, self.current_piece_position[1]):
- self.current_piece_position[0] -= 1
- else:
- raise WouldCollide()
-
- def move_piece_left(self) -> None:
- if not self.has_collision(self.current_piece_position[0], self.current_piece_position[1] - 1):
- self.current_piece_position[1] -= 1
- else:
- raise WouldCollide()
-
- def move_piece_right(self) -> None:
- if not self.has_collision(self.current_piece_position[0], self.current_piece_position[1] + 1):
- self.current_piece_position[1] += 1
- else:
- raise WouldCollide()
-
- def rotate_piece_counter_clockwise(self) -> None:
- self.current_piece.rotate_counter_clockwise()
-
- if self.has_collision(self.current_piece_position[0], self.current_piece_position[1]):
- self.current_piece.rotate_clockwise()
- raise WouldCollide()
-
- def rotate_piece_clockwise(self) -> None:
- self.current_piece.rotate_clockwise()
-
- if self.has_collision(self.current_piece_position[0], self.current_piece_position[1]):
- self.current_piece.rotate_counter_clockwise()
- raise WouldCollide()
-
- def handle_input_pressed(self, event: pygame.event.Event) -> None:
- if self.controller.get_input_down(event) == Input.QUIT:
- raise PlayerQuit()
-
- if self.controller.get_input_down(event) == Input.PAUSE:
- raise Pause()
-
- with contextlib.suppress(WouldCollide):
- if self.controller.get_input_down(event) == Input.MOVE_RIGHT:
- self.move_piece_right()
- self.das = 0
- if self.controller.get_input_down(event) == Input.MOVE_LEFT:
- self.move_piece_left()
- self.das = 0
- if self.controller.get_input_down(event) == Input.ROTATE_CLOCKWISE:
- self.rotate_piece_clockwise()
- if self.controller.get_input_down(event) == Input.ROTATE_COUNTER_CLOCKWISE:
- self.rotate_piece_counter_clockwise()
- if self.controller.get_input_down(event) == Input.MOVE_DOWN:
- self.piece_drop_frames = 0
- self.pressing_down_countdown = 3
- try:
- self.move_piece_down()
- except WouldCollide:
- self.lock_piece()
-
- def handle_input_released(self, event: pygame.event.Event) -> None:
- if self.controller.get_input_up(event) == Input.MOVE_DOWN:
- self.pressing_down_countdown = None
-
- def refresh_piece_preview_canvas(self) -> None:
- self.piece_preview_canvas.fill(Color.black.value)
-
- non_empty_rows = list()
- for row in self.next_piece.elements:
- if any(map(lambda element: element is not None, row)):
- non_empty_rows.append(row)
-
- non_empty_cols = set()
- for row in self.next_piece.elements:
- for col_id, element in enumerate(row):
- if element is not None:
- non_empty_cols.add(col_id)
-
- y_offset = (4 - len(non_empty_rows)) / 2
- x_offset = (4 - len(non_empty_cols)) / 2
-
- # Display the next piece
- for row_idx, row in enumerate(non_empty_rows):
- for col_idx, element in enumerate(row):
- if element is not None:
- self.piece_preview_canvas.blit(element, ((col_idx + x_offset) * 50 + 1, (row_idx + y_offset) * 50 + 1))
-
- def refresh_grid_canvas(self) -> None:
- self.grid_canvas.fill(Color.black.value)
-
- for row_idx, row in enumerate(self.playfield.grid):
- for col_idx, element in enumerate(row):
- if element is not None:
- self.grid_canvas.blit(element, (col_idx * 50 + 1, row_idx * 50 + 1))
-
- # Display the current piece
- for row_idx, row in enumerate(self.current_piece.elements):
- for col_idx, element in enumerate(row):
- if element is not None:
- self.grid_canvas.blit(element, ((col_idx + self.current_piece_position[1]) * 50 + 1, (row_idx + self.current_piece_position[0]) * 50 + 1))
-
-
def handle_input_pressed(instance, players: list[Player], event: pygame.event.Event) -> None:
for player in players:
if isinstance(player.controller, instance):
@@ -238,6 +26,9 @@ def handle_input_released(instance, players: list[Player], event: pygame.event.E
# Number of frames
frames_per_gridcell = [48, 43, 38, 33, 28, 23, 18, 13, 8, 6, 5, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1]
+right_pane_canvas = pygame.Surface((300, 1000))
+right_pane_canvas.fill((255, 255, 255))
+
class InGame(Screen):
def __init__(self, players: list[Player], screen: pygame.surface.Surface):