C Sc 335 Project: RoboSim, 2nd to last iteration

Collaboration: You may complete this project with one other student registered in CSc 335 Fall 2010. You will be building upon code written by section leaders and are required to turn in that code as part of your project. First turn in: 19:00 Tuesday 19-Oct

Introduction: RoboSim is a computer game in which players can build robots and pit them against each other for cash and glory. For this project, you will be starting with a working version of a system that only fulfills part of the desired capability. A previous team implemented the first 3 iterations of RoboSim. You will implement two more iterations of RoboSim to completion. First, let's understand where we're at by considering a few objects that are already part of our system.

Player: RoboSim has instances of the Player class to represent human and computer players. Through this class, players will be able to control and manage their robots. A Player has a Garage where they store inactive robots as well as an active instance of the Robot class which they will control. A Player has a changeMoney(int) method, which adds the given value to the player’s money and return true if this leaves the player with >=0 money. If adding the given amount of money leaves the player with a negative amount, changeMoney returns false.

Robots and their Parts: Robots are the main actors in RoboSim. A Robot is constructed with a String as its name, a Point as its position, and an int as its space available for equipment. A robot's equipment consists of some Armor, a Reactor, and a Weapon. All parts are constructed with three arguments: an int, a String, and another int. An instance of the Weapon class is immutable (no methods can change the state).

Reactors and Armor have two int values: a ‘max’ value and a ‘current’ value. Initialize these to the 1st value passed in the constructor. The last few methods listed in the UML do the same for both of these. One depletes the current value by the given value, one increments it by the given value, and one returns true if the current value is <=0.

A Robot is dead if its Reactor is drained or if its Armor is destroyed (or both). A Robot has a Point which represents their location. The move(int x, int y) method expend energy and add the given value to the Point’s x and y values. For more information on Point, see the Java API.

RoboSim: Advanced Swing and Command Pattern

First things to do:

  • Read this spec for the first part of RoboSim you will implement: Advanced Swing and Command Pattern
  • Peruse the two UML Diagrams that show
  • Current Design
  • Desired Design (by the end of part B when it is all completed)
  • One person get the beginning of RoboSim as an Eclipse Java Project and import it into one team member's workspace RoboSimBegin.zip
  • Read about getting a cvs repository and have that one person share this project to the Computer Science cvs repository. Have your teammate check it out. You don't need to synchronize at first.

RoboSim users can now create their own robots, but they have no way to pit them against each other. In this assignment, you will create a fully functional single-player GUI which allows a player to move their robot on a grid and interact with traps and blocks in the arena.

Moving Towards Multiplayer

To simplify the transition from single-player to multiplayer, interaction will take place through the use of various command objects. Each command object will implement the Command interface. Any action which needs to take place over a network can be expressed as a subclass of Command, and the action can be performed simply by calling the execute() method with the current Arena. You will need to implement the following Commands:

  • TurnCommand: This command encapsulates everything about a player's turn. Once a player's turn is complete, they will construct a TurnCommand object containing the name of the Robot to be moved, the location to move it, and a Hit (if any) to be applied after the move.
  • AddBotCommand: This command will add a new Robot to a random empty location in the Arena.

Commands will need to add messages to the Arena's message log as well. The format for these messages is shown in the GUI mock-up below. Commands should only be executed by the doCommand() method in Arena.

Arena Changes

Add a doCommand(Command) method to Arena. This method allows us to give the Arena complex orders by way of Command objects. These orders will include adding robots, moving robots, and dealing damage.

The Arena must now be able to log certain status messages. Specifically, the Arena should log messages about adding robots, moving robots, and dealing damage. The addMessage(String) method adds a new message to the log and the getMessageLog() method returns a list of all messages in the log, preserving the order in which the messages were added.

The Arena should also extend Observable. The Arena will be the Model for this GUI. Call setChanged() and notifyObservers() whenever Arena executes a command.

Amend addActor() to update the position of the ArenaActor it is passed if that ArenaActor is already in the Arena.

GUI

Earlier you used a series of basic Swing tools to create a simple GUI. Now that you have been introduced to Swing, you'll be using more tools to create a more complex GUI with more complex user interaction. The GUI (ArenaFrame) will be divided into 3 main parts: the Grid, the Status Text, and the Player Status (described next).

Grid

The Arena will always be an 8X8 grid. Represent this as a JPanel 400 pixels wide by 400 pixels tall. Override paintComponent() to draw graphics on the JPaneluse a MouseListener to detect mouse clicks. It is also acceptable to represent the grid with other components, but they must react in the same manner.

Clicks will correspond to Arena coordinates, and the user will click on a grid location to cause his Robot to move or attack. If the location is empty, the Robot will move (if it is able). If the location contains a Destroyable, the Robot will attack it (if it is able). If the Robot cannot perform the requested action, add a message to the status text to alert the user. Once the user is done, they will click the "End Turn" button, which will create a TurnCommand summarizing their move. Have the Arena execute this command.

ArenaActor instances on the grid will be represented by simple images. We will provide images to you, or you may create your own. Add an abstract method (getActorImage()) that returns a BufferedImage. In each subclass of ArenaActor, implement this method to return the relevant image.

Status Text

Your GUI must have a scrollable text component for status text to appear. This area must always display the most up-to-date version of the Arena's message log. You may also use it to display errors, but error text does not need to persist between updates.

Player Status

Users must be able to see their status and the status of their robot. Using any Swing Components you like, list the Player's name, cash on hand, number of Robots in the Player's Garage, and Player's active Robot.

For the Player's active Robot, also list the Robot's current armor and energy. Below this information, show a JList of all other robots in the Player's Garage. Provide a JButton (with text "Build Bots") which opens a GarageFrame, passing the current Player as the argument to the constructor.

Here is a mock-up of the specified GUI:

On starting the GUI, there should be no default Player. Instead, create a JMenuBar with a "Game" JMenu. This menu should have the following options:

  • Create New Player – Creates a new Player which populates all fields. You will need to prompt the user for their name, and open a GarageFrame with at least 3 of each type of RoboPart. Design your own parts, but make sure a new player has enough money to build a decent Robot.
  • Start Game – Causes the GUI to populate with Player information and a new game to start. If a new Player has not been created, this option should be disabled.
  • About – Displays the names of you and your partner as well as a short description of this GUI.
  • Close – Closes the GUI and terminates the program.

You don't need to populate the status text or any of the fields concerning the Player's status until a game has been started. You may use JOptionPane dialog boxes to prompt the user for the requisite information.

Exceptions / Dirty Input

All input fields in your GUI should be ready to handle dirty input. Expect strings when you ask for integers and nulls when you ask for strings. Check for this! You should now have the skills required to catch and handle any exceptions caused by dirty input. Robustness and error handling will be graded on this and future assignments.

Turn in

Create a .zip archive of your project and turn it in to D2L Drop Box Swing_Command with the format

<Partner1 last name>_<Partner2 last name>_Robo1.zip

Where Partner1's last name comes before Partner2's alphabetically.

Grading Criteria50 Points (subject to change)

+5GUI Layout as prescribed / Close and BuildBot work

+5Start Game populates GUI

+5About shows partner information

+10Create New Player/Robot works

+25Moving Bots and Attacking with bots works correctly via a TurnCommand object

1