COSC 3P91

Assignment 3

Instructor: Michael Winter, Office J323, email: mwinter@brocku.ca


RoboRace (Part 3)

In this assignment you are going to use XML and multiple threads. The communication between the threads will use the Producer-Consumer design pattern. Each message send is an XML string that has to be parsed before it can be used.

EventReader

Implement the class EventReader (package roborace.client). The node passes into convertXMLNode is supposed to represent an event as XML. Create the corresponding event and return this value.
Remarks:
  1. Use the static method getChildNodes(node) from the class COSC3P91.xml.XMLTools and not the method node.getChildNodes().
  2. To access a direction attribute use (Direction) getEnumAttribute(Direction.class,node,"direction").
  3. Use an CardReader to parse a card.
  4. Test your implementation. You find a class for testing here. By creating different events in the main program you should test implementation throughly. This will prevent that errors in this code cause problems in later parts.

EventListReader

Implement the class EventListReader (package roborace.client). The node passes into convertXMLNode is supposed to represent an event list as XML. Create an event list and return this value.
Remarks:
  1. Use the static method getChildNodes(node) from the class COSC3P91.xml.XMLTools and not the method node.getChildNodes().
  2. Use an EventReader to parse individual events.
  3. Test you code similar to above.

execute in all subclasses of Event

The execute method of all subclasses of Event (package roborace.client not roborace.server) have to be implemented as follows:
  1. EventBump: Call the method bump of the corresponding RobotSprite.
  2. EventCardEnd: Call the method waitOnAnimations of the board, then sleep for 1sec (1000ms), then call waitOnSingleStep of the infoPane, and finally set the infoPane to display no information (method displayNoInfo).
  3. EventCardStart: Call the method displayCardInfo of the infoPane.
  4. EventDestroyed: Call the method destroyed of the corresponding RobotSprite.
  5. EventEffectEnd: Same as EventCardEnd.
  6. EventEffectStart: Call the method displayEffectInfo of the infoPane. In addition, start the decoration at the corresponding position if the variable isDecorationEffect is true.
  7. EventRevitalize: Call the method revitalize of the board.
  8. EventRunDecorations: First call the method displayRunDecorationsInfo of the infoPane. Then run the decorations and wait for the animations using the corresponding methods of the board. Finally, wait on single step, display no information and increase the phase by calling the corresponding methods of the infoPane/
  9. EventStep: Call the method step of the corresponding RobotSprite.
  10. EventTurn180: Call the method turn180 of the corresponding RobotSprite.
  11. EventTurn90: Call the method turn90 of the corresponding RobotSprite.
  12. EventVictory: No implementation.
  13. EventWait: Call the method waitOnAnimations of the board.

Communication

The communication between the GameMaster and the players will be using channels (class roborace.common.Channel). A Channel is a class with two Queues for bidirectional communication. Once created each Channel can provide two Ports (methods asPort1() and asPort2()), one for each participant in the communication. The ports allow easy communication by providing the methods send and receive for sending and receiving messages. During set up the GameMaster receives an array of Ports , one port for each player, and each player receives one Port for communicating with the GameMaster. The diagram below shows the set up.

Player

The class Player (package roborace.client) is a thread that runs the client side of the program. Implement its run() method as follows:
  1. First receive the board via the port and store it in the variable board. Then call the private method init()
  2. Then loop until the game is at end, i.e., the event list contains a victory event, doing the following:
    1. Receive the card list from the port. Use CardList.read(new StringReader(port.receive()));
    2. Select cards by calling the selectCards method of the cardPane.
    3. Send the selected cards via the port. Use port.send(cards.toXMLString());
    4. Receive the event list from the port. Use EventList.read(new StringReader(port.receive()));
    5. Reset the phases of the infoPane and execute the event list.
  3. After leaving the loop above display the winner using a game dialog and close the player. Use GameDialogs.showMessageDialog("Title","Text",this);
Remark: In order to get the name of a player with ID id, you call board.getRobotByID(id).getName(). The ID of the winner at the end of the game can be obtained by calling getWinnerID() of the event list.

GameMaster

The class GameMaster (package roborace.server) has to be changed by replacing every method call to a player with a communication via the corresponding port. The methods calls are currently placed into a comment environment. Make sure that every player receives a card list before you try to collect the selected cards from each player.

RoboRace

In the main class RoboRace (package roborace) do the following:
  1. Create a channel for each player.
  2. Construct a player by passing in one port of the channel.
  3. Collect all other ports in an array that you use to construct the GameMaster.
  4. Start the player threads and call run() of the GameMaster.

Sources


COSC Home Page
COSC 3P91 Home Page
© M. Winter, 2023