Files
project_game/piece.py
Chris Proctor c8d1ddd58f Started retro tetris game
Started developing a retro version of Tetris, following
the planning on the board of the classroom
(see planning.jpg).

Moved cursor work into cursor.
2025-12-18 17:45:39 -05:00

101 lines
3.3 KiB
Python

from block import Block
PIECE_DEFINITIONS = [
[(-1, 0), (0, 0), (1, 0), (2, 0)],
[(0, 0), (1, 0), (0, 1), (1, 1)],
]
class Piece:
"""A Piece is a group of blocks which are 'alive':
They fall and the player can rotate or move them.
A Piece is created with a position, the game, and a list of block_offsets,
each of which represents the location of one of the Piece's
Blocks relative to the Piece position.
"""
name = "piece"
display = False
def __init__(self, position, game, block_offsets):
self.position = position
self.blocks = {}
for offset in block_offsets:
self.create_block(game, offset)
def handle_keystroke(self, keystroke, game):
x, y = self.position
if keystroke.name == "KEY_LEFT":
new_position = (x - 1, y)
if self.can_move_to(new_position, game):
self.move_to(new_position)
elif keystroke.name == "KEY_RIGHT":
new_position = (x + 1, y)
if self.can_move_to(new_position, game):
self.move_to(new_position)
def play_turn(self, game):
if self.should_fall(game):
self.fall(game)
def should_fall(self, game):
"""Determines whether the piece should fall.
Currently, the Piece falls every third turn.
In the future, the Piece should fall slowly at first, and
then should fall faster at higher levels.
"""
return game.turn_number % 3 == 0
def fall(self, game):
x, y = self.position
falling_position = (x, y + 1)
if self.can_move_to(falling_position, game):
self.move_to(falling_position)
else:
self.destroy(game)
def can_move_to(self, new_position, game):
"""Checks whether the Piece can move to a new position.
For every one of the Piece's Blocks, finds where that block
would be after the move, and checks whether there are any dead agents
already there (live agents would be Blocks which are part of this Piece,
not a problem since they'll be moving too).
"""
x, y = new_position
agents_by_position = game.get_agents_by_position()
for offset in self.blocks.keys():
ox, oy = offset
new_block_position = (x+ox, y+oy)
if not game.on_board(new_block_position):
return False
for agent in agents_by_position[new_block_position]:
if not agent.alive:
return False
return True
def move_to(self, position):
"""Move to position and updates positions of Blocks.
"""
x, y = position
self.position = position
for offset, block in self.blocks.items():
ox, oy = offset
block.position = (x + ox, y + oy)
def create_block(self, game, offset):
x, y = self.position
ox, oy = offset
block = Block((x + ox, y + oy))
self.blocks[offset] = block
game.add_agent(block)
def destroy(self, game):
"""Causes the Piece to destroy itself.
All the Blocks are set to dead.
"""
for block in self.blocks.values():
block.alive = False
game.remove_agent(self)