generated from mwc/project_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.
101 lines
3.3 KiB
Python
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)
|
|
|
|
|
|
|
|
|