technologyList) {
/**
* Attack a target city
* Attacking city loses troops equal to min(# of troops attacking, # of troops in the
defending city)
* Defending city loses round(0.8 * # of attacking troops * product of tech attack
bonuses)
*
* This method is overridden in the WarGeneral class
*
* Print the following messages:
* "[attacker city name] loses [number of troops lost by attacker] troops while
attacking"
* "[defender city name] loses [number of troops lost by defender] troops while
defending"21
*
* @param attacker attacking city
* @param defender defending city
* @param attackingTroops number of troops deployed for the attack
* @param technologyList technologies owned by the attacking player
*/
}
public void improveCropYield(Player player, City city) throws
TooPoorException {
/**
* Improve the crop yields in a city
* Improve Crop yields by 50 for 500 golds
* If the player does not have enough gold, throw an exception
* Else decrease 500 golds from the player and improves crops by 50
*
* This method is overridden in the Economist class
*
* @param player
* @param city
* @throws TooPoorException
*/
}
public void recruitTroops(Player player, City city) throws TooPoorException {
/**
* Recruit troops to be stationed in a city
* Recruit 50 troops for 500 golds
* If the player does not have enough gold, throw an exception
*
* Overridden in WarGeneral class
*
* @param player
* @param city
* @throws TooPoorException
*/
}22
public void upgradeTech(Player player, Technology technology) throws
TooPoorException {
/**
* Upgrades tech
* 1. Get the cost of upgrading tech, with applied minister discount
* 2. Check whether player has enough gold, production, and science points
* 3. If not, throw an exception
* 4. Subtract the costs from the player's balance
* 5. Add level of technology by one
*
* HINT:
* - the Cost class has a getDiscounterCost() method
* - the Minister class has a getTechDiscountRate() method
*
* @param player
* @param technology
* @throws TooPoorException
*/
}
public void spyOnNeighbors(City city, GameMap map) {
/**
* This method is called when you want to spy on your neighbors.
*
* Print the information of a City's neighbors
*
* HINT:
* - GameMap class has a getNeighboringCities() method
* - City class overrides the toString() method which returns the
* String representation of a city
*
* @param city
* @param map
*/
}23
The TODOs in the Economist class (Economist.java)
public Economist(int intelligence, int experience, int leadership) {
/**
* Call the superclass' constructor
* @param intelligence
* @param experience
* @param leadership
*/
}
@Override
public double getImprovementDiscountRate() {
/**
* @return improvement discount rate equals to 1 - (intelligence + experience) /
1500
*/
}
@Override
public int collectTax(City city) {
/**
* @param city to collect gold from
* @return 1.5 times the amount collected by other types of minister
*/
}24
@Override
public void improveCropYield(Player player, City city) throws
TooPoorException {
/**
* Economists get a bonus when doing crops improvements
* Crop improvement still costs 500 gold
* Crop is improved by 50 + round((intelligence + experience + leadership) * 0.2)
* If the player does not have enough gold, throw an exception
* Else decrease 500 golds from the player and improves crops by the calculated
amount
*
* @param player
* @param city
* @throws TooPoorException
*/
}
@Override
public String toString() {
/**
* Example string representation:
* "Economist | intelligence: 100 | experience: 100 | leadership: 100 | READY" -
when isReady() == true
* "Economist | intelligence: 100 | experience: 100 | leadership: 100 | DONE" -
when isReady() == false
*
* @return string representation of this object
*/
}25
The TODOs in the Scientist class (Scientist.java)
public Scientist(int intelligence, int experience, int leadership) {
/**
* Calls the superclass' constructor
*
* @param intelligence
* @param experience
* @param leadership
*/
}
@Override
public double getTechDiscountRate() {
/**
* @return tech discount rate equals to 1 - (intelligence + experience) / 1500
*/
}
@Override
public int collectSciencePoints(City city) {
/**
* @param city to collect science points from
* @return 1.5 times the amount collected by other types of minister
*/
}26
@Override
public String toString() {
/**
* Example string representation:
* "Scientist | intelligence: 100 | experience: 100 | leadership: 100 | READY" -
when isReady() == true
* "Scientist | intelligence: 100 | experience: 100 | leadership: 100 | DONE" - when
isReady() == false
*
* @return string representation of this object
*/
}
The TODOs in the WarGeneral class (WarGeneral.java)
public WarGeneral(int intelligence, int experience, int leadership) {
/**
* Calls the superclass' constructor
*
* @param intelligence
* @param experience
* @param leadership
*/
}
@Override
public int collectProductionPoints(City city) {
/**
* @param city to collect production points from
* @return 1.5 times the amount collected by other types of minister
*/
}27
@Override
public void recruitTroops(Player player, City city) throws TooPoorException {
/**
* Recruits more troops than superclass implementation,
* troops added to city = 50 + round(leadership * 0.2).
* Recruitment still costs 500 golds. Throw an exception
* when player does not have enough gold.
*
* @param player
* @param city
* @throws TooPoorException
*/
}
@Override
public void attackCity(City attacker, City defender, int troops, List
technologyList) {
/**
* WarGeneral gets attack bonus when attacking a city.
* bonus_multiplier = 1 + (intelligence + experience + leadership) / 1500
*
* Attacking city loses troops equal to min(# of troops attacking, # of troops in the
defending city)
* Defending city loses round(bonus_multiplier * # of attacking troops * product of
tech attack bonuses)
*
* "[attacker city name] loses [number of troops lost by attacker] troops while
attacking"
* "[defender city name] loses [number of troops lost by defender] troops while
defending"
*
* @param attacker attacking city
* @param defender defending city
* @param troops number of troops deployed for the attack
* @param technologyList
*/
}28
@Override
public String toString() {
/**
* Example string representation:
* "WarGeneral | intelligence: 100 | experience: 100 | leadership: 100 | READY" -
when isReady() == true
* "WarGeneral | intelligence: 100 | experience: 100 | leadership: 100 | DONE" -
when isReady() == false
*
* @return string representation of this object
*/
}
The TODOs in the pa1.technologies package (in the
technologies folder)
The technology package contains classes represent the technologies owned by a player
and they provide bonuses to various aspects of the game. They are structured similarly
to the minister classes with one abstract class and many specific subclasses with different
behaviors. You need to complete the implementation of these subclasses.29
The TODOs in the TradingTech class (TradingTech.java)
@Override
public double getGoldBonus() {
/**
* @return gold bonus equal to 1 + (level * 0.5);
*/
}
@Override
public Cost getUpgradeCost() {
/**
* Upgrade costs:
* gold = production = science = (current level + 1) * 1000;
*
* @return upgrade costs
*/
}
@Override
public String toString() {
/**
* Example string representation:
* "TradingTech | level: 1 | gold bonus: 1.50"
*
* @return String representing this object
*/
}30
The TODOs in the ManufacturingTech class
(ManufacturingTech.java)
@Override
public double getProductionBonus() {
/**
* @return production bonus equal to 1 + current level * 0.5
*/
}
@Override
public Cost getUpgradeCost() {
/**
* Upgrade costs:
* gold = production = (current level + 1) * 1000;
* science = 0
*
* @return upgrade costs
*/
}
@Override
public String toString() {
/**
* Example string representation:
* "ManufacturingTech | level: 1 | production bonus: 1.50"
*
* @return String representing this object
*/
}31
The TODOs in the WarTech class (WarTech.java)
@Override
public double getAttackBonus() {
/**
* @return attack bonus equal to 1 + level * 0.5
*/
}
@Override
public Cost getUpgradeCost() {
/**
* Upgrade costs:
* gold = science = (current level + 1) * 1000;
* production = 0
*
* @return upgrade costs
*/
}
@Override
public String toString() {
/**
* Example string representation:
* "WarTech | level: 1 | attack bonus: 1.50"
*
* @return String representing this object
*/
}32
Additional Classes
These additional classes help encapsulate data. The Cell class represent an x, y
location on the game map. The Cost class encapsulates gold, production and science
points costs for performing a task.
The TODOs in the Cell class (Cell.java)
Implement this class from scratch according to the UML diagram33
The TODOs in the Cost class (Cost.java)
public Cost getDiscountedCost(double rate) {
/**
* Get a new Cost object with applied discount rate
*
* @param rate discount rate
* @return Discounted Cost = round(rate * current cost)
*/
}
@Override
public boolean equals(Object obj) {
/**
* Two Cost objects are equal if their
* gold costs AND production costs AND science costs
* are equal
*
* Return false if obj is not an instance of Cost
*
* @param obj
* @return
*/
}34
Exceptions
You also need to implement a custom exception class, TooPoorException. This
exception will be thrown when the player does not have enough resources to complete a
task. You will need to throw this exception in your implementation of the minister classes.
TooPoorException.java
@Override
public String getMessage() {
/**
* Constructs an error message in the form:
* "need (%d golds, %d production points, %d science points), have (%d golds,
%d production points, %d science points)"
*
* @return
*/
}35
Running the executable file
An executable file for the PA could be downloaded from the PA1 link at the course web.
You could use it to verify the correctness of your finished PA. To run the executable file
under Windows (we only have Windows machine to compile it :( ), first you have to make
sure the two .txt files (map.txt and players.txt files) are in the same directory as the
executable file. Then Open a Windows command window, adjust the width of the
command window as indicate below for a better display:
Then issue the command:
ASCII_civilization.exe36
After you are done with the PA
Congratulations! Hope you have enjoyed it! Now you can Zip your complete project
directory to PA1.zip and submit this file to the CASS link shown on page 1. You can
submit for as many times as you wish before the deadline, but we will only mark you latest
submission.
Late Submission Policy
There will be a penalty of -1 point (out of a maximum 100 points) for every minute you
submit the PA late. If you submit your PA1 at 00:30am on 17 April 2019 (Wednesday),
there will be a penalty of -35 points for your assignment. The lowest score you may get
from the assignment is zero. If you submit your PA1 at 2:35am on 17 April 2019 or later,
you will have zero for the PA1. So be sure to submit the finished PA1 as early as possible.