BasicSoldier Class: The four constants below represent the relative fighting attributes of all soldiers of this class. These attributes dictate what happens when a soldier of this class attacks someone or is attacked by someone. The intricacies of how these constants are interpreted internally will remain our secret — you will have to experiment to see what combinations work well.
We have started you with an empty shell for this class. Look in the package called fighters and you will find it. When complete, your BasicSoldier class must contain the following public members.
final static constants
The four constants below represent the relative fighting attributes of all soldiers of this class. These attributes dictate what happens when a soldier of this class attacks someone or is attacked by someone. The intricacies of how these constants are interpreted internally will remain our secret — you will have to experiment to see what combinations work well. The numerical values listed below are just an example — You may assign these four attributes any values you want (between 1 and 97), but they must add up to 100 total . These variables are static because all soldiers in the class share the same attributes. They are final because they never change while the program runs.
The additional constants below will be used by your methods when they need to specify a direction. Do not modify the numerical values!
You may add final static constants of your own, but you are forbidden from adding static variables that are not final.
Each soldier has his own copy of these variables. All of these variables will be initialized in the constructor for the class. You may add other instance variables, if you choose to.
You must implement a constructor with the prototype below. The constructor will be called by the framework to initialize your soldiers at the beginning of a battle. The constructor will assign the four parameters to the corresponding instance variables. It must also set the health variable equal to the value INITIAL_HEALTH . (You may have your constructor do additional things as well, if you wish.)
public BasicSoldier(BattleField gridIn, int teamIn, int rowIn, int colIn)
You’ll find that while implementing these methods, the current soldier will need to interact with the battlefield. In particular, the soldier will need to ask the battlefield about his surroundings using the battlefield’s get method. Please see the for more information about using the battlefield. You may add instance methods of your own, if you choose to.
public boolean canMove()
This method returns true if it is possible for this soldier to move, false otherwise. To be able to move, one of the adjacent locations (up/down/left/right) must be empty. There is no diagonal movement. This method does not actually move the soldier, it just returns true or false.
public int numberOfEnemiesRemaining()
This method returns the number of enemies who are on the battlefield. (Enemies are soldiers who are not on this soldier’s team!)
public int getDistance(int destinationRow, int destinationCol)
This method calculates the number of moves it would take this soldier to reach the destination specified by the parameters. Hint: Remember that a soldier does not move diagonally — only up, down, left, and right. So the return value must represent the number of up/down/left/right moves required for the current soldier to reach this location along the shortest possible route (we are ignoring obstacles or other soldiers that might be in the way).
public int getDirection(int destinationRow, int destinationCol)
This method determines which way this soldier would have to go in order to arrive at the destination specified by the parameters. The return value will be either NEUTRAL or one of the symbolic constants representing directions (UP, DOWN , etc.) determined using the following rules:
public int getDirectionOfNearestFriend()
This method will return the direction of the nearest teammate. Distances should be calculated by calling your getDistance method. In cases of a tie (more than one teammate is equally close), you may return the direction of any of the nearest teammates. The direction to be returned should be determined by calling the getDirection method. Note: If there are no friends available then the method must return NEUTRAL.
public int countNearbyFriends(int radius)
This method will count the number of teammates whose distance (measured in “moves”) from the current soldier is less than or equal to the specified radius. Please note that the radius is measuring the number of “moves away” rather than a geometrical distance. For example: If the radius is 6, then the method is looking for the number of friends who could be reached in 6 moves or fewer. Obviously you should not count the current soldier, himself, as a friend.
public int getDirectionOfNearestEnemy(int radius)
This method will return the direction of the nearest enemy whose distance from the current soldier (measured in “moves”) is less than or equal to the given radius. Please note that the radius is measuring the number of “moves away” rather than a geometrical distance. For example: If the radius is 6, then the method is looking for the nearest enemy who could be reached in 6 moves or fewer. In cases of a tie (more than one enemy within the radius is equally close), you may return the direction of any of the nearest enemies who have tied. The direction to be returned should be determined by calling the getDirection method. Note: If there are no enemies within the given radius then the method must return NEUTRAL.
public void performMyTurn()
This method is the heart of your soldier’s “AI” (Artificial Intelligence). It will be called by the framework each time it is the soldier’s turn to perform an action. He has three choices: move, attack, or do nothing. In order to make his decision, the soldier will want to gather information about his surroundings by making calls to the get method of the battlefield. Your soldier can decide on his actions in any way you choose, but he must adhere to the following rules:
Once the soldier’s decision is made (be sure not to violate the rules above), your code must implement his choice as follows:
Running the Game
To simulate a battle, run the main method in the class called Driver (it’s in the package called GUI). By default, this will initiate a battle between two built-in soldier classes, Easy and Medium.
You can modify the game parameters at the top of the GUI and then press “Begin New Game” to start a completely new battle. If you would like to replay the same battle that is currently being fought, just press the “Replay This Battle” button. There is a slider at the bottom which allows you to control the speed of the simulation.
The Red Team and Blue Team boxes can be used to choose different classes for the battle. The built-in classes are Easy, Medium, and Smart. If you’d like to see your own soldiers fighting, then just enter the name of one of your classes (e.g. BasicSoldier) into one or both of these boxes. (You can have both teams use the same class if you want — that works fine).
If you would like to change the default start-up parameters for the game (for example, you would like it to always start off with a 20 by 20 battlefield where the blue team is BasicSoldier and the red team is Smart) you may modify the Driver class in the obvious way to suit your needs.
Additional Fighting Classes
You are only required to implement one class, BasicSoldier. We hope that some of you will enjoy this project and will have fun creating some additional fighting classes in a quest to produce the ultimate soldiers! See the contest rules, below, for more motivation. If you choose to write some additional classes, you may name them anything you wish. Be sure to put your fighting classes in the package called fighters so that the framework can find them. Any additional fighting classes you write must contain the following elements, which were described above for the BasicSoldier:
Random Number Generation
(This section is optional reading, and is only important if you want the “Replay This Battle” button in the GUI to function correctly for battles involving classes you have written.) It is likely that you will want your soldiers to sometimes behave randomly. Rather than using one of the usual random number generators, please use the one we invented. It is called Random131. If you use this generator, the very same “random” numbers will be reproduced after you press “Replay This Battle”, so that the exact same battle can be studied repeatedly.
The Random131 class has a static method called getRandomInteger that you can call whenever you need a random integer in a range that you specify. For example, if you would like to obtain a random number from 0 to 9, then you could use this:
int randomValue = Random131.getRandomInteger(10);
// randomValue will be assigned a random integer from 0 to 9