From 58cfda8a7eb690ff14e39697d7d1b5362697d382 Mon Sep 17 00:00:00 2001 From: Michael Kitson Date: Tue, 16 Nov 2010 09:32:07 +0000 Subject: Added TONS of comments, all epydoc compatible, with documentation sitting at mikekitson.com/pacmath --- diff --git a/dev/pacmath.activity/GhostMovement.py b/dev/pacmath.activity/GhostMovement.py index 3128664..7282dea 100644 --- a/dev/pacmath.activity/GhostMovement.py +++ b/dev/pacmath.activity/GhostMovement.py @@ -1,6 +1,6 @@ #! /usr/bin/env python """ -Creationg of enemy sprites and movement +Creation of enemy sprites and movement @license: U{http://creativecommons.org/licenses/by-sa/3.0/us/} """ @@ -10,10 +10,13 @@ import sys import random class ghostMovement(pygame.sprite.Sprite): - def __init__(self, position, g, q): + def __init__(self, g, q): """ Creates a Enemy sprite - @param position: location of enemy in maze + @type g: number 1-4 + @param g: The number identifying this ghost, used to associate image + @type q: question object + @param q: The question object (unused?) """ pygame.sprite.Sprite.__init__(self) self.name = 'Ghost' @@ -34,7 +37,7 @@ class ghostMovement(pygame.sprite.Sprite): self.screen = pygame.display.get_surface().get_rect() self.freezeTime = 0 #initialize the move instance - self.move = basicMovement(self) + self.move = basicMovement() # Create a variable to store the previous position of the sprite self.old = self.image.get_rect() @@ -48,6 +51,7 @@ class ghostMovement(pygame.sprite.Sprite): def randomMovement(self): """ Randomly generates the movement of the enemy + @rtype: [dx, dy] @return: returns the amount to move by """ on = 1 #0 is off and 1 is on @@ -91,8 +95,10 @@ class ghostMovement(pygame.sprite.Sprite): def update(self, screen, MAZE_SIZE, mazeObj): """ Updates enemy sprite using random movement + @type screen: pygame.display @param screen: the screen in which we will draw @param MAZE_SIZE: size of maze + @type mazeObj: Maze @param mazeObj: an instance of the maze """ # call basic movement and add any other update @@ -129,19 +135,39 @@ class ghostMovement(pygame.sprite.Sprite): pygame.display.update([self.old, self.rect]) def clearSelf(self, screen, mazeObj): + """ + Draws the grid square occupied by this ghost at the location in 'rect' + @type screen: pygame.display + @param screen: the screen in which we will draw + @type mazeObj: Maze + @param mazeObj: an instance of the maze + """ gridX = int(round(self.rect.x/MAZE_SIZE, 0) ) gridY = int(round(self.rect.y/MAZE_SIZE, 0) ) mazeObj.drawPoint(screen, gridX, gridY) pygame.display.update(self.rect) def drawSelf(self, screen): + """ + Draws this ghost's image onto the screen at the location in 'rect' + @type screen: pygame.display + @param screen: the screen in which we will draw + """ screen.blit(self.image, self.rect) pygame.display.update(self.rect) def freeze(self, time): + """ + Adds freezetime to this ghost, not letting it move for a given number + of 'update' calls + @param time: the number of update calls for which it should freeze + """ self.freezeTime += time def eaten(self): + """ + Called when this ghost is eaten, moving it back to spawn + """ self.rect.x = 300 self.rect.y = 300 self.move.moving = False diff --git a/dev/pacmath.activity/basicMovement.py b/dev/pacmath.activity/basicMovement.py index 404ce9e..43f0ec4 100644 --- a/dev/pacmath.activity/basicMovement.py +++ b/dev/pacmath.activity/basicMovement.py @@ -1,17 +1,43 @@ +""" +@license: U{http://creativecommons.org/licenses/by-sa/3.0/us/} +""" import pygame import sys from mazeSetup import mazeSetup class basicMovement(pygame.sprite.Sprite): - def __init__(self, position): + def __init__(self): + """ + Constructs a new basicMovement object + """ pygame.sprite.Sprite.__init__(self) self.moving = False def getMoving(self): + """ + Accessor for moving + @rtype: boolean + @return: moving + """ #for moving until the character reaches an intersection return self.moving - def update(self, screen, character, amount, MAZE_SIZE, mazeObj): + def update(self, screen, character, amount, MAZE_SIZE, mazeObj): + """ + Moves a character a given amount, handling wall collision detection + @type screen: pygame.display + @param screen: the screen in which we will draw + @type character: usually self, referring to a GhostMovement or pacmanMovement + @param character: the character on which the movement is performed + @type amount: [dx, dy] + @param amount: the amount to move in each direction + @param MAZE_SIZE: size of maze + @type mazeObj: Maze + @param mazeObj: an instance of the maze + @rtype: int + @return: 0 for no pacman event, 1 for small pellet eaten, 2 for power pellet eaten + """ + pacmanEvent = 0 # Make a copy of the current rectangle for use in erasing diff --git a/dev/pacmath.activity/gameMain.py b/dev/pacmath.activity/gameMain.py index a2e887b..d861bd7 100644 --- a/dev/pacmath.activity/gameMain.py +++ b/dev/pacmath.activity/gameMain.py @@ -2,7 +2,9 @@ """ Creates a game with maze and sprites and updates game @license: U{http://creativecommons.org/licenses/by-sa/3.0/us/} +@var game: The instance of gameMain @var done: when game is done it will equal true +@var BASE_LIVES: the number of lives with witch a player starts @var MAZE_SIZE: size of maze @var MAZE_DRAW_FRAME: size of maze to be drawn """ @@ -43,6 +45,9 @@ class gameMain: self.level = 1 def gameOver(self): + """ + Called to restart the game at level 1 when a player loses + """ self.level = 1 self.lives = BASE_LIVES self.score = 0 @@ -55,22 +60,29 @@ class gameMain: self.resetQuestion() def resetQuestion(self): - + """ + Generates and uses a new question set with a new operation + """ self.maze = mazeSetup(self.screen, MAZE_SIZE) # create an instance of the # maze->call the constructor self.operation = random.sample('x+-/', 1) self.questGen = questionGenerator( self.operation, 2, 12 ) self.QandA = question(self.screen, self.questGen.getQuestionSet()) - self.ghost1 = ghostMovement((self.screen.get_rect().x, self.screen.get_rect().y), 0, self.QandA.questions[0]) - self.ghost2 = ghostMovement((self.screen.get_rect().x, self.screen.get_rect().y), 1, self.QandA.questions[1]) - self.ghost3 = ghostMovement((self.screen.get_rect().x, self.screen.get_rect().y), 2, self.QandA.questions[2]) - self.ghost4 = ghostMovement((self.screen.get_rect().x, self.screen.get_rect().y), 3, self.QandA.questions[3]) - self.pacman = pacmanMovement((self.screen.get_rect().x, self.screen.get_rect().y)) + self.ghost1 = ghostMovement( 0, self.QandA.questions[0]) + self.ghost2 = ghostMovement( 1, self.QandA.questions[1]) + self.ghost3 = ghostMovement( 2, self.QandA.questions[2]) + self.ghost4 = ghostMovement( 3, self.QandA.questions[3]) + self.pacman = pacmanMovement() self.ghosts = [ self.ghost1, self.ghost2, self.ghost3, self.ghost4 ] self.nextQuestion() def nextQuestion(self): + """ + Updates the game to move on to a new question, if no more are available + in the current set, this calls resetQuestion and moves the player to + the next level + """ if self.QandA.nextQuestion(): self.wrongGhosts = pygame.sprite.Group() self.correctGhosts = pygame.sprite.Group() @@ -88,8 +100,8 @@ class gameMain: def update(self, event): """ Updates the maze and sprites given an event + @type event: pygame.event.Event @param event: directional key - @param frame: frame where game is held """ alreadyCollided = False # anything the needs to be update in the game loop @@ -113,12 +125,22 @@ class gameMain: self.freeze(30) def freeze(self, time): + """ + Frezzes all ghosts for a given amount of time + @type time: number + @param time: The number of update calls to stay still for + """ self.ghost1.freeze(time) self.ghost2.freeze(time) self.ghost3.freeze(time) self.ghost4.freeze(time) def checkCollisions(self): + """ + Checks for and handles collisions between ghosts and the player + @rtype: boolean + @return: if there was a collision + """ for ghost in pygame.sprite.spritecollide(self.pacman, self.correctGhosts,False): self.nextQuestion() self.QandA.updateLevel(self.screen, self.level) @@ -144,9 +166,15 @@ class gameMain: def unpause(self): + """ + Removes the pause overlay + """ self.QandA.drawQuestion(self.screen) def loop(self): + """ + Main game loop, handles user input and timing + """ done = False paused = False self.resetQuestion() diff --git a/dev/pacmath.activity/maze.py b/dev/pacmath.activity/maze.py index 4bc4dfc..1930a15 100644 --- a/dev/pacmath.activity/maze.py +++ b/dev/pacmath.activity/maze.py @@ -13,13 +13,13 @@ grid = [] class Maze: """ - @var EMPTY: An empty space in the maze where a regular pellet would be - @var SOLID: A wall representation in the maze - @var OFFL: A space off limits to pacmath character - @var PELLET: Where you could move and collect a regular pellet - @var PPL: The power pellet that would give a question - @var PELLET_INT: The intersection of a pellet - @var EMPTY_INT: An intersection of a pellet + @cvar EMPTY: An empty space in the maze where a regular pellet would be + @cvar SOLID: A wall representation in the maze + @cvar OFFL: A space off limits to pacmath character + @cvar PELLET: Where you could move and collect a regular pellet + @cvar PPL: The power pellet that would give a question + @cvar PELLET_INT: The intersection of a pellet + @cvar EMPTY_INT: An intersection of a pellet """ EMPTY = 0 #You can move around @@ -94,7 +94,8 @@ class Maze: #access the grid (or map) def getGrid(self): """Returns the grid instance - @return: a map of the grid + @rtype: 2d list + @return: the grid """ #simply returns the grid (or map) @@ -106,7 +107,8 @@ class Maze: coordinates, returns solid if it is off the grid @param x: the X parameter, may be off the grid @param y: the Y parameter, may be off the grid - @return the integer representing block type, use the class constants to determine what that means. + @rtype: number + @return: the integer representing block type, use the class constants to determine what that means. """ if x < 0 or y < 0 or x >= self.width or y >= self.height: return self.SOLID diff --git a/dev/pacmath.activity/mazeSetup.py b/dev/pacmath.activity/mazeSetup.py index 7d3930f..a1ee8c2 100644 --- a/dev/pacmath.activity/mazeSetup.py +++ b/dev/pacmath.activity/mazeSetup.py @@ -1,7 +1,7 @@ #! /usr/bin/env python """Setup the maze so it could be drawn in the screen @license: U{http://creativecommons.org/licenses/by-sa/3.0/us/} -@var FILLED: whether or nott the filled wall images are used +@var FILLED: whether or not the filled wall images are used """ import pygame @@ -17,7 +17,8 @@ class mazeSetup: def __init__ (self, screen, MAZE_SIZE): """ Initialize the maze setup - @param screen: the screen in which we will draw + @type screen: pygame.display + @param screen: the screen in which we will draw @param MAZE_SIZE: the size of the maze """ @@ -35,7 +36,8 @@ class mazeSetup: def drawPoint(self, screen, x, y): """ Draw a certain point of the maze on the screen - @param screen: the screen to draw in + @type screen: pygame.display + @param screen: the screen to draw in @param x: the x coordinate of the maze map @param y: the y coordinate of the maze map """ @@ -80,7 +82,8 @@ class mazeSetup: def drawMaze(self, screen, MAZE_SIZE): """ Draw the whole maze - @param screen: the screen to draw into + @type screen: pygame.display + @param screen: the screen to draw into @param MAZE_SIZE: the maze size """ @@ -97,7 +100,8 @@ class mazeSetup: plots @param x: x coordinate @param y: y coordinate - @return a converted image + @rtype: loaded, converted image + @return: The correct wall image for the given plot """ file = 'EMPTY' @@ -153,6 +157,12 @@ class mazeSetup: else: return False - def redrawMaze(self, screen, mazeSize = 25): - self.drawMaze( screen, mazeSize ) + def redrawMaze(self, screen, MAZE_SIZE = 25): + """ + Draws the whole maze and updates the display + @type screen: pygame.display + @param screen: the screen to draw into + @param MAZE_SIZE: the size of the maze + """ + self.drawMaze( screen, MAZE_SIZE ) pygame.display.update(0,0,625,625) diff --git a/dev/pacmath.activity/pacmanMovement.py b/dev/pacmath.activity/pacmanMovement.py index 30e3eba..5ca8667 100644 --- a/dev/pacmath.activity/pacmanMovement.py +++ b/dev/pacmath.activity/pacmanMovement.py @@ -9,10 +9,9 @@ import pygame import sys class pacmanMovement(pygame.sprite.Sprite): - def __init__(self, position): + def __init__(self): """ Creates a PacMath sprite - @param position: location of pacmath in maze """ pygame.sprite.Sprite.__init__(self) self.name = 'PacMath' @@ -23,7 +22,7 @@ class pacmanMovement(pygame.sprite.Sprite): self.screen = pygame.display.get_surface().get_rect() #initialize the move instance - self.move = basicMovement(self) + self.move = basicMovement() self.image = {} self.image[0] = pygame.image.load('./images/pacmanu.png').convert_alpha() @@ -44,8 +43,10 @@ class pacmanMovement(pygame.sprite.Sprite): """ Updates Pacmath sprite when directional key is pressed @param screen: the screen in which we will draw + @type event: pygame.event.Event @param event: directional key @param MAZE_SIZE: size of maze + @type mazeObj: Maze @param mazeObj: an instance of the maze """ # call basic movement and add any other update @@ -103,11 +104,23 @@ class pacmanMovement(pygame.sprite.Sprite): return pacmanEvent def clearSelf(self, screen, mazeObj): + """ + Draws the grid square occupied by pacman at the location in 'rect' + @type screen: pygame.display + @param screen: the screen in which we will draw + @type mazeObj: Maze + @param mazeObj: an instance of the maze + """ gridX = int(round(self.rect.x/MAZE_SIZE, 0) ) gridY = int(round(self.rect.y/MAZE_SIZE, 0) ) mazeObj.drawPoint(screen, gridX, gridY) pygame.display.update(self.rect) def drawSelf(self, screen): + """ + Draws pacman's image onto the screen at the location in 'rect' + @type screen: pygame.display + @param screen: the screen in which we will draw + """ screen.blit(self.images[self.imageIndex], self.rect) pygame.display.update(self.rect) diff --git a/dev/pacmath.activity/question.py b/dev/pacmath.activity/question.py index 5dd01c9..68c90df 100644 --- a/dev/pacmath.activity/question.py +++ b/dev/pacmath.activity/question.py @@ -8,18 +8,18 @@ import random class question: """ - @var A: Properties of answer box [color, (left, top), center, ghost location] - @var B: Properties of answer box [color, (left, top), center, ghost location] - @var C: Properties of answer box [color, (left, top), center, ghost location] - @var D: Properties of answer box [color, (left, top), center, ghost location] - @var SIZE: Size of answer box - @var QUESTION_COLOR: the rgb color in which question text is written + @cvar A: Properties of answer box [color, (left, top), center, ghost location] + @cvar B: Properties of answer box [color, (left, top), center, ghost location] + @cvar C: Properties of answer box [color, (left, top), center, ghost location] + @cvar D: Properties of answer box [color, (left, top), center, ghost location] + @cvar SIZE: Size of answer box + @cvar QUESTION_COLOR: the rgb color in which question text is written """ # Properties of rectangles: [color, (left, top), center, ghost location] - A = [(0, 180, 255), (625, 0), (735, 15), "./images/ghost.png"] - B = [(253, 0, 1), (625, 79), (735, 94), "./images/ghost2.png"] - C = [(255, 124, 0), (625, 158), (735, 173), "./images/ghost3.png"] - D = [(255, 0, 192), (625, 237), (735, 250), "./images/ghost4.png"] + A = [( 0, 180, 255), (625, 0), (735, 15), "./images/ghost.png"] + B = [(253, 0, 1), (625, 79), (735, 94), "./images/ghost2.png"] + C = [(255, 124, 0), (625, 158), (735, 173), "./images/ghost3.png"] + D = [(255, 0, 192), (625, 237), (735, 250), "./images/ghost4.png"] # Size of rectangles @@ -31,8 +31,9 @@ class question: def __init__ (self, screen, quests): """ Randomly selects which questions are going to be used and draws the answer + @type screen: pygame.display @param screen: the screen in which we will draw - @param quests: array a questions with answers + @param quests: list of questions with answers """ # Draw the answers and questions self.questions = quests @@ -47,6 +48,11 @@ class question: self.screen = screen def nextQuestion(self): + """ + Moves on to a new question to answer from this question set. If the set has been exhausted, false is returned + @rtype: boolean + @return: True if the question set had enough questions, false if a new one needs to be generated + """ if(len(self.answered) > 3): return False else: @@ -60,6 +66,7 @@ class question: def drawAnswers(self, screen): """ Draws all answers in their color coded boxes + @type screen: pygame.display @param screen: The screen on which to draw """ for i in range(4): @@ -69,7 +76,9 @@ class question: def drawAnswer(self, screen, answer, choice): """ Draws answers in a color coded box + @type screen: pygame.display @param screen: the screen in which we will draw + @type answer: string @param answer: answer to be drawn @param choice: which choice from 1-4 """ @@ -110,10 +119,21 @@ class question: pygame.display.update(total) def clearAnswers(self, screen): + """ + Clears the answers off the screen + @type screen: pygame.display + @param screen: the screen in which we will draw + """ for i in range(3): self.clearAnswer( screen, i ) def clearAnswer(self, screen, number): + """ + Clears a specified answer off the screen + @type screen: pygame.display + @param screen: the screen in which we will draw + @param number: which answer to clear + """ pos = (625, number*B[1][1]) dim = SIZE rect = pygame.rect.Rect(pos, dim) @@ -124,6 +144,7 @@ class question: def drawQuestion(self, screen): """ Draws the question to the screen + @type screen: pygame.display @param screen: the screen in which we will draw """ # Font used @@ -141,6 +162,7 @@ class question: def drawPaused(self, screen): """ Writes 'Paused' over where the question is usually printed + @type screen: pygame.display @param screen: the screen on which we will draw """ # Font used @@ -157,6 +179,7 @@ class question: def clearBottom(self, screen): """ Draws a black box over the question-holding part of the screen + @type screen: pygame.display """ blackBox = pygame.Surface((600,60)) blackBox.fill((0,0,0)) @@ -166,7 +189,8 @@ class question: def getAnswerIndex(self): """ Returns the integer index of the correct answer - @return the index + @rtype: number + @return: the index """ return self.answerIndex @@ -174,7 +198,9 @@ class question: def updateLives(self, screen, count): """ Redraws the lives display onto the screen + @type screen: pygame.display @param screen: the screen on which to draw + @type count: number @param count: the number of lives we have """ self.clearLives(screen) @@ -196,6 +222,7 @@ class question: def clearLives(self, screen): """ Draws a black box over the lives display so we may redraw them + @type screen: pygame.display @param screen: the screen on which to draw """ blackBox = pygame.Surface((300,30)) @@ -206,6 +233,7 @@ class question: def updateScore(self, screen, score): """ Redraws the score onto the screen + @type screen: pygame.display @param screen: the screen on which we will draw @param score: the score to be drawn """ @@ -218,6 +246,7 @@ class question: def clearScore(self, screen): """ Draws a black box over the score display so that we may redraw it + @type screen: pygame.display @param screen: the screen on which to draw """ blackBox = pygame.Surface((300,30)) @@ -228,8 +257,10 @@ class question: def updateLevel(self, screen, level): """ Redraws the score onto the screen + @type screen: pygame.display @param screen: the screen on which we will draw - @param score: the score to be drawn + @type level: number + @param level: the level to be drawn """ self.clearLevel(screen) @@ -240,6 +271,7 @@ class question: def clearLevel(self, screen): """ Draws a black box over the score display so that we may redraw it + @type screen: pygame.display @param screen: the screen on which to draw """ blackBox = pygame.Surface((275,30)) diff --git a/dev/pacmath.activity/questionGenerator.py b/dev/pacmath.activity/questionGenerator.py index a612077..0fe42de 100644 --- a/dev/pacmath.activity/questionGenerator.py +++ b/dev/pacmath.activity/questionGenerator.py @@ -9,16 +9,13 @@ import pygame class questionGenerator: """ A reusable object which is used to generate questions - @var operation: The operation that the math questions will incorporate - @var minOp: The minimum allowable value for an operand - @var maxOp: The maximum allowable value for an operand """ def __init__(self, operation, minOp, maxOp): """ Constructor - @var operation: The operation that the math questions will incorporate - @var minOp: The minimum allowable value for an operand - @var maxOp: The maximum allowable value for an operand + @param operation: The operation that the math questions will incorporate + @param minOp: The minimum allowable value for an operand + @param maxOp: The maximum allowable value for an operand """ self.minOp = minOp self.maxOp = maxOp @@ -28,7 +25,8 @@ class questionGenerator: """ Returns a single question based on the constraints the generator was created with - @return A tuple contining two strings: ("question", "answer") + @rtype: ("q", "a") + @return: A single question answer tuple """ op1 = randint(self.minOp, self.maxOp) op2 = randint(self.minOp, self.maxOp) @@ -54,7 +52,8 @@ class questionGenerator: Fails and exits if four questions with distinct answers cannot be generated from this constraint set (eg minOp = 2, maxOp = 3: only 2 * 2, 2 * 3, 3 * 3) - @return A list with four questions in the form ("question", "answer") + @rtype: [("q", "a"), ("q", "a"), ("q", "a"), ("q", "a")] + @return: A list of four questions with no repeat answers """ questions = [] attempts = 0 -- cgit v0.9.1