CS1110 2017sp Assignment 5

Due on CMS by Wednesday May 10th, 2017, 11:59pm

Updates

Tip

Click on the title of the update to see the contents / how to apply it.

Tip

If you have not had trouble, you do not need to update anything!

  1. Some students have been having trouble with the splash images. The actual cause is unknown, but a “simple graphics mode” has been enabled to circumvent this. The new controller.py now has a boolean at the top controller.USE_FANCY_GRAPHICS — set this to False if the splash messages were not displaying. Screenshots of what they should look like for your reference in 5   Screenshots of Game Stages.

  2. Since we were releasing another update, I decided to add the ability to replay the game when it is finished :) In addition to the new controller.py, in order to enable the Replay feature, you will need to edit the very bottom of model.py. This is included in the new release, but be VERY careful not to overwrite your existing solutions!!! Instead, you can perform this easy edit on your own, which amounts to adding two lines. The very last method in model.py is keyReleaseEvent(self, e):. The implementation used to be

    key = e.key()
    if key == QtCore.Qt.Key_W:
        self.citizenPac.queueMove(constants.MOVE_NORTH, False)
    elif key == QtCore.Qt.Key_S:
        self.citizenPac.queueMove(constants.MOVE_SOUTH, False)
    elif key == QtCore.Qt.Key_D:
        self.citizenPac.queueMove(constants.MOVE_EAST, False)
    elif key == QtCore.Qt.Key_A:
        self.citizenPac.queueMove(constants.MOVE_WEST, False)
    elif key == QtCore.Qt.Key_Space:
        self.controller.gameRunningSwitched()
    else:
        super(Scene, self).keyPressEvent(e)
    

    and is now

    key = e.key()
    if key == QtCore.Qt.Key_W:
        self.citizenPac.queueMove(constants.MOVE_NORTH, False)
    elif key == QtCore.Qt.Key_S:
        self.citizenPac.queueMove(constants.MOVE_SOUTH, False)
    elif key == QtCore.Qt.Key_D:
        self.citizenPac.queueMove(constants.MOVE_EAST, False)
    elif key == QtCore.Qt.Key_A:
        self.citizenPac.queueMove(constants.MOVE_WEST, False)
    elif key == QtCore.Qt.Key_Space:
        self.controller.gameRunningSwitched()
    elif key == QtCore.Qt.Key_R:  # <<< Add this line
        self.controller.replay()  # <<< and this line
    else:
        super(Scene, self).keyPressEvent(e)
    

Note

Simply re-download the source code (a5.zip), extract it in a different directory than where you are writing your solutions, and replace controller.py with the updated version. Instead of overwriting the model.py, make the two line additions for replay ON YOUR OWN so that you do not accidentally delete your solutions. If you do not update the two lines in model.py, it will say “Press <R> to replay!” when you win / lose, but nothing will happen.

  1. The view.actors.Food.reset() function was resetting the wrong variable. It used to be

    self.outerRadius = 360.0
    self.innerRadius = 0.0
    self.decreasing  = False
    super(Food, self).reset()
    

    and is now

    self.outerSweep = 360.0
    self.innerSweep = 0.0
    self.decreasing = True
    super(Food, self).reset()
    
  2. Minor docs updates in the SplineDrawer and CitizenPacMainWindow classes.

  1. The documentation for model.Scene.reset() has been updated to rectify inconsistencies.

    The documentation used to say:

    This method resets the game state for the actors that change locations. It should not modify any instances directly, rather, call the view.actors.Actor.reset() for the appropriate entities of this instance.

    the updated documentation now says

    This method resets the game state for all actors in the scene, and ensures that all food becomes edible again. This method should not modify any instances directly — call the view.actors.Actor.reset() for the appropriate entities of this instance.

    Tip

    You are encouraged to refer to the implementation of model.Scene.advance(), in addition to the parent class documentation of view.actors.Actor, to complete making food edible.

  2. As there were previously conflicting specifications for reset, we have updated the controller.py and view/display.py with some minor but helpful updates:

    1. When students had an infinite loop in their implementation of the generateFoodGrid function and clicked away from the window, the program crashed. This was fixed by changing the controller.appLostFocus() function to verify that both self.scene and self.scene.citizenPac are not None. This is necessary because they have not been created yet.

      if self.scene and self.scene.citizenPac:  # this line added
          self.scene.citizenPac.setStationary() # this line indented
      
    2. Game state consistency changes. The following updates are VERY helpful for you to make sure that you have correctly reset the scene. Various small changes were made to controller.py and view/display.py so that when the game resets

      1. The score should be set to zero, assuming you have reset everything you should be correctly
      2. The speed boost progress bar should be set to zero, assuming you have reset everything you should be correctly.

      Tip

      Simply re-download the source code (a5.zip), extract it in a different directory than where you are writing your solutions, and replace controller.py and view/display.py with the updated versions. You must update both, not just one or the other.

  3. ALL METHODS HAVE NOW BEEN DOCUMENTED :)

  1. We forgot to say: when you write any while-loops, you must document the meaning of any variables that you create to use in the loops, using the notation for invariants we’ve been going over in class. Write this documentation as comments in the appropriate places in your while-loops.

  2. model.py, model.generateFoodGrid(): A few more words about the variables we computed for you. We stated in the specifications that dx and dy correspond to the change in position \(\Delta x\) and \(\Delta y\), respectively, and tx and ty in the code correspond to the global translation \(t_x\) and \(t_y\), respectively.

    This means that the centers of “adjacent” food items should be separated by \(\Delta x\) in the x direction and \(\Delta y\) in the y direction.

    Furthermore, we mention in section 4.2 of the assignment writeup the problem of food items getting placed beyond the visible board boundaries. More specifically, you might think that you want to have food with x-coordinates 0, dx, 2*dx, 3*dx, and so on. But, this would put all the food on the right-hand half of the board. The solution is that we can translate (shift) those x-coordinates by the negative number tx, yielding tx, dx + tx, 2*dx + tx, and so on. This shift leftwards should bring all the food items onto the board.

  3. controller.py: a line needs correcting. If you downloaded the assignment files before about 9pm Wed May 3, then line 292 (in the method errorOut) needs to be changed to self.gameRunning = False (the incorrect outdate code refers to self.gameWon) Optional: see this Piazza post for what problem this change prevents.