Skip to content

Instantly share code, notes, and snippets.

@xmunoz
Last active August 29, 2015 14:22
Show Gist options
  • Save xmunoz/ace5e92e647b8cba81ee to your computer and use it in GitHub Desktop.
Save xmunoz/ace5e92e647b8cba81ee to your computer and use it in GitHub Desktop.
import random
from copy import deepcopy
class Piece:
def __init__(self, display, stuck = False):
self.display = display
self.stuck = stuck
# 4 x 4
self.height = len(display)
self.width = len(display[0])
def actual_width(self):
'''
Determine the actual piece length to determine valid range of initial position
'''
widths = [0] * self.height
for row in self.display:
for i in range(len(row)):
if row[i] == "*":
widths[i] = 1
return sum(widths)
def actual_height(self):
'''
Determine the actual piece height to determine valid range of initial position
'''
heights = [0] * self.width
for i in range(len(self.display)):
for cell in self.display[i]:
if cell == "*":
heights[i] = 1
return sum(heights)
def rotate_clockwise(self):
display_copy = deepcopy(self.display)
for y in range(self.height):
for x in range(self.width):
self.display[y][x] = display_copy[x][y]
def rotate_counterclockwise(self):
'''
Got tired...
'''
self.rotate_clockwise()
class Pieces:
def __init__(self):
self.generate_pieces()
def generate_pieces(self):
LOG = 0
ELLE = 1
BELLE = 2
SNAKE= 3
BOX = 4
self.all_pieces = {}
self.all_pieces[LOG] = Piece([["*", "*", "*", "*"],
[" ", " ", " ", " "],
[" ", " ", " ", " "],
[" ", " ", " ", " "]])
self.all_pieces[ELLE] = Piece([["*", " ", " ", " "],
["*", " ", " ", " "],
["*", "*", " ", " "],
[" ", " ", " ", " "]])
self.all_pieces[BELLE] = Piece([[" ", "*", " ", " "],
[" ", "*", " ", " "],
["*", "*", " ", " "],
[" ", " ", " ", " "]])
self.all_pieces[SNAKE] = Piece([[" ", "*", " ", " "],
["*", "*", " ", " "],
["*", " ", " ", " "],
[" ", " ", " ", " "]])
self.all_pieces[BOX] = Piece([["*", "*", " ", " "],
["*", "*", " ", " "],
[" ", " ", " ", " "],
[" ", " ", " ", " "]])
def choose_random(self):
return deepcopy(self.all_pieces[random.randint(0,4)])
class Board:
def __init__(self, length, width):
self.length = length
self.width = width
self.border_char = "*"
self.display = []
self.initialize()
self.valid_moves = set(["a", "d", "w", "s"])
def initialize(self):
for i in range(self.length):
self.display.append([" "] * self.width)
def show(self):
for i in range(self.length):
line = self.border_char
for j in range(self.width):
line += self.display[i][j]
line += self.border_char
print line
print self.border_char * (self.width + 2)
def add(self, piece, x, y):
for i in range(y, y + piece.actual_height()):
for j in range(x, x + piece.actual_width()):
piece_part = piece.display[i - y][j - x]
if piece_part == "*":
if self.display[i][j] == "*":
# a collision at the top, game over
return False
else:
# alter the board display
self.display[i][j] = "*"
if i == (self.length - 1) or self.display[i+1][j] == "*":
piece.stuck = True
return True
def perform_move_update(self, piece, x, move):
while move not in self.valid_moves:
print "Please input one of the valid characters: "
move = raw_input()
'''
Capable of updating x or piece, hence the deepcopy one level up
'''
if move == "a":
x -= 1
elif move == "d":
x += 1
elif move == "w":
piece.rotate_clockwise()
else:
piece.rotate_counterclockwise()
return x
def check_result(self, piece, x, y):
'''
Perform move validation
'''
# within bounds
if x < 0:
return False
if x > (self.width - piece.actual_width()):
return False
if y > (self.length - piece.actual_height()):
return False
for i in range(y, y + piece.actual_height()):
for j in range(x, x + piece.actual_width()):
if piece.display[i - y][j - x] == "*":
if self.display[i][j] == "*":
return False
return True
class Game:
'''
The main game class.
'''
def __init__(self):
self.length = 20
self.width = 20
self.board = Board(self.length, self.width)
self.pieces = Pieces()
self.game_over = False
def run(self):
while not self.game_over:
self.drop_piece()
def drop_piece(self):
moves_tried = set()
piece = self.pieces.choose_random()
x_position = random.randint(0, self.board.width - piece.actual_width())
y_position = 0
# keep backup for later
board_backup = deepcopy(self.board)
add_success = self.board.add(piece, x_position, y_position)
if not add_success:
self.game_over = True
return
while not piece.stuck:
self.board.show()
print "Move (a: left, d: right, w: rotate clockwise, s: rotate counter-clockwise): "
move = raw_input()
y_position += 1
# perform_move_update modifies piece also, so keep a back up
piece_backup = deepcopy(piece)
x_position_tmp = board_backup.perform_move_update(piece, x_position, move)
valid = board_backup.check_result(piece, x_position_tmp, y_position)
while not valid:
self.board.show()
if move in self.board.valid_moves: moves_tried.add(move)
if len(moves_tried) == 4:
print "AcK, no moves left to try."
self.game_over = True
return
print "Move invalid, please try another option (a, d, w, s): "
move = raw_input()
piece = deepcopy(piece_backup)
x_position_tmp = board_backup.perform_move_update(piece, x_position, move)
valid = board_backup.check_result(piece, x_position_tmp, y_position)
# refresh the item location
self.board = deepcopy(board_backup)
x_position = x_position_tmp
self.board.add(piece, x_position, y_position)
self.board.show()
def main():
Game().run()
print "Game Over!"
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment