RandomStrategy.java
package soen6441riskgame.models.strategies;
import java.util.ArrayList;
import soen6441riskgame.enums.GamePhase;
import soen6441riskgame.enums.StrategyName;
import soen6441riskgame.models.Country;
import soen6441riskgame.models.Player;
import soen6441riskgame.singleton.GameBoard;
import soen6441riskgame.utils.GameHelper;
/**
* 1. reinforces random a random country
*
* 2. attacks a random number of times a random country
*
* 3. and fortifies a random country
*
* all following the standard rules for each phase.
*/
public class RandomStrategy implements Strategy {
/**
* get strategy name
*
* @return the name of the strategy as enum
*/
@Override
public StrategyName getName() {
return StrategyName.RANDOM;
}
/**
* get country to reinforce
*
* @param player current player
* @return the country
*/
private Country getCountryToReinforce(Player player) {
ArrayList<Country> conquered = player.getConqueredCountries();
int randIndex = GameHelper.nextRandomIntInRange(0, (conquered.size() - 1));
return conquered.get(randIndex);
}
/**
* reinforce
*
* @param player current player
* @param countryToReinforce country to reinforce
*/
@Override
public void reinforce(Player player, Country countryToReinforce) {
if (player.getUnplacedArmies() > 0) {
int randArmy = GameHelper.nextRandomIntInRange(1, player.getUnplacedArmies());
reinforce(countryToReinforce, randArmy);
}
}
/**
* attacks a random number of times a random country
*
* @param player current player
* @param attackingCountry attack from
* @return list of attacked countries
*/
@Override
public ArrayList<Country> attack(Player player, Country attackingCountry) {
ArrayList<Country> neighbours = attackingCountry.getNeighbors();
Country defendingCountry = null;
ArrayList<Country> defendableCountries = new ArrayList<>();
ArrayList<Country> attackedCountries = new ArrayList<>();
for (Country country : neighbours) {
if (country.getConquerer() != player) {
defendableCountries.add(country);
}
}
if (defendableCountries.size() > 0) {
defendingCountry = defendableCountries.get(GameHelper.nextRandomIntInRange(0,
defendableCountries.size() - 1));
}
if (defendingCountry != null) {
attack(attackingCountry, defendingCountry, 0);
// after attack with allout
if (defendingCountry.getConquerer() == player) {
// player conquered the defending country
int armyToMove = GameBoard.getInstance().getGameBoardPlaying().getAttackerNumDice();
attackMove(armyToMove);
attackedCountries.add(defendingCountry);
}
}
return attackedCountries;
}
/**
* fortify
*
* @param fromCountry from country
* @param toCountry to country
*/
@Override
public void fortify(Country fromCountry, Country toCountry) {
// Fortify Phase
// Command: fortify fromcountry tocountry num
/*
* 1. get list of conquered countries 2. get filtered list of conquered countries to move army from
* 3. generate index of country from filtered list of conquered countries 4. generate randArmyMove
* int (min 1, max = number of army moving from country filtered)
*/
if(fromCountry.getArmyAmount()-1 > 0) {
int randArmyAmountToMove = GameHelper.nextRandomIntInRange(1, fromCountry.getArmyAmount()-1);
fortify(fromCountry, toCountry, randArmyAmountToMove);
}
}
/**
* 1. reinforces random a random country
*
* 2. attacks a random number of times a random country
*
* 3. and fortifies a random country
*
* @param player current player
*/
@Override
public void playTurn(Player player) {
exchangeCards(player);
Country randomCountry = getCountryToReinforce(player);
// run reinforce once to generate unplaced armies
reinforce(randomCountry, 0);
while (player.getUnplacedArmies() > 0) {
randomCountry = getCountryToReinforce(player);
reinforce(player, randomCountry);
}
if (player.getUnplacedArmies() == 0
&& (player.getCurrentPhase() == GamePhase.REINFORCEMENT
|| player.getCurrentPhase() == GamePhase.WAITING_TO_TURN)) {
// call reinforce when unplaced armies = 0 will change phase from REINFORCE to ATTACK
reinforce(randomCountry, 0);
}
ArrayList<Country> attackingCountries = filterAttackableCountries(player.getConqueredCountries());
if (attackingCountries.size() > 0) {
int attackTime = GameHelper.nextRandomInt(attackingCountries.size());
Country attackingCountry = attackingCountries.get(0);
for (int index = 0; index < attackTime && player.getCurrentPhase() == GamePhase.ATTACK; index++) {
attack(player, attackingCountry);
}
}
if (player.getCurrentPhase() == GamePhase.ATTACK) {
attackEnd();
}
if (player.isGameEnded()) {
player.setEndOfGamePhase();
} else {
ArrayList<Country> conquered = player.getConqueredCountries();
ArrayList<Country> moveArmyFrom = filterAttackableCountries(conquered);
ArrayList<Country> fortifiableCountries = new ArrayList<>();
if (moveArmyFrom.size() > 1 && conquered.size() > 1) {
int randIndexCountryFrom = GameHelper.nextRandomIntInRange(0, (moveArmyFrom.size() - 1));
Country countryFrom = moveArmyFrom.get(randIndexCountryFrom);
for (Country country : countryFrom.getNeighbors()) {
if (country.getConquerer() == player) {
fortifiableCountries.add(country);
}
}
if (fortifiableCountries.size() > 0) {
int randIndexCountryTo = GameHelper.nextRandomIntInRange(0, (fortifiableCountries.size() - 1));
Country countryTo = fortifiableCountries.get(randIndexCountryTo);
fortify(countryFrom, countryTo);
}
}
fortifyNone();
}
}
/**
* A function to filter ArrayList of Countries which has army less than two
*
* @param countries all country list of a player
*
* @return return ArrayList of countries with army count more than one.
*
*/
private ArrayList<Country> filterAttackableCountries(ArrayList<Country> countries) {
ArrayList<Country> filteredList = new ArrayList<>();
for (Country country : countries) {
if (country.getArmyAmount() > 1) {
filteredList.add(country);
}
}
return filteredList;
}
}