aboutsummaryrefslogtreecommitdiff
path: root/originaltetris/tetris.py
diff options
context:
space:
mode:
Diffstat (limited to 'originaltetris/tetris.py')
-rw-r--r--originaltetris/tetris.py191
1 files changed, 128 insertions, 63 deletions
diff --git a/originaltetris/tetris.py b/originaltetris/tetris.py
index b6b31f4..dec4a17 100644
--- a/originaltetris/tetris.py
+++ b/originaltetris/tetris.py
@@ -5,8 +5,8 @@ Tetris Tk - A tetris clone written in Python using the Tkinter GUI library.
Controls:
Left/a Move left
Right/d Move right
- Down/s Move down
- Up/w Rotate anti-clockwise (to the left)
+ Up/w Rotate / add player
+ Down/s Move down / start game
"""
from Tkinter import *
from time import sleep
@@ -30,13 +30,17 @@ COLORS = ["orange", "red", "green", "blue", "purple", "yellow", "magenta"]
class Board():
"""
The board represents the tetris playing area. A grid of x by y blocks.
+ Stores blocks that have landed.
"""
def __init__(self, max_x=10, max_y=20):
# blocks are stored in dict of (x,y)->"color"
self.landed = {}
self.max_x = max_x
self.max_y = max_y
-
+
+ def clear(self):
+ self.landed = {}
+
def receive_lines(self, num_lines):
#shift lines up
for y in range(self.max_y-num_lines):
@@ -97,23 +101,15 @@ class Board():
dx,dy = direction_d[DOWN]
self.landed[(x+dx, ay+dy)] = block_color
- # move the empty row down index down too
+ # move the empty row index down too
empty_row +=1
# y stays same as row above has moved down.
else:
y -= 1
- # return the score, calculated by the number of rows deleted.
+ # return the number of rows deleted.
return rows_deleted
-
- def output( self ):
- for y in xrange(self.max_y):
- line = []
- for x in xrange(self.max_x):
- if self.landed.get((x,y), None): line.append("X")
- else: line.append(".")
- print "".join(line)
-
+
def check_block( self, (x, y) ):
"""
Check if the x, y coordinate can have a block placed there.
@@ -130,19 +126,11 @@ class Board():
#represents a player. each player has a board and can get new shapes...
#
class Player():
- def __init__(self,parent, gs, myBoard, otherBoard):
+ def __init__(self, gs, myBoard, otherBoard):
print "initialize player"
- self.parent = parent
self.board = myBoard
self.other_board = otherBoard
self.score = 0
- self.shapes = [square_shape,
- t_shape,
- l_shape,
- reverse_l_shape,
- z_shape,
- s_shape,
- i_shape ]
self.gs = gs
self.shape = self.get_next_shape()
@@ -155,18 +143,21 @@ class Player():
if direction == DOWN:
points = self.board.check_for_complete_row(
self.shape.blocks)
- del self.shape
+ #del self.shape
self.shape = self.get_next_shape()
self.score += points
- if points > 1:
- self.other_board.receive_lines(points-1)
+ if self.gs.num_players == 2:
+ if points > 1:
+ self.other_board.receive_lines(points-1)
# If the shape returned is None, then this indicates that
# that the check before creating it failed and the
# game is over!
if self.shape is None:
- self.end_game() #loss!
+ self.gs.state = "ending" #loss!
+ self.gs.winner = self.other_board
+ #self.status = "loss"
# do we go up a level?
if (self.gs.level < NO_OF_LEVELS and
@@ -200,75 +191,149 @@ class Player():
def get_next_shape( self ):
#Randomly select which tetrominoe will be used next.
- the_shape = self.shapes[ random.randint(0,len(self.shapes)-1) ]
+ the_shape = self.gs.shapes[ random.randint(0,len(self.gs.shapes)-1) ]
return the_shape.check_and_create(self.board)
#contains variables that are shared between the players:
#levels, delay time, etc?
class GameState():
def __init__(self, gui):
+ self.shapes = [square_shape, t_shape,l_shape, reverse_l_shape,
+ z_shape, s_shape,i_shape ]
+ self.num_players = 0
self.level = 1
- self.delay = 1000
+ self.delay = 800
self.thresholds = range(10,100,10)
+ self.state = "waiting" #states: waiting, playing, ending
+ self.winner = None #winning Board
#runs the overall game. initializes both player and any displays
class TwoPlayerGame(object):
- """
- Main game loop and receives GUI callback events for keypresses etc...
- """
+
+ #one-time initialization for gui etc
def __init__(self, parent):
- print "initialize game"
+ print "initialize tetris"
self.parent = parent
self.gui = GUI(parent,20,MAXX,MAXY)
self.gui.pack(side=BOTTOM)
- self.gameState = GameState(self.gui)
-
+ self.parent.bind("<Key>", self.handle_key_press)
+ self.init_game()
+
+ #initializes each game
+ def init_game(self):
+ print "init next game"
board0 = Board(MAXX,MAXY)
board1 = Board(MAXX,MAXY)
- player0 = Player(parent, self.gameState, board0, board1)
- player1 = Player(parent, self.gameState, board1, board0)
- self.players = [player0, player1]
+ self.boards = [board0, board1]
+ self.gameState = GameState(self.gui)
+ self.players = [None,None]
+ self.update_gui()
+ self.gameState.state = "waiting" #states are waiting, playing, ending
- self.parent.bind("<Key>", self.handle_key_press)
+ def add_player(self,num): # 0=left, 1=right
+ if self.players[num]==None:
+ p = Player(self.gameState, self.boards[num], self.boards[(num+1)%2])
+ self.players[num] = p
+ self.update_gui()
+ self.gameState.num_players+=1
+
+ def start_game(self):
+ print "start game"
+ self.gameState.state = "playing"
self.parent.after( self.gameState.delay, self.gravity)
-
- def gravity(self):
- for p in self.players:
- p.move_my_shape()
self.update_gui()
- self.parent.after( self.gameState.delay, self.gravity)
+
+ #handles gravity and checks for game over
+ def gravity(self): #probably shouldn't handle gravity and endgame...or rename?
+ if self.gameState.state == "ending":
+ self.end_game()
+ return
+ else:
+ for p in self.players:
+ if p:
+ p.move_my_shape()
+ self.update_gui()
+ self.parent.after( self.gameState.delay, self.gravity)
def handle_key_press(self,event):
k = event.keysym
- if k=="Left":
- self.players[1].left()
- elif k=="Right":
- self.players[1].right()
- elif k=="Down":
- self.players[1].down()
- elif k=="Up":
- self.players[1].up()
- elif k=="a":
- self.players[0].left()
- elif k=="d":
- self.players[0].right()
- elif k=="s":
- self.players[0].down()
- elif k=="w":
- self.players[0].up()
+ if self.gameState.state == "playing":
+ if self.players[1]:
+ if k=="Left":
+ self.players[1].left()
+ elif k=="Right":
+ self.players[1].right()
+ elif k=="Down":
+ self.players[1].down()
+ elif k=="Up":
+ self.players[1].up()
+ if self.players[0]:
+ if k=="a":
+ self.players[0].left()
+ elif k=="d":
+ self.players[0].right()
+ elif k=="s":
+ self.players[0].down()
+ elif k=="w":
+ self.players[0].up()
+ elif self.gameState.state == "waiting":
+ if k=="Up":
+ self.add_player(1)
+ elif k=="w":
+ self.add_player(0)
+ elif k=="Down" and self.players[1]!=None:
+ self.start_game()
+ elif k=="s" and self.players[0]!=None:
+ self.start_game()
+ #if state==ending, ignore input
self.update_gui()
def update_gui(self):
self.gui.draw_board(self.players)
-
+
def end_game(self):
- #fix this
- #show_end_seq()
+ winner_board = self.gameState.winner
+ self.animate_ending(winner_board)
+ self.init_game()
+
+ def animate_ending(self,winner_board):
+ print "game over, display animation"
+ for i in range(100):
+ print i,
+
+ def end_all(self):
+ #this will destory the gui. not really useful.
Toplevel().destroy()
self.parent.destroy()
sys.exit(0)
+ def to_dict(self):
+ d = {}
+ for n in range(2):
+ #in progress...
+ p = players[n]
+ offset = n*self.max_x
+
+ #blocks
+ for (x,y) in p.board.landed:
+ d[(x+offset,y)] = p.board.landed[xy]
+
+ #shapes
+ blocks = p.shape.blocks
+ for b in blocks:
+ d[(b.x+offset*n,b.y)] = b.color
+
+ #score
+ for i in range(10):
+ score = p.score
+ bit = score%2
+ score = score>>1
+ coord = (self.max_x-1-i + offset, self.max_y+1)
+ if bit:
+ d[coord] = "yellow"
+ else:
+ d[coord] = "gray"
if __name__ == "__main__":