Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/tower.py
diff options
context:
space:
mode:
Diffstat (limited to 'tower.py')
-rw-r--r--tower.py639
1 files changed, 639 insertions, 0 deletions
diff --git a/tower.py b/tower.py
new file mode 100644
index 0000000..be61962
--- /dev/null
+++ b/tower.py
@@ -0,0 +1,639 @@
+import random, os.path
+import util
+
+import pygame
+import pygame.font
+from pygame.locals import *
+
+#Global variables:
+
+#List representing the range of the numbers that are in the gaps on each level, the first level has numbers from 0~20 and so on
+levelRanges = [(0,20),(10,30),(20,40),(30,50),(45,65),(60,80),(65,85),(80,100)]
+
+#Generates a tower "floor", given the amount of holes in the floor and the height on the screen it will be placed on
+#Returns a list of 4 things each representing different aspects of the floor:
+# 1. A list of the rectangles which make up the "walls" of the floor"
+# 2. A list of the rectangles which represent the gaps between the floor walls
+# 3. A list of the rectangles which will contain the numbers (all within the walls, on either side of the gaps)
+# 4. A list representing which number boxes are associated with each gap
+
+def generateFloor(holes, height, type = 1):
+ walls, gaps = [], []
+ numBoxes = []
+ rect = []
+ gapPattern = []
+ if holes == 1:
+ holeSize = random.randint(10,50)*10
+ holeStart = random.randint(0,70-holeSize/10)*10
+
+ walls.append(pygame.Rect(150,height,100+holeStart,50))
+ walls.append(pygame.Rect(250+holeStart+holeSize,height,800-holeStart-holeSize,50))
+
+ gaps.append(pygame.Rect(250+holeStart, height, holeSize, 20))
+
+ numBoxes.append(pygame.Rect(155+holeStart, height+5, 90, 40))
+ numBoxes.append(pygame.Rect(255+holeStart+holeSize,height+5,90,40))
+
+ gapPattern = [(0,1)]
+
+ elif holes == 2 and type == 1:
+
+ hole1Size = random.randint(10,24)*10
+ hole2Size = random.randint(10,24)*10
+ centerSize = random.randint(22,70-hole1Size/10-hole2Size/10)*10
+ holeStart = random.randint(0,70-hole1Size/10-hole2Size/10-centerSize/10)*10
+
+ #print "Hole 1 Size:%d\nHole 2 Size: %d\n Center Size: %d\nHole Start: %d"%(hole1Size,hole2Size,centerSize,holeStart)
+
+ walls.append(pygame.Rect(150,height,100+holeStart,50))
+ walls.append(pygame.Rect(250+holeStart+hole1Size,height,centerSize,50))
+ walls.append(pygame.Rect(250+holeStart+hole1Size+centerSize+hole2Size,height,800-(holeStart+hole1Size+centerSize+hole2Size),50))
+
+ gaps.append(pygame.Rect(250+holeStart,height,hole1Size,20))
+ gaps.append(pygame.Rect(250+holeStart+hole1Size+centerSize,height,hole2Size,20))
+
+ numBoxes.append(pygame.Rect(155+holeStart,height+5,90,40))
+ numBoxes.append(pygame.Rect(255+holeStart+hole1Size,height+5,90,40))
+ numBoxes.append(pygame.Rect(155+holeStart+hole1Size+centerSize,height+5,90,40))
+ numBoxes.append(pygame.Rect(255+holeStart+hole1Size+centerSize+hole2Size,height+5,90,40))
+
+ gapPattern = [(0,1),(2,3)]
+
+ elif holes == 2 and type != 1:
+ #Randomly assigns hole sizes
+ hole1Size = random.randint(10,50)*10
+ hole2Size = random.randint(10,60-(hole1Size/10))*10
+ holeStart = random.randint(0,60-(hole1Size+hole2Size)/10)*10
+
+ walls.append(pygame.Rect(150,height,100+holeStart,50))
+ walls.append(pygame.Rect(250+holeStart+hole1Size,height,100,50))
+ walls.append(pygame.Rect(350+holeStart+hole1Size+hole2Size,height,700-holeStart-hole1Size-hole2Size,50))
+
+ gaps.append(pygame.Rect(250+holeStart, height, hole1Size, 20))
+ gaps.append(pygame.Rect(350+holeStart+hole1Size, height, hole2Size, 20))
+
+ numBoxes.append(pygame.Rect(155+holeStart,height+5,90,40))
+ numBoxes.append(pygame.Rect(255+holeStart+hole1Size,height+5,90,40))
+ numBoxes.append(pygame.Rect(355+holeStart+hole1Size+hole2Size,height+5,90,40))
+
+ gapPattern = [(0,1),(1,2)]
+
+ elif holes == 3 and type == 1:
+ holeStart = random.randint(0,2)*10
+ hole1Size = random.randint(0,1)*10
+ hole2Size = random.randint(0,2)*10
+ hole3Size = random.randint(0,1)*10
+ centerSize = random.randint(0,3)*10
+
+ if random.randint(0,1) == 1:
+ walls.append(pygame.Rect(150,height,100+holeStart,50))
+ walls.append(pygame.Rect(350+holeStart+hole1Size,height,210+centerSize,50))
+ walls.append(pygame.Rect(660+holeStart+hole1Size+centerSize+hole2Size,height,100,50))
+ walls.append(pygame.Rect(860+holeStart+hole1Size+centerSize+hole2Size+hole3Size,height,190-(holeStart+hole1Size+centerSize+hole2Size+hole3Size),50))
+
+ gaps.append(pygame.Rect(250+holeStart,height,100+hole1Size,20))
+ gaps.append(pygame.Rect(560+holeStart+hole1Size+centerSize,height,100+hole2Size,20))
+ gaps.append(pygame.Rect(760+holeStart+hole1Size+centerSize+hole2Size,height,100+hole3Size,20))
+
+ numBoxes.append(pygame.Rect(155+holeStart,height+5,90,40))
+ numBoxes.append(pygame.Rect(355+holeStart+hole1Size,height+5,90,40))
+ numBoxes.append(pygame.Rect(465+holeStart+hole1Size+centerSize,height+5,90,40))
+ numBoxes.append(pygame.Rect(665+holeStart+hole1Size+centerSize+hole2Size,height+5,90,40))
+ numBoxes.append(pygame.Rect(865+holeStart+hole1Size+centerSize+hole2Size+hole3Size,height+5,90,40))
+
+ gapPattern = [(0,1),(2,3),(3,4)]
+
+ else:
+ walls.append(pygame.Rect(150,height,100+holeStart,50))
+ walls.append(pygame.Rect(350+holeStart+hole1Size,height,100,50))
+ walls.append(pygame.Rect(550+holeStart+hole1Size+hole2Size,height,210+centerSize,50))
+ walls.append(pygame.Rect(860+holeStart+hole1Size+centerSize+hole2Size+hole3Size,height,190-(holeStart+hole1Size+centerSize+hole2Size+hole3Size),50))
+
+ gaps.append(pygame.Rect(250+holeStart,height,100+hole1Size,20))
+ gaps.append(pygame.Rect(450+holeStart+hole1Size,height,100+hole2Size,20))
+ gaps.append(pygame.Rect(760+holeStart+hole1Size+centerSize+hole2Size,height,100+hole3Size,20))
+
+ numBoxes.append(pygame.Rect(155+holeStart,height+5,90,40))
+ numBoxes.append(pygame.Rect(355+holeStart+hole1Size,height+5,90,40))
+ numBoxes.append(pygame.Rect(555+holeStart+hole1Size+hole2Size,height+5,90,40))
+ numBoxes.append(pygame.Rect(665+holeStart+hole1Size+centerSize+hole2Size,height+5,90,40))
+ numBoxes.append(pygame.Rect(865+holeStart+hole1Size+centerSize+hole2Size+hole3Size,height+5,90,40))
+
+ gapPattern = [(0,1),(1,2),(3,4)]
+
+ elif holes == 3 and type != 1:
+
+ holeStart = random.randint(0,10)*10
+ hole1Size = random.randint(0,15-holeStart/10)*10
+ hole2Size = random.randint(0,17-(holeStart+hole1Size)/10)*10
+ hole3Size = random.randint(0,20-(holeStart+hole1Size+hole2Size)/10)*10
+
+ walls.append(pygame.Rect(150,height,100+holeStart,50))
+ walls.append(pygame.Rect(350+holeStart+hole1Size,height,100,50))
+ walls.append(pygame.Rect(550+holeStart+hole1Size+hole2Size,height,100,50))
+ walls.append(pygame.Rect(750+holeStart+hole1Size+hole2Size+hole3Size,height,300-(holeStart+hole1Size+hole2Size+hole3Size),50))
+
+ gaps.append(pygame.Rect(250+holeStart,height,100+hole1Size,20))
+ gaps.append(pygame.Rect(450+holeStart+hole1Size,height,100+hole2Size,20))
+ gaps.append(pygame.Rect(650+holeStart+hole1Size+hole2Size,height,100+hole3Size,20))
+
+ numBoxes.append(pygame.Rect(155+holeStart,height+5,90,40))
+ numBoxes.append(pygame.Rect(355+holeStart+hole1Size,height+5,90,40))
+ numBoxes.append(pygame.Rect(555+holeStart+hole1Size+hole2Size,height+5,90,40))
+ numBoxes.append(pygame.Rect(755+holeStart+hole1Size+hole2Size+hole3Size,height+5,90,40))
+
+ gapPattern = [(0,1),(1,2),(2,3)]
+
+ elif holes == 4:
+ walls.append(pygame.Rect(150,height,100,50))
+ walls.append(pygame.Rect(350,height,100,50))
+ walls.append(pygame.Rect(550,height,100,50))
+ walls.append(pygame.Rect(750,height,100,50))
+ walls.append(pygame.Rect(950,height,100,50))
+
+ gaps.append(pygame.Rect(250,height,100,20))
+ gaps.append(pygame.Rect(450,height,100,20))
+ gaps.append(pygame.Rect(650,height,100,20))
+ gaps.append(pygame.Rect(850,height,100,20))
+
+ numBoxes.append(pygame.Rect(155,height+5,90,40))
+ numBoxes.append(pygame.Rect(355,height+5,90,40))
+ numBoxes.append(pygame.Rect(555,height+5,90,40))
+ numBoxes.append(pygame.Rect(755,height+5,90,40))
+ numBoxes.append(pygame.Rect(955,height+5,90,40))
+
+ gapPattern = [(0,1),(1,2),(2,3),(3,4)]
+
+ return (walls, gaps, numBoxes, gapPattern)
+
+
+
+def generateScreen(background, levelNum):
+
+ #defines the locations of the outer walls
+ leftWall = pygame.Rect(100,0,50,900)
+ rightWall = pygame.Rect(1050,0,50,900)
+ bottomWall = pygame.Rect(100,850,1000,50)
+
+ #loads up the sky graphic, selects a random portion
+ skyGraphic = util.load_image('sky.jpg')
+ background.blit(skyGraphic,(0,0),(random.randint(0,600),0,100,900))
+ background.blit(skyGraphic,(1100,0),(random.randint(0,600),0,100,900))
+
+ if levelNum == 0:#only draw grass on the bottom level!
+ grass = util.load_image('grass.bmp')
+ background.blit(grass,(0,850))
+ background.blit(grass,(1100,850))
+
+ #Generates/saves the two middle floors of the tower
+ if levelNum == 0:
+ floor1size = random.sample([1,1,2,2,2,2,2],1)[0]
+ floor2size = random.sample([1,2,2,2,2,2,3,3,3,3,4],1)[0]
+ floor1type = random.randint(0,1)
+ floor2type = random.randint(0,1)
+
+ else:
+ floor1size = random.sample([1,2,2,2,2,2,3,3,3,3,3,4,4],1)[0]
+ floor2size = random.sample([1,2,2,2,2,2,3,3,3,3,3,4,4],1)[0]
+ floor1type = random.randint(0,1)
+ floor2type = random.randint(0,1)
+
+ floor1 = generateFloor(floor1size,500,floor1type)
+ floor2 = generateFloor(floor2size,150,floor2type)
+
+ floor1Numbers = len(floor1[2])
+
+ centerWalls = util.merge(floor1[0],floor2[0])
+ gaps = util.merge(floor1[1],floor2[1])
+ numbers = util.merge(floor1[2],floor2[2])
+
+ gapPattern = floor1[3]
+
+ for pair in floor2[3]:
+ gapPattern.append((pair[0]+floor1Numbers, pair[1]+floor1Numbers))
+
+ floorNumbers = []
+ gapNumbers = []
+
+ #Goes through every number box (around each gap), and randomly assigns a number to it, based on the number range of the current level
+ for i in range(len(numbers)):
+ floorNumbers.append(random.randint(levelRanges[levelNum][0],levelRanges[levelNum][1]))
+
+ walls = [leftWall, rightWall, bottomWall]
+ walls = util.merge(walls,centerWalls)
+
+ #Loads the two background image files into surfaces
+ towerWallTile = util.load_image('WallTile.bmp')
+ windowTile = util.load_image('TowerWindow.bmp')
+
+ #Prints each wall tile
+ for i in range(18):
+ for j in range(18):
+ background.blit(towerWallTile, (150+50*i,50*j))
+
+ #Draws the four windows on the screen
+ background.blit(windowTile, (400,300))
+ background.blit(windowTile, (750,300))
+ background.blit(windowTile, (400,650))
+ background.blit(windowTile, (750,650))
+
+ #loads the image for the walls
+ wallSprite = util.load_image('wall.bmp')
+
+ #Draws the walls
+ for wall in walls:
+ pygame.draw.rect(background, [100,100,100], wall)
+ if wall.width == 50: #draws the vertical walls
+ x = wall.topleft[0]
+ y = wall.topleft[1]
+ while y < wall.height:
+ background.blit(wallSprite, (x,y))
+ y = y + 50
+ else: #draws the horizontal walls
+ x = wall.topleft[0]
+ y = wall.topleft[1]
+ #Checks if the horizontal wall touches the right one, if so adds a small bit of tile first, to make sure it tiles properly on the right side
+ if wall.topright[0] == 1050:
+ if wall.width%50 != 0:
+ background.blit(wallSprite,(x,y),pygame.Rect(50-(wall.width%50),0,wall.width%50,50))
+ x = x + wall.width % 50
+ while x < wall.topright[0]:
+ background.blit(wallSprite, (x,y))
+ x = x + 50
+ if wall.topright[0] - x < 50:
+ background.blit(wallSprite,(x,y),pygame.Rect(0,0,wall.topright[0] - x,50))
+ x = wall.topright[0]
+
+
+ #Goes through every gap and associates the numbers with it, also checks the randomized numbers to make sure they are passable, if not generates a new one
+ index = 0
+ for gap in gaps:
+ #makes sure there is a difference of at least two around each gap so there is room to go through
+ while -1 <= floorNumbers[gapPattern[index][0]] - floorNumbers[gapPattern[index][1]] <= 1:
+ floorNumbers[gapPattern[index][1]] = random.randint(levelRanges[levelNum][0],levelRanges[levelNum][1])
+ gapNumbers.append((floorNumbers[gapPattern[index][0]],floorNumbers[gapPattern[index][1]]))
+ index = index+1
+
+ index = 0
+ numberPlate = util.load_image('numberPlate.bmp') #The background image behind the numbers
+
+ #Draws all the numbers/its background image around every gap
+ for numBox in numbers:
+ numberText = stringFactor(floorNumbers[index])
+
+ #Sets up the font which will be used in the box containing the number
+ fontSize = 40
+ font = pygame.font.Font(None, fontSize)
+
+ displayBox = font.render(numberText, 1, (50,50,50))
+ textSize = font.size(numberText)
+
+ background.blit(numberPlate, numBox.topleft)
+ background.blit(displayBox, (numBox.topleft[0]+(90-textSize[0])/2,numBox.topleft[1]+(40-textSize[1])/2))
+
+ index = index+1
+
+ background.convert()
+ return (background,walls,gaps,gapNumbers)
+
+def run():
+ #Must initialize pygame before doing anything else
+ pygame.init()
+ random.seed()
+
+ display_flags = DOUBLEBUF
+
+ #XO laptop is 1200x900 resolution
+ width, height = 1200, 900
+
+ if pygame.display.mode_ok((width, height), display_flags ):
+ screen = pygame.display.set_mode((width, height), display_flags)
+
+ #display background
+ background = pygame.Surface(screen.get_size())
+ background = background.convert()
+ background.fill((200, 200, 200))
+
+
+ heroNumber = random.randint(3,17)
+ levelNum = 0
+
+ level = generateScreen(background,levelNum)
+ background = level[0]
+ walls = level[1]
+ gaps = level[2]
+ gapNumbers = level[3]
+
+ #Grid, for display purposes
+ grid = 0
+ if grid == 1:
+ for i in range(24):
+ pygame.draw.line(background, [0,0,0], (50*i,0),(50*i,900))
+ for i in range(18):
+ pygame.draw.line(background, [0,0,0], (0,50*i),(1200,50*i))
+
+
+ screen.blit(background, (0, 0))
+ pygame.display.flip()
+
+
+ hero = pygame.Rect(600, 700, 70, 100) #The rectangle representing the hero
+
+ dropRects = []
+ dropValues = []
+ dropStrings = []
+
+ updateGaps = 1 #The variable that stores if the gaps need to be updated(set to 1 whenever the heroes number changes), also need to update at start
+
+ #Sets the movement speeds for the character, in pixels per loop increment (game runs at 40 FPS)
+ sideSpeed = 10
+ upSpeed = 20
+ gravity = 10
+ xchange = 0
+ ychange = gravity
+
+ clock = pygame.time.Clock()
+
+ shownGap1, shownGap2 = None, None #Variables will represent gaps that will be displayed (if they get hit or stepped on)
+ fallWait, topHoleWait = 0, 0 #Variables representing timers for if the hero is falling or a gap is being displayed because it was stepped on
+
+ run = 1 #Variable representing if the game is running
+ runCounter = 0 #The number of run loops the game has gone through
+
+ #The main game loop of the program
+ while run:
+ runCounter = runCounter+1
+ events = pygame.event.get()
+ for event in events:
+ #User decides to exit program
+ if event.type == QUIT:
+ run = 0 #stop running
+
+ #Triggers when a key is first pressed down
+ elif event.type == pygame.KEYDOWN:
+ if event.key == 273: #up
+ ychange += -upSpeed
+ elif event.key == 274: #down
+ ychange += 0
+ elif event.key == 275: #right
+ xchange += sideSpeed
+ elif event.key == 276: #left
+ xchange += -sideSpeed
+ elif event.unicode == "+":
+ heroNumber = heroNumber+1
+ updateGaps = 1
+ elif event.unicode == "-":
+ heroNumber = heroNumber-1
+ updateGaps = 1
+
+ #Triggers when a pressed down key is no longer being pressed
+ elif event.type == pygame.KEYUP:
+ if event.key == 273:
+ ychange += +upSpeed
+ elif event.key == 274:
+ ychange += 0
+ elif event.key == 275:
+ xchange += -sideSpeed
+ elif event.key == 276:
+ xchange += +sideSpeed
+
+ #Sees if the lists storing the gaps which are impassable need to be updated
+ if updateGaps != 0:
+ updateGaps = 0
+ print "Updating Gaps"
+
+ impassableGaps = [] #The list that will store all the gaps that are not currently passable because of the heroes current number
+ impassableWalls = util.merge([],walls) #Combined list representing impassable gaps and all walls
+
+ #Goes through every gap on the screen and checks if it is impassable or not, if so adds to appropriate lists
+ for i in range(len(gaps)):
+ if not(gapNumbers[i][0]<=heroNumber<=gapNumbers[i][1] or gapNumbers[i][0]>=heroNumber>=gapNumbers[i][1]):
+ if hero.collidelist([gaps[i]]) == -1: #makes sure the hero isn't in the gap currently (prevents it from getting stuck)
+ impassableGaps.append(gaps[i])
+ impassableWalls.append(pygame.Rect(gaps[i][0],gaps[i][1],gaps[i][2],1))
+
+ #Start of hero movement/collision detection block
+ if fallWait != 0: #The hero is falling, so movement is not based on arrow keys pressed
+ fallWait = fallWait - 1
+ tempXChange = 0 #hero does not move left or right, just falls based o gravity
+ tempYChange = gravity
+ if fallWait <= 20: #After done falling for a while stops showing the gap which was hit
+ shownGap1 = None
+ else: #hero is not falling, movement based on the modifiers from the arrow keys.
+ shownGap1 = None
+ tempXChange = xchange
+ tempYChange = ychange
+
+ tempHero = hero.move(tempXChange,tempYChange)
+
+ if tempHero.collidelist(impassableWalls) == -1: #no collision problems, hero moves normally
+ hero = tempHero
+ else:
+ tempHero = hero.move(tempXChange,0) # first checks if collision is from vertical movement,
+ if tempHero.collidelist(impassableWalls) == -1: # if it is, move hero horizontally only
+ hero = tempHero
+ else:
+ tempHero = hero.move(0,tempYChange) # otherwise, checks if collision is from horizontal movement
+ if tempHero.collidelist(impassableWalls) == -1:
+ hero = tempHero
+
+
+ #If collison comes from both horizontal and verical movements, the hero does not get moved
+
+ #checks if the hero hits a gap they cannot pass through from the bottom
+ if hero.collidelist(impassableGaps) != -1:
+ fallWait = 60 #Sets the variable representing the fact that the hero is falling, because they went the wrong way
+ shownGap1 = impassableGaps[hero.collidelist(impassableGaps)]
+
+ #checks if the hero is standing on top of a gap they cannot pass through
+ tempHero = hero.inflate(-70,0)
+ tempHero = tempHero.move(0,1)
+ if tempHero.collidelist(impassableGaps) != -1:
+ topHoleWait = 5 #gap hero is standing on stays for 5 increments after it's off
+ gap = impassableGaps[tempHero.collidelist(impassableGaps)]
+ shownGap2 = pygame.Rect(gap.topleft,(gap.width,20))
+
+ #re-draws the background
+ screen.blit(background, (0, 0))
+ pygame.draw.rect(screen, [255,50,50], hero) #draws the hero
+
+ #Checks if any impassable gaps have been hit or stepped on and thus need to be displayed
+ if shownGap1 != None:
+ pygame.draw.rect(screen, [250,100,100,50], shownGap1)
+ if topHoleWait != 0:
+ topHoleWait = topHoleWait - 1
+ pygame.draw.rect(screen, [250,100,100,50], shownGap2)
+
+ #Code which spawns a drop which contains a number, only called every 100 loops
+ if runCounter%75 == 0:
+ #for i in range(1):
+ newDrop = generateDropNumber(heroNumber,levelNum)
+ #print "spawn bubble %d"%(runCounter),newDrop[2]
+ dropRects.append(pygame.Rect(random.randint(150,850),0,50,50))
+ dropValues.append(newDrop[0:2])
+ dropStrings.append(newDrop[2])
+
+
+
+ #Checks if hero has hit any drops
+ if hero.collidelist(dropRects) != -1:
+ i = hero.collidelist(dropRects)
+
+ if dropValues[i][0] == 0: #hit an addition drop
+ if heroNumber + dropValues[i][1] < 1000:
+ heroNumber = heroNumber + dropValues[i][1]
+ dropRects.pop(i)
+ dropValues.pop(i)
+ dropStrings.pop(i)
+ updateGaps = 1
+
+ elif dropValues[i][0] == 1: #hit a subtraction drop
+ if -1000 < heroNumber - dropValues[i][1]:
+ heroNumber = heroNumber - dropValues[i][1]
+ dropRects.pop(i)
+ dropValues.pop(i)
+ dropStrings.pop(i)
+ updateGaps = 1
+
+ elif dropValues[i][0] == 2: #Multiplication drop
+ if -1000 < heroNumber*dropValues[i][1] < 1000:
+ heroNumber = heroNumber * dropValues[i][1]
+ dropRects.pop(i)
+ dropValues.pop(i)
+ dropStrings.pop(i)
+ updateGaps = 1
+
+ elif dropValues[i][0] == 3: #Division drop
+ if heroNumber%dropValues[i][1] == 0:
+ heroNumber = heroNumber / dropValues[i][1]
+ dropRects.pop(i)
+ dropValues.pop(i)
+ dropStrings.pop(i)
+ updateGaps = 1
+
+ #Goes through every drop currently on screen (starting with most recently spawned), draws it to the screen with the appropriate number, and moves it down
+ dropIndexs = range(len(dropRects))
+ dropIndexs.reverse()
+ for i in dropIndexs:
+ #dropTextRect = dropRects[i].inflate(20,-25)
+ #pygame.draw.rect(screen, [102,255,255], dropRects[i])
+ font = pygame.font.Font(None,42)
+ dropBox = font.render(dropStrings[i], 1, (50,50,230))
+ textSize = font.size(dropStrings[i])
+ screen.blit(dropBox, (dropRects[i].topleft[0]+(50-textSize[0])/2,dropRects[i].topleft[1]+(50-textSize[1])/2))
+ dropRects[i] = dropRects[i].move(0,2)
+ if dropRects[i].topleft[1]>=900: #Removes from all applicable lists if no longer on screen
+ dropRects.pop(i)
+ dropValues.pop(i)
+ dropStrings.pop(i)
+
+ #Sets up and displays the box which contains the number the hero currently has
+ numBox = pygame.Rect(0,0,60,30)
+ hero_number_box = util.render_textrect(str(heroNumber),pygame.font.Font(None, 40),numBox,(50,50,50),[250,250,250],0,1)
+ screen.blit(hero_number_box, (hero.topleft[0]+5,hero.topleft[1]+35))
+ pygame.display.flip() #updates screen
+
+ #Made it off the top of the screen, must advance to next level
+ if hero.topleft[1] <= -80:
+ levelNum = levelNum+1
+ if levelNum == 8: #Made it to the top of the tower!
+ victoryCinematic(screen)
+ break
+
+ #Copy copies the second floor displayed on the screen so it can be shown as the very bottom on the next level
+ for gap in gaps:
+ pygame.draw.rect(background,[250,100,100,50], gap)
+
+ copy = background.subsurface(pygame.Rect(100,150,1000,50)).copy()
+
+ #Clears background, generate new level/get it saved into variables
+ background.fill((200, 200, 200))
+ level = generateScreen(background,levelNum)
+ background = level[0]
+ walls = level[1]
+ gaps = level[2]
+ gapNumbers = level[3]
+
+ #Clear the falling numbers from the screen
+ dropRects, dropValues, dropStrings = [], [], []
+
+ #Reset heros vertical location
+ hero = pygame.Rect(hero.topleft[0],700,70,100)
+
+ #As the level has changed, gaps need to be updated again
+ updateGaps = 1
+
+ background.blit(copy, (100,850))
+ print "Now on level %d."%(levelNum)
+
+ #print clock
+ clock.tick(40) #limits to 40 FPS
+
+
+def main():
+ print "Running Tower"
+ run()
+
+
+#Given a number, returns a string representing the number, randomly formated into a short math equasion
+def stringFactor(number):
+ #The list which represents the string posibilities which will be chosen from later
+ choices = []
+
+ if number == 0: #special case if the number is 0, string possibilites are 0 times a number from 2~12
+ for i in range(13)[1:]:
+ choices.append("%dx%d"%(0,i))
+ choices.append("%dx%d"%(i,0))
+ else: # Number is non-zero
+ #Checks if the number is a multiple of 2~12x2~12, adds all possibilities to list
+ for i in range(13)[2:]:
+ if number%i == 0:
+ if 1 < number/i <= 12:
+ choices.append("%dx%d"%(i,number/i))
+
+
+ #Sees if no possibilities found yet:
+ if len(choices) == 0:
+ #Adds the number itself to choices multiple times to make that choice more likely
+ for i in range(6):
+ choices.append("%d"%(number))
+ #choices.append(u"%d\u00F75"%(number*5)) #Five times the number divided by 5
+ choices.append(u"%d\u00F72"%(number*2)) # Double the number divided by 2
+ if number<100:
+ choices.append("%dx10+%d"%(number/10,number%10))#expanded notation
+
+ #selects a single entry at random from the possible choices, and returns the string
+ return random.sample(choices,1)[0]
+
+
+# Executed once the player reaches the top of the tower
+def victoryCinematic(screen):
+
+ util.ok_box("You have reached the top of the tower!", (450,400), 300, 50, screen)
+
+def generateDropNumber(heroNumber,level):
+ #Randomly selects if the drop will have addition, subtraction, multiplication, or division, addition and subtraction being more likely
+ type = random.sample([0,0,0,0,0,0,1,1,1,1,1,1],1)[0]
+ levelAverage = (levelRanges[level][0]+levelRanges[level][1])/2
+ returnString = ""
+ if type == 0: #Addition drop
+ number = random.randint(2,15)
+ if heroNumber-levelAverage < -30:
+ number = random.sample([number,-number-heroNumber+levelAverage],1)[0]
+ returnString = "+%d"%(number)
+ elif type == 1: #Subtraction drop
+ number = random.randint(2,9)
+ if heroNumber-levelAverage > 30:
+ number = random.sample([number,number+heroNumber-levelAverage],1)[0]
+ returnString = "-%d"%(number)
+ elif type == 2: #Multiplication drop
+ number = random.randint(2,5)
+ returnString = "x%d"%(number)
+ elif type == 3: #Division drop
+ number = random.randint(2,5)
+ returnString = u"\u00F7%d"%(number)
+
+ return (type,number,returnString)
+
+#runs main if called via other naming convention
+if __name__ == '__main__': main() \ No newline at end of file