generated from mwc/project_game
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)
|
|
|
|
|
|
|
|
|