aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar dxiao <dxiao@mit.edu>2011-08-08 03:00:20 -0400
committerGravatar dxiao <dxiao@mit.edu>2011-08-08 03:00:20 -0400
commit43618642732145e7c20196ca1e79b498bc08f23b (patch)
tree43efd3cc1192907c9305bb4b16cb0fce09645cc0
parentf2d6e532d38f771a3dbeace96550e40393adbf3b (diff)
Leah's changes to tetris
-rw-r--r--originaltetris/tetris.py191
-rw-r--r--originaltetris/tetrisGUI.py88
2 files changed, 155 insertions, 124 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__":
diff --git a/originaltetris/tetrisGUI.py b/originaltetris/tetrisGUI.py
index 8085980..799dec3 100644
--- a/originaltetris/tetrisGUI.py
+++ b/originaltetris/tetrisGUI.py
@@ -3,6 +3,9 @@ This is the class you run to run tetris.
Handles input and output
"""
+#make this more display-independent, yo.
+
+
from Tkinter import *
#GUI
@@ -18,8 +21,6 @@ class GUI( Frame ):
self.max_x = max_x
self.max_y = max_y
self.offset = offset
- #height = rows + one blank + score row
- #width = left board + 4 blank + right board
self.canvas = Canvas(parent,
height=((max_y+2) * scale)+offset,
width= 2*((max_x+2) * scale)+offset)
@@ -27,7 +28,6 @@ class GUI( Frame ):
self.boardsize = ((max_x+4) * scale)+offset
self.canvas.pack()
-
def add_block(self, (x, y), color):
"""
Draw a block on the canvas
@@ -40,13 +40,20 @@ class GUI( Frame ):
self.canvas.create_rectangle(
rx, ry, rx+self.scale, ry+self.scale, fill=color
)
- """
- def draw_board(self, color_dict):
+
+ def display_dict(self,d):
self.canvas.delete(ALL)
- #ARRAY or DICT...
- for b in color_dict:
- self.add_block(b)
- """
+ x_width = self.max_x*self.scale+3
+ y_width = self.max_y*self.scale+3
+ gap = 4*self.scale
+ self.canvas.create_rectangle(3,2,x_width, y_width)
+ self.canvas.create_rectangle(x_width+gap,2,2*x_width+gap-3, y_width)
+ for (x,y) in d:
+ color = d[(x,y)]
+ if x>self.max_x:
+ x+=4
+ self.add_block((x,y),color)
+
def draw_board(self, players):
self.canvas.delete(ALL)
x_width = self.max_x*self.scale+3
@@ -55,16 +62,17 @@ class GUI( Frame ):
self.canvas.create_rectangle(3,2,x_width, y_width)
self.canvas.create_rectangle(x_width+gap,2,2*x_width+gap-3, y_width)
offset = 0
- for p in players:
- landed = p.board.landed
- for b in landed:
- self.add_block((b[0]+offset, b[1]), landed[b])
- for b in p.shape.blocks:
- self.add_block((b.x+offset, b.y), b.color)
- offset += (self.max_x + 4)
-
- self.display_score(players[0].score,0)
- self.display_score(players[1].score,1)
+ for n in range(2):
+ p = players[n]
+ if p:
+ offset = n*(self.max_x + 4)
+ landed = p.board.landed
+ for b in landed:
+ self.add_block((b[0]+offset, b[1]), landed[b])
+ if p.shape:
+ for b in p.shape.blocks:
+ self.add_block((b.x+offset, b.y), b.color)
+ self.display_score(p.score,n)
def display_score(self, score, player_num):
offset = player_num * (self.max_x + 4)
@@ -76,45 +84,3 @@ class GUI( Frame ):
self.add_block(coord, "yellow")
else:
self.add_block(coord, "gray")
-
-"""
-def update_display(player1,player2)
- nah = process(meh)
- #debug mode:
- display_image(nah)
- #real mode:
- #update_lights(nah)
-
-
-#waiting
-#press
-start = false
-while (!start)
-if (get_press(p0s)and p0_is_in) or (p1s and p1_is_in):
- start = true
-if get_press(p0in):
- game.add_player(0)
-if p1in:
- game.add_player(1)
-
-animate countdown
-
-#assume 1p
-handle controls...
-p0.left()
-p0.right()
-etc
-
-get state...
-if p0.update()...
- update_display(p0.board, p0.score)
-
-if p0.died:
- end
-
-animate end_seq(score)
-
-goto waiting
-
-
-"""