/**********************************
 * Assignment 5: Pacman 
 * Date: 5/6/07
 * 
 * Eric Wolff: emw56, 1847050
 * Mike Chow: mcc59, 1847995
 **********************************/


How to compile and run:
  As provided.


4.1 Scoring
Classes Edited: Actor, Ghost, Token, Game, GUI, Constants

In order to keep track of the score, we created a static variable in Game that is initially set to 0. It is static so that the score is maintained even when the player progresses to the next level. We then added a score varible to the Actor class so that every class that extends it would have a score variable. In the Ghost and Token class, we set the score values for when Pacman ate a vunerable Ghost or Token (big or small). These values are listed in the Constants file. Finally, the GUI gets the score and displays it.


4.2 Lives
Classes Edited: Game, GUI, Constants

In order to keep track of the lives, we created a static variable in Game that is initially set to the initial number of lives in Constants. For each time, Pacman collided with a non-vunerable Ghost, the number of lives remaining was decremented. The GUI would then get the number of lives remaining from Game and display the correct number of Pacman lives remaining.


4.6 High Scores
Classes Edited: Game, GUI

As soon as a new Pacman game is opened, the GUI class reads the high scores into a static ordered ArrayList. The high scores are displayed with a JList. If there isn't a high scores file, then default values will populate the empty spots in the list. The static ordered ArrayList is then passed to the Game constructor. After the game has ended, we implemented a method in the Game class to see if the player's current score is eligible for the high scores list. If it is then a method in the Game class inserts it into the correct position in the ArrayList. Finally, the Game class writes the high scores in the ArrayList to a text file.


4.7 & 4.2 Splash Screen & Game Over

Classes Modified: GUI, Background
Classes created: OpeningScreen, OpeningDialog, HighScoresPanel

We created a custom dialog (OpeningDialog) that is created in the GUI class and launched before the actual game. OpeningDialog allows the user to pick a one player, two player, or AI game, and the level of difficulty. This was done with a JDialog because these values needed to be known before a new Game was instantiated. Thus, a new Game can be constructed with the user provided parameters. OpeningScreen is the content pane for OpeningDialog. It contains a list of high scores that is read from a text file and into an ArrayList, a choice of game options, and a new Game button. Once the game has ended, the Game class displays a dialog stating the game is over and it displays the OpeningDialog so that the user can start a new game. The Background class was modified so that it would display the level number before the start a new level. This is done with a static variable that keeps track of the level number in the PacmanMap class.


Mute
Classes Modified: GUI

We created added a JCheckBox to the control panel in GUI in order to enable or disable the sound. We created a new ItemChangeListener that detected when the checkbox was checked and it would set the boolean "silent" variable to true or false depending on whether or not the checkbox is checked. It then refocuses on the GUI frame.


4.3 2 Pacmen
  Classes modified: Constants, Game, GUI, AIPlayer, Background
  Classes created: LocalPlayer2

We made another class LocalPlayer2 that extended LocalPlayer.  We changed it so that its keylistener would respond to the WASD keys.  In addition, we made new Ms. Pacman images in Constant and used these for the 2nd pacman. We added a static boolean variable 'twoPlayers' in GUI. This value is set by the user from the Splash Screen. This value is passed to the Game constructor which assigns the value to the boolean variable 'twoPlayers' in Game. If this is true, we initialize the 2nd pacman in the Game constructor.  We also made a method in Game 'isTwoPlayers' so that we could find out if there are two players for checking collisions (Game), updating locations (GUI), painting components (Background), and moving the ghosts (AIPlayer).  We programmed the ghosts to compute paths to both pacmen and take the shortest path. 


4.4 Levels
  Classes modified: Constants, GUI, Token, PacmanMap, AIPlayer, Background
  Classes created: 

We added 3 more levels to the game.  In Constants, we made an array holding all of the level names as strings.  We then made a static int in PacmanMap to determine the level number.  This is incremented after every call to the Pacman Map constructor.   The map loaded is equal to the array index of the level number.  We made a static variable in Token that kept track of the number of visible tokens left.  This is incremented in the constructor and decremented when a token is eaten by pacman.  When all of the tokens are eaten, we shut down all of the old threads, dispose of the window, and call a new instance of GUI.  Since the level number is static and incremented by 1 in the PacmanMap constructor, we go to the next level.  When there are no more levels left and we have won, we reset the level number variable to 0.  Also, we increase the calculation interval of the ghosts (AIPlayer) as the user increases levels to make them slightly harder. The level is also passed into the Background class so that it knows what level the user is on when it displays the mid-level splash screen.

4.5 Scaling of AI of ghosts
  Classes modified: AIPlayer, MapGraph, GUI

  We included radio buttons on the start up screen so the user can select the difficulty that they want.  There are two static variables in GUI, 'isEasy' and 'isHard.' If the Easy button on the start up screen is selected, isEasy is set to true, isHard is set to false and the ghosts will be slightly slower. If Hard is selected the boolean values are reversed. If Medium is selected, both booleans are set to false. AIPlayer contains its own local set of isEasy and isHard booleans that are assigned the value of the booleans from GUI.  Every time that the moveGhosts() method is called in AIPlayer, we reweight the edges on the graph near the ghosts.  We creted a method in MapGraph setEdgeWeight() to do this. Then we calculate the shortest path by using Dijkstra's algorithim, and finally we reset the changed edge weights to the default.  If the user selects the easy setting, the edges around the ghosts will have less weight than the usual edges.  This makes the ghosts tend to cluster, and makes it really easy to avoid them.  If the user selects the normal setting, the edges near the ghosts have the same weight, so they behave as in the solution code.  If the user selects the hard setting, the edges near the ghosts have increased weight.  This makes the ghosts not want to be near each other, so they spread out and corner pacman.  Also, we increase the amount by which we weight the edges near the ghosts with every level.  This makes the ghosts tend to spread out more as the level number increases, regardless of their initial difficulty.  The final level on the hard setting is quite difficult.

4.10 AI Pacman
  Classes modified: PacmanMap, GUI
  Classes created: AIPacman   

  We created a new class AIPacman that extended Player.  The computer controlled pacman moves by finding the shortest path between it and its destination.  The nodes at the corners of the map are its destinations, and upon reaching one, it sets off for another.  At every call of moveAIPacman(), we find the location of the ghosts and greatly increase the edge weights around them and their neighbors.  We also decrease the edge weights around tokens.  This makes it so that pacman avoids the ghosts and tends to go for the tokens when the shortest path is calculated.  After this is calculated, we reset the edge weights so that the state of the graph remains constant.  On a side note, in the PacmanMap constructor we found the warp points and linked them together with an edge so that the computer controlled pacman would use the warp points.
The user can select if they want an AI Pacman from the splash screen. If they choose an AI Pacman, then the static variable in GUI, 'isAI' is set to true. It is then passed to the Game constructor.

4.13 "All your base are belong to us!"
Classes modified: Game

  If you lose all your lives, you see this on the game over screen.

