Country.java
package soen6441riskgame.models;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Observable;
import com.google.gson.annotations.Expose;
import soen6441riskgame.singleton.GameBoard;
import soen6441riskgame.utils.ConsolePrinter;
/**
* Hold country data
*/
public class Country extends Observable implements Viewable {
@Expose
private Coordinate coordinate;
@Expose
private int armyAmount;
@Expose
private String name;
private Continent continent;
private Player conquerer;
@Expose
private int serializedOrder;
/**
* this property is for saving data only
*/
@Expose
private String continentName;
/**
* this property is for saving data only
*/
@Expose
private String conquererName;
/**
* constructor
*
* @param order country order in connected graph
* @param name country name
* @param coordinate country coordinate on bitmap file of the map
* @param continent the continent this country belong to
*/
public Country(int order, String name, Coordinate coordinate, Continent continent) {
this.serializedOrder = order;
this.name = name;
this.coordinate = coordinate;
this.continent = continent;
this.continentName = continent.getName();
}
/**
* construct country object from json serialized country
*
* @param serializedCountry the serialized country object
* @param continents list of continents in game
* @param players list of players in game
*/
public Country(Country serializedCountry, List<Continent> continents, List<Player> players) {
for (Continent continent : continents) {
if (serializedCountry.continentName.equals(continent.getName())) {
this.continent = continent;
break;
}
}
for (Player player : players) {
if (serializedCountry.conquererName != null
&& serializedCountry.conquererName.equals(player.getName())) {
this.conquerer = player;
break;
}
}
this.name = serializedCountry.name;
this.coordinate = serializedCountry.coordinate;
this.armyAmount = serializedCountry.armyAmount;
}
/**
* get serialized order of country. This method is only used for save and load game data
*
* @return serialized order
*/
public int getSerializedOrder() {
return this.serializedOrder;
}
/**
* get this country conquerer
*
* @return conquerer
*/
public Player getConquerer() {
return conquerer;
}
/**
* set conquerer of this country.
*
* if set to null, this country have no conquerer
*
* @param conquerer player object to set
*/
public void setConquerer(Player conquerer) {
if (conquerer != null) {
ConsolePrinter.printFormat("Player %s conquered %s", conquerer.getName(), this.getName());
} else {
ConsolePrinter.printFormat("Country %s has no conquerer", this.getName());
}
if (conquerer != this.conquerer) {
this.conquerer = conquerer;
if (conquerer != null) {
this.conquererName = conquerer.getName();
}
setChanged();
notifyObservers();
}
}
/**
* get the continent this country belong to
*
* @return continent object
*/
public Continent getContinent() {
return continent;
}
/**
* get country name
*
* @return name
*/
public String getName() {
return name;
}
/**
* get army amount this country have
*
* @return army amount
*/
public int getArmyAmount() {
return armyAmount;
}
/**
* set army amount this country have
*
* @param armyAmount army amount
*/
public void setArmyAmount(int armyAmount) {
this.armyAmount = armyAmount;
ConsolePrinter.printFormat("Country %s now have %d armies, belong to %s",
getName(),
getArmyAmount(),
getConquerer().getName());
}
/**
* return the order of the country in the country list, starting with 1
*
* @return the order of the country
*/
public int getOrder() {
serializedOrder = GameBoard.getInstance().getGameBoardMap().getCountries().indexOf(this) + 1;
return serializedOrder;
}
/**
* get the coordinate of this country on the map
*
* @return coordinate
*/
public Coordinate getCoordinate() {
return coordinate;
}
/**
* get the neighbors of this country
*
* @return if no neighbors, return an empty list
*/
public ArrayList<Country> getNeighbors() {
ArrayList<Country> neighbors = new ArrayList<Country>();
int[][] borders = GameBoard.getInstance().getGameBoardMap().getBorders();
int countryOrder = this.getOrder();
for (int index = 0; index < borders[countryOrder - 1].length; index++) {
if (borders[countryOrder - 1][index] == 1) {
neighbors.add(GameBoard.getInstance().getGameBoardMap().getCountries().get(index));
}
}
return neighbors;
}
/**
* is this country conquered by any player?
*
* @return conquered or not
*/
public boolean isConquered() {
return this.getConquerer() != null;
}
/**
* Increase armies inside this country from unplaced armies
*
* @param amount of armies from unplaced armies of the conquerer
*/
public void receiveArmiesFromUnPlacedArmies(int amount) {
Player conquerer = this.getConquerer();
if (amount > conquerer.getUnplacedArmies()) {
ConsolePrinter.printFormat("The amount of armies you want to place in this country is bigger than the amount of armies you have");
return;
}
this.increaseArmies(amount);
int newUnplacedArmiesOfConquerer = conquerer.getUnplacedArmies() - amount;
conquerer.setUnplacedArmies(newUnplacedArmiesOfConquerer);
}
/**
* Increase armies inside this country from unplaced armies
*
* @param amount of armies from unplaced armies of the conquerer
*/
public void increaseArmies(int amount) {
int newArmiesAmount = this.getArmyAmount() + amount;
this.setArmyAmount(newArmiesAmount);
}
/**
* decrease armies inside this country from unplaced armies
*
* @param amount of armies from unplaced armies of the conquerer
*/
public void decreaseArmies(int amount) {
int newArmiesAmount = this.getArmyAmount() - amount;
this.setArmyAmount(newArmiesAmount);
}
/**
* move armies from this country to another neighbor country (have the same conquerer)
*
* @param toCountry the destination country
* @param armiesToMove number of armies to move
*/
public void moveArmies(Country toCountry, int armiesToMove) {
if (!this.isNeighboringCountries(toCountry)) {
ConsolePrinter.printFormat("Country %s and %s is not neighbor", this.getName(), toCountry.getName());
return;
}
if (armiesToMove > this.getArmyAmount() - 1) {
ConsolePrinter.printFormat("The 'fromcountry' must have at least 1 army after fortification");
ConsolePrinter.printFormat("You are moving %1$d army from %2$s to %3$s, but %2$s only have %4$d armies left",
armiesToMove,
this.getName(),
toCountry.getName(),
this.getArmyAmount());
return;
}
this.decreaseArmies(armiesToMove);
toCountry.increaseArmies(armiesToMove);
}
/**
* Place army for player
*
* @param player the player to place army
*/
public void placeArmy(Player player) {
int originalArmy = getArmyAmount();
setArmyAmount(originalArmy + 1);
int newUnplacedArmies = player.getUnplacedArmies() - 1;
player.setUnplacedArmies(newUnplacedArmies);
}
/**
* check if 2 country is neighbor in map
*
* @param neighborCountry neighbor country object
* @return false if any of two countries is not existed
*/
public boolean isNeighboringCountries(Country neighborCountry) {
int countryOrder = getOrder();
int neighbouringCountryOrder = neighborCountry.getOrder();
int relationshipWithNeighbor = GameBoard.getInstance()
.getGameBoardMap()
.getBorders()[countryOrder - 1][neighbouringCountryOrder - 1];
return relationshipWithNeighbor == 1;
}
/**
* check if this country belong to a specific player
*
* @param player player to check
* @return true if the country belong to that player
*/
public boolean isCountryBelongToPlayer(Player player) {
if (!getConquerer().equals(player)) {
ConsolePrinter.printFormat("The country %s is not belong to %s",
getName(),
player.getName());
return false;
}
return true;
}
/**
* print this country content without printing it's neighbors
*
* @param indent number of indentation before print
*/
public void viewWithoutNeighbors(int indent) {
viewWithoutNeighbors(GameBoard.getInstance().standardPrintStream, indent);
}
/**
* print this country content without printing it's neighbors
*
* @param printStream the stream to print
* @param indent number of indentation before print
*/
public void viewWithoutNeighbors(PrintStream printStream, int indent) {
this.printIndent(printStream, indent);
String printString = "Country: %s\t| No.: %s\t| Army: %s ";
String conquererName = "";
if (this.getConquerer() != null) {
printString += "\t| Conquerer: %s";
conquererName = this.getConquerer().getName();
}
ConsolePrinter.printFormat(printStream,
printString,
this.getName(),
this.getOrder(),
this.getArmyAmount(),
conquererName);
}
/**
* print the country info to output
*
* @param printStream the print stream to print
* @param indent number of indent to print
*/
public void view(PrintStream printStream, int indent) {
this.viewWithoutNeighbors(indent);
this.printIndent(printStream, indent + 1);
ConsolePrinter.printFormat("Neighbors:");
for (Country country : this.getNeighbors()) {
country.viewWithoutNeighbors(indent + 2);
}
}
}