diff --git a/src/main/java/edu/ntnu/idatt2001/runarin/wargames/backend/armies/Army.java b/src/main/java/edu/ntnu/idatt2001/runarin/wargames/backend/armies/Army.java index d715c337d9a64761b0d128b0a8a8c40ed92e5f35..988fcafc38e8185a5aefd40394d9e3c25b4f16b7 100644 --- a/src/main/java/edu/ntnu/idatt2001/runarin/wargames/backend/armies/Army.java +++ b/src/main/java/edu/ntnu/idatt2001/runarin/wargames/backend/armies/Army.java @@ -187,7 +187,7 @@ public class Army { * @throws IOException thrown if the file refers to the wrong army. */ public void addUnitsFromFile(String file) throws IOException { - ArrayList<Unit> importUnitsList = FileHandler.readArmyFromFile(this, file); + ArrayList<Unit> importUnitsList = FileHandler.readUnitsFromFile(this, file); units.addAll(importUnitsList); } diff --git a/src/main/java/edu/ntnu/idatt2001/runarin/wargames/backend/armies/Battle.java b/src/main/java/edu/ntnu/idatt2001/runarin/wargames/backend/armies/Battle.java index ee8366967f49191200fc252a33da3df3f963a973..6c1ed36cd576ee7d062cd319ef4c579300ff774c 100644 --- a/src/main/java/edu/ntnu/idatt2001/runarin/wargames/backend/armies/Battle.java +++ b/src/main/java/edu/ntnu/idatt2001/runarin/wargames/backend/armies/Battle.java @@ -1,12 +1,12 @@ package edu.ntnu.idatt2001.runarin.wargames.backend.armies; +import edu.ntnu.idatt2001.runarin.wargames.backend.exceptions.ArmyEmptyOfUnitsException; +import edu.ntnu.idatt2001.runarin.wargames.backend.filehandling.FileHandler; import edu.ntnu.idatt2001.runarin.wargames.backend.units.TerrainType; import edu.ntnu.idatt2001.runarin.wargames.backend.units.specialised.CavalryUnit; import edu.ntnu.idatt2001.runarin.wargames.backend.units.specialised.RangedUnit; import edu.ntnu.idatt2001.runarin.wargames.backend.units.Unit; - -import java.io.FileNotFoundException; -import java.io.PrintStream; +import java.io.IOException; import java.util.Random; /** @@ -14,8 +14,8 @@ import java.util.Random; * This class represents a battle between two armies. * * @author Runar Indahl - * @version 1.0 - * @since 2022-04-03 + * @version 3.0 + * @since 2022-04-19 */ public class Battle { @@ -28,9 +28,11 @@ public class Battle { * @param armyOne one out of two armies battling for survival. * @param armyTwo second out of two armies battling for survival. */ - public Battle(Army armyOne, Army armyTwo) { - if (armyOne == null || armyTwo == null) throw new IllegalArgumentException("There must be two armies as input."); - if (armyOne.equals(armyTwo)) throw new IllegalArgumentException("An army cannot battle itself."); + public Battle(Army armyOne, Army armyTwo) throws IOException { + if (armyOne == null || armyTwo == null) + throw new IOException("Two armies must be initialised to run simulation."); + if (armyOne.equals(armyTwo)) + throw new IllegalArgumentException("An army cannot battle itself."); this.armyOne = armyOne; this.armyTwo = armyTwo; } @@ -45,85 +47,58 @@ public class Battle { * * @return the name of the winning army. */ - public Army simulate(TerrainType terrain) { - int roundCount = 0; - int randomiseAttack; - int attackedWarriorOldHealth; - int attackedWarriorNewHealth; - Random rand = new Random(); + public Army simulate(TerrainType terrain) throws ArmyEmptyOfUnitsException { - // Creating a File object the battle log will be applied to. - PrintStream o = null; - try { - o = new PrintStream("src/main/resources/battle-log/BattleLog.txt"); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - // Store current System.out before assigning a new value - PrintStream console = System.out; - // Assign o to output stream. Every print from now until reset will go to a log-file. - System.setOut(o); + if (!armyOne.hasUnits()) throw new ArmyEmptyOfUnitsException(armyOne.getName() + + " has no units left to fight in the simulation. " + + "Press the \"Initialise army from file\"-button to rebuild the army."); + if (!armyTwo.hasUnits()) throw new ArmyEmptyOfUnitsException(armyTwo.getName() + + " has no units left to fight in the simulation. " + + "Press the \"Initialise army from file\"-button to rebuild the army."); + int roundCount = 0; + Random rand = new Random(); Unit warriorArmyOne = armyOne.getRandom(); Unit warriorArmyTwo = armyTwo.getRandom(); + String clashReport; + StringBuilder battleLog = new StringBuilder(); - // Run as long as there is units left in both armies. + // Loop run as long as there is units left in both armies. while (armyOne.hasUnits() & armyTwo.hasUnits()) { roundCount++; - System.out.println("\nRound " + roundCount + ""); - System.out.println(" " + warriorArmyOne.getName() + " [" + warriorArmyOne.getHealth() + " HP]" - + " against "+ warriorArmyTwo.getName() + " [" + warriorArmyTwo.getHealth() + " HP]"); + battleLog.append("\n\nRound ").append(roundCount); + battleLog.append(" ").append(warriorArmyOne.getName()) + .append(" [").append(warriorArmyOne.getHealth()) + .append(" hp]").append(" VS. ").append(warriorArmyTwo.getName()) + .append(" [").append(warriorArmyTwo.getHealth()).append(" hp]"); // Randomises who attacks first. - randomiseAttack = rand.nextInt(0, 2); - if (randomiseAttack == 0) { + if (rand.nextInt(0, 2) == 0) { if (warriorArmyOne.getHealth() > 0) { - attackedWarriorOldHealth = warriorArmyTwo.getHealth(); - warriorArmyOne.attack(warriorArmyTwo, terrain); - attackedWarriorNewHealth = warriorArmyTwo.getHealth(); - System.out.println(" " - + warriorArmyOne.getName() + " [" + warriorArmyOne.getHealth() + " HP]" - + " strikes and deals " + (attackedWarriorOldHealth - attackedWarriorNewHealth) - + " damage to " + warriorArmyTwo.getName() + " [" + attackedWarriorOldHealth - + " HP][-" + (attackedWarriorOldHealth - attackedWarriorNewHealth) + " HP]"); + clashReport = clash(warriorArmyOne, warriorArmyTwo, terrain); + battleLog.append(clashReport); } if (warriorArmyTwo.getHealth() > 0) { - attackedWarriorOldHealth = warriorArmyOne.getHealth(); - warriorArmyTwo.attack(warriorArmyOne, terrain); - attackedWarriorNewHealth = warriorArmyOne.getHealth(); - System.out.println(" " - + warriorArmyTwo.getName() + " [" + warriorArmyTwo.getHealth() + " HP]" - + " then deals " + (attackedWarriorOldHealth - attackedWarriorNewHealth) - + " damage to " + warriorArmyOne.getName() + " [" + attackedWarriorOldHealth - + " HP][-" + (attackedWarriorOldHealth - attackedWarriorNewHealth) + " HP]"); + clashReport = clash(warriorArmyTwo, warriorArmyOne, terrain); + battleLog.append(clashReport); } } else { if (warriorArmyTwo.getHealth() > 0) { - attackedWarriorOldHealth = warriorArmyOne.getHealth(); - warriorArmyTwo.attack(warriorArmyOne, terrain); - attackedWarriorNewHealth = warriorArmyOne.getHealth(); - System.out.println(" " - + warriorArmyTwo.getName() + " [" + warriorArmyTwo.getHealth() + " HP]" - + " strikes and deals " + (attackedWarriorOldHealth - attackedWarriorNewHealth) - + " damage to " + warriorArmyOne.getName() + " [" + attackedWarriorOldHealth - + " HP][-" + (attackedWarriorOldHealth - attackedWarriorNewHealth) + " HP]"); + clashReport = clash(warriorArmyTwo, warriorArmyOne, terrain); + battleLog.append(clashReport); } if (warriorArmyOne.getHealth() > 0) { - attackedWarriorOldHealth = warriorArmyTwo.getHealth(); - warriorArmyOne.attack(warriorArmyTwo, terrain); - attackedWarriorNewHealth = warriorArmyTwo.getHealth(); - System.out.println(" " - + warriorArmyOne.getName() + " [" + warriorArmyOne.getHealth() + " HP]" - + " then deals " + (attackedWarriorOldHealth - attackedWarriorNewHealth) - + " damage to " + warriorArmyTwo.getName() + " [" + attackedWarriorOldHealth - + " HP][-" + (attackedWarriorOldHealth - attackedWarriorNewHealth) + " HP]"); + clashReport = clash(warriorArmyOne, warriorArmyTwo, terrain); + battleLog.append(clashReport); } } // After an attack, see if a warrior died or not. If a warrior died, it is replaced. if (warriorArmyTwo.getHealth() <= 0) { - System.out.println("\n " + warriorArmyTwo.getName() - + " died of fatal blow from " + warriorArmyOne.getName() + "!"); + battleLog.append("\n ").append(warriorArmyTwo.getName()) + .append(" died of fatal blow from ") + .append(warriorArmyOne.getName()).append("!"); + armyTwo.remove(warriorArmyTwo); if (armyTwo.hasUnits()) { warriorArmyTwo = armyTwo.getRandom(); @@ -136,8 +111,10 @@ public class Battle { } } if (warriorArmyOne.getHealth() <= 0) { - System.out.println("\n " + warriorArmyOne.getName() - + " died of fatal blow from " + warriorArmyTwo.getName() + "!"); + battleLog.append("\n ").append(warriorArmyOne.getName()) + .append(" died of fatal blow from ") + .append(warriorArmyTwo.getName()).append("!"); + armyOne.remove(warriorArmyOne); if (armyOne.hasUnits()) { warriorArmyOne = armyOne.getRandom(); @@ -152,16 +129,42 @@ public class Battle { } if (!armyOne.hasUnits()) { - System.out.println("\n " + armyTwo.getName() + " wins the battle!"); // Add to log who the winner is. - System.setOut(console); // Restores output to console. + battleLog.append("\n\n ").append(armyTwo.getName()) + .append(" wins the battle!"); // Add to log who the winner is. + try { + FileHandler.writeBattleLogToFile(battleLog,"/BattleLog.txt"); + } catch (IOException e) { + e.printStackTrace(); + } return armyTwo; } else { - System.out.println("\n " + armyOne.getName() + " wins the battle!"); // Add to log who the winner is. - System.setOut(console); // Restores output to console. + battleLog.append("\n\n ").append(armyOne.getName()) + .append(" wins the battle!"); // Add to log who the winner is. + try { + FileHandler.writeBattleLogToFile(battleLog, "/BattleLog.txt"); + } catch (IOException e) { + e.printStackTrace(); + } return armyOne; } } + /** + * Helper method to make the simulate()-method easier to read when randomizing attacks. + * + * @param attacker attacking unit. + * @param defender defending unit. + * @return string of text to be viewed either in terminal, battle log or GUI output window. + */ + private String clash(Unit attacker, Unit defender, TerrainType terrain) { + int defenderOldHealth = defender.getHealth(); + attacker.attack(defender, terrain); + int defenderNewHealth = defender.getHealth(); + return "\n" + " " + + attacker.getName() + " strikes and deals " + (defenderOldHealth - defenderNewHealth) + + " damage to " + defender.getName() + " [" + defenderNewHealth + " hp]"; + } + /** * toString-method which return the names of the two clashing armies. * diff --git a/src/main/java/edu/ntnu/idatt2001/runarin/wargames/backend/exceptions/ArmyEmptyOfUnitsException.java b/src/main/java/edu/ntnu/idatt2001/runarin/wargames/backend/exceptions/ArmyEmptyOfUnitsException.java new file mode 100644 index 0000000000000000000000000000000000000000..a613727b34c101e15e9780897bc0a2a22d16182b --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2001/runarin/wargames/backend/exceptions/ArmyEmptyOfUnitsException.java @@ -0,0 +1,24 @@ +package edu.ntnu.idatt2001.runarin.wargames.backend.exceptions; + +import java.io.IOException; + +/** + * Exception handling for showing dialog window in the War Games GUI. + * This exception is thrown when the system tries to initialise a simulation + * while an army has no units. + * + * @author Runar Indahl + * @version 3.0 + * @since 2022-04-21 + */ +public class ArmyEmptyOfUnitsException extends IOException { + /** + * Instantiates a new ArmyEmptyOfUnitsException-object inherited by IOException super class. + * Specifies the Exception message. + * + * @param message message from the super class, IOException. + */ + public ArmyEmptyOfUnitsException(String message) { + super(message); + } +} diff --git a/src/main/java/edu/ntnu/idatt2001/runarin/wargames/backend/exceptions/CorruptedFileException.java b/src/main/java/edu/ntnu/idatt2001/runarin/wargames/backend/exceptions/CorruptedFileException.java index b79234adf8c8bd4599228122dd21c48e0520df13..0279bba420a5ff21ad7f72f653900a74cd88eddf 100644 --- a/src/main/java/edu/ntnu/idatt2001/runarin/wargames/backend/exceptions/CorruptedFileException.java +++ b/src/main/java/edu/ntnu/idatt2001/runarin/wargames/backend/exceptions/CorruptedFileException.java @@ -8,14 +8,14 @@ import java.io.IOException; * file which is not in the correct format. * * @author Runar Indahl - * @version 1.0 + * @version 2.0 * @since 2022-04-03 */ public class CorruptedFileException extends IOException { /** * Instantiates a new CorruptFileException-object inherited by IOException super class. - * Specialises the Exception message. + * Specifies the Exception message. * * @param message message from the super class, IOException. */ diff --git a/src/main/java/edu/ntnu/idatt2001/runarin/wargames/backend/filehandling/FileHandler.java b/src/main/java/edu/ntnu/idatt2001/runarin/wargames/backend/filehandling/FileHandler.java index ad045c51f5d65ad7c3e75410711be85a97a95673..62765345dbff3c66c29d14386068e5cd07b4ffc7 100644 --- a/src/main/java/edu/ntnu/idatt2001/runarin/wargames/backend/filehandling/FileHandler.java +++ b/src/main/java/edu/ntnu/idatt2001/runarin/wargames/backend/filehandling/FileHandler.java @@ -1,6 +1,7 @@ package edu.ntnu.idatt2001.runarin.wargames.backend.filehandling; import edu.ntnu.idatt2001.runarin.wargames.backend.armies.Army; +import edu.ntnu.idatt2001.runarin.wargames.backend.armies.Battle; import edu.ntnu.idatt2001.runarin.wargames.backend.exceptions.CorruptedFileException; import edu.ntnu.idatt2001.runarin.wargames.backend.units.Unit; import edu.ntnu.idatt2001.runarin.wargames.backend.units.specialised.CavalryUnit; @@ -25,10 +26,10 @@ public class FileHandler { * about the army and its units to a wanted location. * The file name is the same as the army's name. * - * @param filePath Path to where the generated file is to be stored. The file-name + * @param filePath path to where the generated file is to be stored. The file-name * itself is generated based on the army name. * @throws IOException thrown from FileWriter-object. - * @see Army + * @see Army class. */ public static void writeArmyToFile(Army army, String filePath) throws IOException { if (army == null) throw new IllegalArgumentException("Parameter for Army class is missing."); @@ -67,15 +68,34 @@ public class FileHandler { fw.close(); } + /** + * Returns only the army name from a file. + * + * @param file path and file name of the file to be read. + * @return army name. + * @throws IOException if army name s blank. + */ + public static String readArmyNameFromFile(String file) throws IOException { + if (file.isBlank()) throw new IllegalArgumentException("Parameter 'file' cannot be blank."); + + String armyName; + try (BufferedReader br = new BufferedReader((new FileReader(file)))) { + // Reads the first line in the file which contains the army name. + armyName = br.readLine(); + if (armyName.isBlank()) throw new IOException("Army name is blank in the given file."); + } + return armyName; + } + /** * Reads a file containing units and returns an ArrayList with these units. * Throws CorruptedArmyFileException if the file is corrupt. * Only returns units to the list if there are no corruptions in the file. * - * @param file Path and name to the file to be read. - * @throws CorruptedFileException Throws exception if the file data is corrupted. + * @param file path and file name of the file to be read. + * @throws CorruptedFileException throws exception if the file data is corrupted. */ - public static ArrayList<Unit> readArmyFromFile(Army army, String file) throws IOException { + public static ArrayList<Unit> readUnitsFromFile(Army army, String file) throws IOException { if (army == null) throw new IllegalArgumentException("Parameter for Army class is missing."); if (file.isBlank()) throw new IllegalArgumentException("Parameter 'file' cannot be blank."); if (!file.contains(".csv")) throw new IllegalArgumentException("Parameter 'file' must be of a .csv-format"); @@ -123,4 +143,46 @@ public class FileHandler { } return importUnitsList; } + + /** + * Writes string from StringBuilder to a .txt-file named BattleLog.txt. + * + * @param battleLog the battle log in StringBuilder format to be written to a .txt-file. + * @throws IOException thrown from FileWriter-object. + * @see Battle class. + */ + public static void writeBattleLogToFile(StringBuilder battleLog, String fileName) throws IOException { + if (battleLog.isEmpty()) throw new IOException("Battle log is empty."); + + String filePath = "src/main/resources/battle-files" + fileName; + File file = new File(filePath); + FileWriter fw = new FileWriter(file); + BufferedWriter bw = new BufferedWriter(fw); + + // Writes the battle log to file. + bw.write(battleLog.toString()); + + bw.close(); + fw.close(); + } + + /** + * Returns a StringBuilder containing text information from a file. + * + * @return StringBuilder containing text information from a file. + * @throws IOException thrown by BufferedReader. + */ + public static StringBuilder readBattleLogFromFile() throws IOException { + StringBuilder stringBuilder = new StringBuilder(); + + String file = "src/main/resources/battle-files/BattleLog.txt"; + try (BufferedReader br = new BufferedReader((new FileReader(file)))) { + + String line; + while ((line = br.readLine()) != null) { + stringBuilder.append(line).append(System.lineSeparator()); + } + } + return stringBuilder; + } } diff --git a/src/main/java/edu/ntnu/idatt2001/runarin/wargames/backend/units/Unit.java b/src/main/java/edu/ntnu/idatt2001/runarin/wargames/backend/units/Unit.java index d6f9e0e9f8a658c010571194f8c1dbbe0570feb1..2b945a7a9e2958c06c785c6f12f6a4cacb3b9bcd 100644 --- a/src/main/java/edu/ntnu/idatt2001/runarin/wargames/backend/units/Unit.java +++ b/src/main/java/edu/ntnu/idatt2001/runarin/wargames/backend/units/Unit.java @@ -6,7 +6,7 @@ package edu.ntnu.idatt2001.runarin.wargames.backend.units; * * @author Runar Indahl * @version 3.0 - * @since 2022-04-17 + * @since 2022-04-19 */ public abstract class Unit { @@ -122,14 +122,14 @@ public abstract class Unit { } /** - * Returns the status of a warrior in toString-format. + * Returns the unit type, name and health status of a warrior in toString-format. * * @return status of a warrior. */ @Override public String toString() { return ( - "\n| " + name + " | HP = " + health + " | Attack power = " + attack + " | Armor points = " + armor + " |" + "\n" + name + " [" + health + " hp] " + getClass().getSimpleName() ); } diff --git a/src/main/java/edu/ntnu/idatt2001/runarin/wargames/frontend/WarGamesSimpleClient.java b/src/main/java/edu/ntnu/idatt2001/runarin/wargames/frontend/WarGamesSimpleClient.java index fd5f8322cbd823a62717c30fa94952079cf5709c..1685b0ab400dbe70ead097358fc12f41bd0b62a2 100644 --- a/src/main/java/edu/ntnu/idatt2001/runarin/wargames/frontend/WarGamesSimpleClient.java +++ b/src/main/java/edu/ntnu/idatt2001/runarin/wargames/frontend/WarGamesSimpleClient.java @@ -2,11 +2,13 @@ package edu.ntnu.idatt2001.runarin.wargames.frontend; import edu.ntnu.idatt2001.runarin.wargames.backend.armies.Army; import edu.ntnu.idatt2001.runarin.wargames.backend.armies.Battle; +import edu.ntnu.idatt2001.runarin.wargames.backend.exceptions.ArmyEmptyOfUnitsException; import edu.ntnu.idatt2001.runarin.wargames.backend.units.specialised.CavalryUnit; import edu.ntnu.idatt2001.runarin.wargames.backend.units.specialised.CommanderUnit; import edu.ntnu.idatt2001.runarin.wargames.backend.units.specialised.InfantryUnit; import edu.ntnu.idatt2001.runarin.wargames.backend.units.specialised.RangedUnit; +import java.io.IOException; import java.util.HashMap; import java.util.Scanner; @@ -344,8 +346,13 @@ public class WarGamesSimpleClient { } } - public Army startABattleBetweenTwoArmies(Army armyOne, Army armyTwo) { - Battle battle = new Battle(armyOne,armyTwo); + public Army startABattleBetweenTwoArmies(Army armyOne, Army armyTwo) throws ArmyEmptyOfUnitsException { + Battle battle = null; + try { + battle = new Battle(armyOne,armyTwo); + } catch (IOException e) { + e.printStackTrace(); + } return battle.simulate(null); } diff --git a/src/main/java/edu/ntnu/idatt2001/runarin/wargames/frontend/controllers/WarGamesController.java b/src/main/java/edu/ntnu/idatt2001/runarin/wargames/frontend/controllers/WarGamesController.java new file mode 100644 index 0000000000000000000000000000000000000000..78b047dbaa693755198b1d3daad10822c0a6c365 --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2001/runarin/wargames/frontend/controllers/WarGamesController.java @@ -0,0 +1,209 @@ +package edu.ntnu.idatt2001.runarin.wargames.frontend.controllers; +import static edu.ntnu.idatt2001.runarin.wargames.frontend.model.WarGamesModel.*; + +import edu.ntnu.idatt2001.runarin.wargames.backend.armies.Army; +import edu.ntnu.idatt2001.runarin.wargames.backend.armies.Battle; +import edu.ntnu.idatt2001.runarin.wargames.backend.exceptions.ArmyEmptyOfUnitsException; +import edu.ntnu.idatt2001.runarin.wargames.backend.filehandling.FileHandler; +import edu.ntnu.idatt2001.runarin.wargames.backend.units.TerrainType; +import edu.ntnu.idatt2001.runarin.wargames.backend.units.Unit; +import edu.ntnu.idatt2001.runarin.wargames.frontend.views.WarGamesApp; +import javafx.collections.FXCollections; +import javafx.collections.ListChangeListener; +import javafx.collections.ObservableList; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; +import javafx.fxml.Initializable; +import javafx.scene.control.*; + +import java.io.File; +import java.io.IOException; +import java.net.URL; +import java.util.ResourceBundle; + +/** + * + * + * @author Runar Indahl + * @version 3.0 + * @since 2022-04-19 + */ +public class WarGamesController implements Initializable { + + @FXML private Label nameArmyOne; + @FXML private Label armyOneNumberOfUnits; + @FXML private Label armyOneNumberOfCommanders; + @FXML private Label armyOneNumberOfCavalry; + @FXML private Label armyOneNumberOfInfantry; + @FXML private Label armyOneNumberOfRanged; + @FXML private ListView<Unit> listViewArmyOneUnits; + @FXML private TextField filePathArmyOne; + + @FXML private Label nameArmyTwo; + @FXML private Label armyTwoNumberOfUnits; + @FXML private Label armyTwoNumberOfCommanders; + @FXML private Label armyTwoNumberOfCavalry; + @FXML private Label armyTwoNumberOfInfantry; + @FXML private Label armyTwoNumberOfRanged; + @FXML private ListView<Unit> listViewArmyTwoUnits; + @FXML private TextField filePathArmyTwo; + + @FXML private Button idBtnStartBattle; + @FXML private Button idBtnForest; + @FXML private Button idBtnHill; + @FXML private Button idBtnPlains; + + @FXML private TextArea textFieldBattleLog; + + TerrainType terrain; + + /* + private ObservableList<Unit> obsListArmyOne; + private void initArmyOneUnitsListView() { + obsListArmyOne = FXCollections.observableList(getArmyOne().getAllUnits()); + obsListArmyOne.addListener(new ListChangeListener<Unit>() { + @Override + public void onChanged(Change<? extends Unit> change) { + System.out.println("Army One: List change detected."); + obsListArmyOne.setAll(getArmyOne().getAllUnits()); + listViewArmyOneUnits.setItems(null); + listViewArmyOneUnits.setItems(obsListArmyOne); + } + }); + listViewArmyOneUnits.setItems(obsListArmyOne); + }*/ + + private ObservableList<Unit> updateUnitsListView(Army army) { + + ObservableList<Unit> obsArmyList = FXCollections.observableList(army.getAllUnits()); + obsArmyList.addListener(new ListChangeListener<>() { + @Override + public void onChanged(Change<? extends Unit> change) { + System.out.println("Army One: List change detected."); + obsArmyList.setAll(army.getAllUnits()); + } + }); + return obsArmyList; + } + + + public void btnStartBattle(ActionEvent actionEvent) { + + StringBuilder battleLog = null; + try { + Battle battle = new Battle(getArmyOne(), getArmyTwo()); + battle.simulate(terrain); + battleLog = FileHandler.readBattleLogFromFile(); + } + catch (IOException e) { + WarGamesApp.giveInformation(e.getMessage()); + } + + armyOneNumberOfUnits.setText(String.valueOf(getArmyOne().getAllUnits().size())); + armyOneNumberOfCommanders.setText(String.valueOf(getArmyOne().getCommanderUnits().size())); + armyOneNumberOfCavalry.setText(String.valueOf(getArmyOne().getCavalryUnits().size())); + armyOneNumberOfRanged.setText(String.valueOf(getArmyOne().getRangedUnits().size())); + armyOneNumberOfInfantry.setText(String.valueOf(getArmyOne().getInfantryUnits().size())); + + armyTwoNumberOfUnits.setText(String.valueOf(getArmyTwo().getAllUnits().size())); + armyTwoNumberOfCommanders.setText(String.valueOf(getArmyTwo().getCommanderUnits().size())); + armyTwoNumberOfCavalry.setText(String.valueOf(getArmyTwo().getCavalryUnits().size())); + armyTwoNumberOfRanged.setText(String.valueOf(getArmyTwo().getRangedUnits().size())); + armyTwoNumberOfInfantry.setText(String.valueOf(getArmyTwo().getInfantryUnits().size())); + + ObservableList<Unit> obsListArmyOne = updateUnitsListView(getArmyOne()); + listViewArmyOneUnits.setItems(obsListArmyOne); + + ObservableList<Unit> obsListArmyTwo = updateUnitsListView(getArmyTwo()); + listViewArmyTwoUnits.setItems(obsListArmyTwo); + + //if (!getArmyOne().hasUnits() || !getArmyTwo().hasUnits()) idBtnStartBattle.setDisable(true); + + if (battleLog != null) { + textFieldBattleLog.setText(battleLog.toString());textFieldBattleLog.setText(battleLog.toString()); + } + else { + textFieldBattleLog.setText("Battle log not available."); + } + } + + public void btnForest(ActionEvent actionEvent) { + idBtnStartBattle.setDisable(false); + idBtnForest.setDisable(true); + idBtnHill.setDisable(false); + idBtnPlains.setDisable(false); + + terrain = TerrainType.FOREST; + } + + public void btnHill(ActionEvent actionEvent) { + idBtnStartBattle.setDisable(false); + idBtnForest.setDisable(false); + idBtnHill.setDisable(true); + idBtnPlains.setDisable(false); + + terrain = TerrainType.HILL; + } + + public void btnPlains(ActionEvent actionEvent) { + idBtnStartBattle.setDisable(false); + idBtnForest.setDisable(false); + idBtnHill.setDisable(false); + idBtnPlains.setDisable(true); + + terrain = TerrainType.PLAINS; + } + + + public void btnArmyOneSelectFile(ActionEvent actionEvent) { + } + + public void btnArmyTwoSelectFile(ActionEvent actionEvent) { + } + + public void btnInitialiseArmyOne(ActionEvent actionEvent) throws IOException { + String newArmyName = FileHandler.readArmyNameFromFile(getFilePathArmyOne()); + nameArmyOne.setText(newArmyName); + + Army newArmy = new Army(newArmyName); + newArmy.addUnitsFromFile(getFilePathArmyOne()); + setArmyOne(newArmy); + + armyOneNumberOfUnits.setText(String.valueOf(getArmyOne().getAllUnits().size())); + armyOneNumberOfCommanders.setText(String.valueOf(getArmyOne().getCommanderUnits().size())); + armyOneNumberOfCavalry.setText(String.valueOf(getArmyOne().getCavalryUnits().size())); + armyOneNumberOfRanged.setText(String.valueOf(getArmyOne().getRangedUnits().size())); + armyOneNumberOfInfantry.setText(String.valueOf(getArmyOne().getInfantryUnits().size())); + + ObservableList<Unit> obsListArmyOne = updateUnitsListView(getArmyOne()); + listViewArmyOneUnits.setItems(obsListArmyOne); + } + + public void btnInitialiseArmyTwo(ActionEvent actionEvent) throws IOException { + String newArmyName = FileHandler.readArmyNameFromFile(getFilePathArmyTwo()); + nameArmyTwo.setText(newArmyName); + + Army newArmy = new Army(newArmyName); + newArmy.addUnitsFromFile(getFilePathArmyTwo()); + setArmyTwo(newArmy); + + armyTwoNumberOfUnits.setText(String.valueOf(getArmyTwo().getAllUnits().size())); + armyTwoNumberOfCommanders.setText(String.valueOf(getArmyTwo().getCommanderUnits().size())); + armyTwoNumberOfCavalry.setText(String.valueOf(getArmyTwo().getCavalryUnits().size())); + armyTwoNumberOfRanged.setText(String.valueOf(getArmyTwo().getRangedUnits().size())); + armyTwoNumberOfInfantry.setText(String.valueOf(getArmyTwo().getInfantryUnits().size())); + + ObservableList<Unit> obsListArmyTwo = updateUnitsListView(getArmyTwo()); + listViewArmyTwoUnits.setItems(obsListArmyTwo); + } + + @Override + public void initialize(URL url, ResourceBundle resourceBundle) { + + setFilePathArmyOne(new File("src/main/resources/battle-files/The Orcish Horde.csv")); + filePathArmyOne.setText(getFilePathArmyOne()); + + setFilePathArmyTwo(new File("src/main/resources/battle-files/The Human Army.csv")); + filePathArmyTwo.setText(getFilePathArmyTwo()); + } +} diff --git a/src/main/java/edu/ntnu/idatt2001/runarin/wargames/frontend/model/WarGamesModel.java b/src/main/java/edu/ntnu/idatt2001/runarin/wargames/frontend/model/WarGamesModel.java new file mode 100644 index 0000000000000000000000000000000000000000..63727dab75a4f60fbb59b9ff7d6cfa094226fe12 --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2001/runarin/wargames/frontend/model/WarGamesModel.java @@ -0,0 +1,51 @@ +package edu.ntnu.idatt2001.runarin.wargames.frontend.model; + +import edu.ntnu.idatt2001.runarin.wargames.backend.armies.Army; +import java.io.File; + +/** + * + * + * @author Runar Indahl + * @version 3.0 + * @since 2022-04-19 + */ +public class WarGamesModel { + + private static Army armyOne; + private static Army armyTwo; + private static File filePathArmyOne; + private static File filePathArmyTwo; + + public static Army getArmyOne() { + return armyOne; + } + + public static Army getArmyTwo() { + return armyTwo; + } + + public static void setArmyOne(Army armyOne) { + WarGamesModel.armyOne = armyOne; + } + + public static void setArmyTwo(Army armyTwo) { + WarGamesModel.armyTwo = armyTwo; + } + + public static String getFilePathArmyOne() { + return filePathArmyOne.getPath(); + } + + public static String getFilePathArmyTwo() { + return filePathArmyTwo.getPath(); + } + + public static void setFilePathArmyOne(File filePathArmyOne) { + WarGamesModel.filePathArmyOne = filePathArmyOne; + } + + public static void setFilePathArmyTwo(File filePathArmyTwo) { + WarGamesModel.filePathArmyTwo = filePathArmyTwo; + } +} diff --git a/src/main/java/edu/ntnu/idatt2001/runarin/wargames/frontend/views/WarGamesApp.java b/src/main/java/edu/ntnu/idatt2001/runarin/wargames/frontend/views/WarGamesApp.java new file mode 100644 index 0000000000000000000000000000000000000000..021e436fb83aee27646811506e75ffdd5a30524f --- /dev/null +++ b/src/main/java/edu/ntnu/idatt2001/runarin/wargames/frontend/views/WarGamesApp.java @@ -0,0 +1,79 @@ +package edu.ntnu.idatt2001.runarin.wargames.frontend.views; + +import javafx.application.Application; +import javafx.fxml.FXMLLoader; +import javafx.scene.Scene; +import javafx.scene.control.Alert; +import javafx.scene.image.Image; +import javafx.stage.Stage; + +/** + * The view-class which launches the war games' main window/application. + * + * @author Runar Indahl + * @version 3.0 + * @since 2022-04-18 + */ +public class WarGamesApp extends Application { + + private static final String VERSION = "3.0"; + private static Alert alert; + + /** + * Method loads the application window. + * + * @param stage to show the view. + * @throws Exception thrown from FXMLLoader. + */ + @Override + public void start(Stage stage) throws Exception { + FXMLLoader root = new FXMLLoader( + WarGamesApp.class.getClassLoader().getResource("war_games_view.fxml")); + Scene scene = new Scene(root.load()); + + stage.setTitle("War Games v." + VERSION); + + Image icon = new Image("icon.png"); + stage.getIcons().add(icon); + + stage.setScene(scene); + stage.show(); + } + + /** + * Give information. + * Static method that can be called by the controller. + * + * @param message the message + */ + public static void giveInformation(String message) { + alert = new Alert(Alert.AlertType.INFORMATION); + alert.setTitle("Information"); + alert.setHeaderText(null); + alert.setContentText(message); + alert.showAndWait(); + } + + /** + * Give error. + * Static method that can be called by the controller. + * + * @param message the message + */ + public static void giveError(String message) { + alert = new Alert(Alert.AlertType.ERROR); + alert.setTitle("Error"); + alert.setHeaderText(null); + alert.setContentText(message); + alert.showAndWait(); + } + + /** + * Initialising the application with main method. + * + * @param args command line arguments provided during startup. Not used in this app. + */ + public static void main(String[] args) { + launch(args); + } +} diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 79a701d35cfc3e4dcd6ea7fc56baa08987703937..f3d9d0568cbfc0540d21b04f813d1d871da16d00 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -1,5 +1,9 @@ module wargames { requires javafx.controls; + requires javafx.fxml; + requires javafx.graphics; + opens edu.ntnu.idatt2001.runarin.wargames.frontend.controllers to javafx.fxml; exports edu.ntnu.idatt2001.runarin.wargames.frontend; + exports edu.ntnu.idatt2001.runarin.wargames.frontend.views to javafx.graphics; } \ No newline at end of file diff --git a/src/main/resources/battle-files/BattleLog.txt b/src/main/resources/battle-files/BattleLog.txt new file mode 100644 index 0000000000000000000000000000000000000000..95ff119c438b034bed0bb6645d48fb4fc3d3335b --- /dev/null +++ b/src/main/resources/battle-files/BattleLog.txt @@ -0,0 +1,474 @@ + + +Round 1 Grunt [100 hp] VS. Footman [100 hp] + Grunt strikes and deals 6 damage to Footman [94 hp] + Footman strikes and deals 6 damage to Grunt [94 hp] + +Round 2 Grunt [94 hp] VS. Footman [94 hp] + Footman strikes and deals 6 damage to Grunt [88 hp] + Grunt strikes and deals 6 damage to Footman [88 hp] + +Round 3 Grunt [88 hp] VS. Footman [88 hp] + Footman strikes and deals 6 damage to Grunt [82 hp] + Grunt strikes and deals 6 damage to Footman [82 hp] + +Round 4 Grunt [82 hp] VS. Footman [82 hp] + Grunt strikes and deals 6 damage to Footman [76 hp] + Footman strikes and deals 6 damage to Grunt [76 hp] + +Round 5 Grunt [76 hp] VS. Footman [76 hp] + Grunt strikes and deals 6 damage to Footman [70 hp] + Footman strikes and deals 6 damage to Grunt [70 hp] + +Round 6 Grunt [70 hp] VS. Footman [70 hp] + Grunt strikes and deals 6 damage to Footman [64 hp] + Footman strikes and deals 6 damage to Grunt [64 hp] + +Round 7 Grunt [64 hp] VS. Footman [64 hp] + Footman strikes and deals 6 damage to Grunt [58 hp] + Grunt strikes and deals 6 damage to Footman [58 hp] + +Round 8 Grunt [58 hp] VS. Footman [58 hp] + Grunt strikes and deals 6 damage to Footman [52 hp] + Footman strikes and deals 6 damage to Grunt [52 hp] + +Round 9 Grunt [52 hp] VS. Footman [52 hp] + Footman strikes and deals 6 damage to Grunt [46 hp] + Grunt strikes and deals 6 damage to Footman [46 hp] + +Round 10 Grunt [46 hp] VS. Footman [46 hp] + Footman strikes and deals 6 damage to Grunt [40 hp] + Grunt strikes and deals 6 damage to Footman [40 hp] + +Round 11 Grunt [40 hp] VS. Footman [40 hp] + Grunt strikes and deals 6 damage to Footman [34 hp] + Footman strikes and deals 6 damage to Grunt [34 hp] + +Round 12 Grunt [34 hp] VS. Footman [34 hp] + Footman strikes and deals 6 damage to Grunt [28 hp] + Grunt strikes and deals 6 damage to Footman [28 hp] + +Round 13 Grunt [28 hp] VS. Footman [28 hp] + Footman strikes and deals 6 damage to Grunt [22 hp] + Grunt strikes and deals 6 damage to Footman [22 hp] + +Round 14 Grunt [22 hp] VS. Footman [22 hp] + Grunt strikes and deals 6 damage to Footman [16 hp] + Footman strikes and deals 6 damage to Grunt [16 hp] + +Round 15 Grunt [16 hp] VS. Footman [16 hp] + Grunt strikes and deals 6 damage to Footman [10 hp] + Footman strikes and deals 6 damage to Grunt [10 hp] + +Round 16 Grunt [10 hp] VS. Footman [10 hp] + Footman strikes and deals 6 damage to Grunt [4 hp] + Grunt strikes and deals 6 damage to Footman [4 hp] + +Round 17 Grunt [4 hp] VS. Footman [4 hp] + Footman strikes and deals 4 damage to Grunt [0 hp] + Grunt died of fatal blow from Footman! + +Round 18 Spearman [100 hp] VS. Footman [4 hp] + Spearman strikes and deals 4 damage to Footman [0 hp] + Footman died of fatal blow from Spearman! + +Round 19 Spearman [100 hp] VS. Knight [100 hp] + Knight strikes and deals 12 damage to Spearman [88 hp] + Spearman strikes and deals 9 damage to Knight [91 hp] + +Round 20 Spearman [88 hp] VS. Knight [91 hp] + Spearman strikes and deals 9 damage to Knight [82 hp] + Knight strikes and deals 10 damage to Spearman [78 hp] + +Round 21 Spearman [78 hp] VS. Knight [82 hp] + Knight strikes and deals 12 damage to Spearman [66 hp] + Spearman strikes and deals 9 damage to Knight [73 hp] + +Round 22 Spearman [66 hp] VS. Knight [73 hp] + Spearman strikes and deals 9 damage to Knight [64 hp] + Knight strikes and deals 12 damage to Spearman [54 hp] + +Round 23 Spearman [54 hp] VS. Knight [64 hp] + Spearman strikes and deals 9 damage to Knight [55 hp] + Knight strikes and deals 12 damage to Spearman [42 hp] + +Round 24 Spearman [42 hp] VS. Knight [55 hp] + Spearman strikes and deals 9 damage to Knight [46 hp] + Knight strikes and deals 12 damage to Spearman [30 hp] + +Round 25 Spearman [30 hp] VS. Knight [46 hp] + Spearman strikes and deals 9 damage to Knight [37 hp] + Knight strikes and deals 12 damage to Spearman [18 hp] + +Round 26 Spearman [18 hp] VS. Knight [37 hp] + Knight strikes and deals 12 damage to Spearman [6 hp] + Spearman strikes and deals 9 damage to Knight [28 hp] + +Round 27 Spearman [6 hp] VS. Knight [28 hp] + Knight strikes and deals 6 damage to Spearman [0 hp] + Spearman died of fatal blow from Knight! + +Round 28 Raider [100 hp] VS. Knight [28 hp] + Raider strikes and deals 13 damage to Knight [15 hp] + Knight strikes and deals 13 damage to Raider [87 hp] + +Round 29 Raider [87 hp] VS. Knight [15 hp] + Knight strikes and deals 9 damage to Raider [78 hp] + Raider strikes and deals 9 damage to Knight [6 hp] + +Round 30 Raider [78 hp] VS. Knight [6 hp] + Knight strikes and deals 9 damage to Raider [69 hp] + Raider strikes and deals 6 damage to Knight [0 hp] + Knight died of fatal blow from Raider! + +Round 31 Raider [69 hp] VS. Mountain King [180 hp] + Mountain King strikes and deals 18 damage to Raider [51 hp] + Raider strikes and deals 10 damage to Mountain King [170 hp] + +Round 32 Raider [51 hp] VS. Mountain King [170 hp] + Mountain King strikes and deals 14 damage to Raider [37 hp] + Raider strikes and deals 6 damage to Mountain King [164 hp] + +Round 33 Raider [37 hp] VS. Mountain King [164 hp] + Mountain King strikes and deals 14 damage to Raider [23 hp] + Raider strikes and deals 6 damage to Mountain King [158 hp] + +Round 34 Raider [23 hp] VS. Mountain King [158 hp] + Mountain King strikes and deals 14 damage to Raider [9 hp] + Raider strikes and deals 6 damage to Mountain King [152 hp] + +Round 35 Raider [9 hp] VS. Mountain King [152 hp] + Raider strikes and deals 6 damage to Mountain King [146 hp] + Mountain King strikes and deals 9 damage to Raider [0 hp] + Raider died of fatal blow from Mountain King! + +Round 36 Spearman [100 hp] VS. Mountain King [146 hp] + Mountain King strikes and deals 17 damage to Spearman [83 hp] + Spearman strikes and deals 6 damage to Mountain King [140 hp] + +Round 37 Spearman [83 hp] VS. Mountain King [140 hp] + Mountain King strikes and deals 15 damage to Spearman [68 hp] + Spearman strikes and deals 6 damage to Mountain King [134 hp] + +Round 38 Spearman [68 hp] VS. Mountain King [134 hp] + Spearman strikes and deals 6 damage to Mountain King [128 hp] + Mountain King strikes and deals 17 damage to Spearman [51 hp] + +Round 39 Spearman [51 hp] VS. Mountain King [128 hp] + Mountain King strikes and deals 17 damage to Spearman [34 hp] + Spearman strikes and deals 6 damage to Mountain King [122 hp] + +Round 40 Spearman [34 hp] VS. Mountain King [122 hp] + Mountain King strikes and deals 17 damage to Spearman [17 hp] + Spearman strikes and deals 6 damage to Mountain King [116 hp] + +Round 41 Spearman [17 hp] VS. Mountain King [116 hp] + Mountain King strikes and deals 17 damage to Spearman [0 hp] + Spearman died of fatal blow from Mountain King! + +Round 42 Raider [100 hp] VS. Mountain King [116 hp] + Mountain King strikes and deals 18 damage to Raider [82 hp] + Raider strikes and deals 10 damage to Mountain King [106 hp] + +Round 43 Raider [82 hp] VS. Mountain King [106 hp] + Raider strikes and deals 6 damage to Mountain King [100 hp] + Mountain King strikes and deals 14 damage to Raider [68 hp] + +Round 44 Raider [68 hp] VS. Mountain King [100 hp] + Mountain King strikes and deals 14 damage to Raider [54 hp] + Raider strikes and deals 6 damage to Mountain King [94 hp] + +Round 45 Raider [54 hp] VS. Mountain King [94 hp] + Raider strikes and deals 6 damage to Mountain King [88 hp] + Mountain King strikes and deals 14 damage to Raider [40 hp] + +Round 46 Raider [40 hp] VS. Mountain King [88 hp] + Mountain King strikes and deals 14 damage to Raider [26 hp] + Raider strikes and deals 6 damage to Mountain King [82 hp] + +Round 47 Raider [26 hp] VS. Mountain King [82 hp] + Mountain King strikes and deals 14 damage to Raider [12 hp] + Raider strikes and deals 6 damage to Mountain King [76 hp] + +Round 48 Raider [12 hp] VS. Mountain King [76 hp] + Raider strikes and deals 6 damage to Mountain King [70 hp] + Mountain King strikes and deals 12 damage to Raider [0 hp] + Raider died of fatal blow from Mountain King! + +Round 49 Grunt [100 hp] VS. Mountain King [70 hp] + Mountain King strikes and deals 20 damage to Grunt [80 hp] + Grunt strikes and deals 1 damage to Mountain King [69 hp] + +Round 50 Grunt [80 hp] VS. Mountain King [69 hp] + Mountain King strikes and deals 16 damage to Grunt [64 hp] + Grunt strikes and deals 1 damage to Mountain King [68 hp] + +Round 51 Grunt [64 hp] VS. Mountain King [68 hp] + Grunt strikes and deals 1 damage to Mountain King [67 hp] + Mountain King strikes and deals 16 damage to Grunt [48 hp] + +Round 52 Grunt [48 hp] VS. Mountain King [67 hp] + Grunt strikes and deals 1 damage to Mountain King [66 hp] + Mountain King strikes and deals 16 damage to Grunt [32 hp] + +Round 53 Grunt [32 hp] VS. Mountain King [66 hp] + Grunt strikes and deals 1 damage to Mountain King [65 hp] + Mountain King strikes and deals 16 damage to Grunt [16 hp] + +Round 54 Grunt [16 hp] VS. Mountain King [65 hp] + Grunt strikes and deals 1 damage to Mountain King [64 hp] + Mountain King strikes and deals 16 damage to Grunt [0 hp] + Grunt died of fatal blow from Mountain King! + +Round 55 Grunt [100 hp] VS. Mountain King [64 hp] + Mountain King strikes and deals 20 damage to Grunt [80 hp] + Grunt strikes and deals 1 damage to Mountain King [63 hp] + +Round 56 Grunt [80 hp] VS. Mountain King [63 hp] + Grunt strikes and deals 1 damage to Mountain King [62 hp] + Mountain King strikes and deals 16 damage to Grunt [64 hp] + +Round 57 Grunt [64 hp] VS. Mountain King [62 hp] + Grunt strikes and deals 1 damage to Mountain King [61 hp] + Mountain King strikes and deals 16 damage to Grunt [48 hp] + +Round 58 Grunt [48 hp] VS. Mountain King [61 hp] + Mountain King strikes and deals 16 damage to Grunt [32 hp] + Grunt strikes and deals 1 damage to Mountain King [60 hp] + +Round 59 Grunt [32 hp] VS. Mountain King [60 hp] + Grunt strikes and deals 1 damage to Mountain King [59 hp] + Mountain King strikes and deals 16 damage to Grunt [16 hp] + +Round 60 Grunt [16 hp] VS. Mountain King [59 hp] + Mountain King strikes and deals 16 damage to Grunt [0 hp] + Grunt died of fatal blow from Mountain King! + +Round 61 Gul'dan [180 hp] VS. Mountain King [59 hp] + Gul'dan strikes and deals 15 damage to Mountain King [44 hp] + Mountain King strikes and deals 15 damage to Gul'dan [165 hp] + +Round 62 Gul'dan [165 hp] VS. Mountain King [44 hp] + Gul'dan strikes and deals 11 damage to Mountain King [33 hp] + Mountain King strikes and deals 11 damage to Gul'dan [154 hp] + +Round 63 Gul'dan [154 hp] VS. Mountain King [33 hp] + Mountain King strikes and deals 11 damage to Gul'dan [143 hp] + Gul'dan strikes and deals 11 damage to Mountain King [22 hp] + +Round 64 Gul'dan [143 hp] VS. Mountain King [22 hp] + Gul'dan strikes and deals 11 damage to Mountain King [11 hp] + Mountain King strikes and deals 11 damage to Gul'dan [132 hp] + +Round 65 Gul'dan [132 hp] VS. Mountain King [11 hp] + Mountain King strikes and deals 11 damage to Gul'dan [121 hp] + Gul'dan strikes and deals 11 damage to Mountain King [0 hp] + Mountain King died of fatal blow from Gul'dan! + +Round 66 Gul'dan [121 hp] VS. Archer [100 hp] + Archer strikes and deals 6 damage to Gul'dan [115 hp] + Gul'dan strikes and deals 17 damage to Archer [83 hp] + +Round 67 Gul'dan [115 hp] VS. Archer [83 hp] + Archer strikes and deals 6 damage to Gul'dan [109 hp] + Gul'dan strikes and deals 15 damage to Archer [68 hp] + +Round 68 Gul'dan [109 hp] VS. Archer [68 hp] + Gul'dan strikes and deals 17 damage to Archer [51 hp] + Archer strikes and deals 6 damage to Gul'dan [103 hp] + +Round 69 Gul'dan [103 hp] VS. Archer [51 hp] + Gul'dan strikes and deals 17 damage to Archer [34 hp] + Archer strikes and deals 6 damage to Gul'dan [97 hp] + +Round 70 Gul'dan [97 hp] VS. Archer [34 hp] + Archer strikes and deals 6 damage to Gul'dan [91 hp] + Gul'dan strikes and deals 17 damage to Archer [17 hp] + +Round 71 Gul'dan [91 hp] VS. Archer [17 hp] + Gul'dan strikes and deals 17 damage to Archer [0 hp] + Archer died of fatal blow from Gul'dan! + +Round 72 Gul'dan [91 hp] VS. Knight [100 hp] + Gul'dan strikes and deals 18 damage to Knight [82 hp] + Knight strikes and deals 10 damage to Gul'dan [81 hp] + +Round 73 Gul'dan [81 hp] VS. Knight [82 hp] + Gul'dan strikes and deals 14 damage to Knight [68 hp] + Knight strikes and deals 6 damage to Gul'dan [75 hp] + +Round 74 Gul'dan [75 hp] VS. Knight [68 hp] + Gul'dan strikes and deals 14 damage to Knight [54 hp] + Knight strikes and deals 6 damage to Gul'dan [69 hp] + +Round 75 Gul'dan [69 hp] VS. Knight [54 hp] + Knight strikes and deals 6 damage to Gul'dan [63 hp] + Gul'dan strikes and deals 14 damage to Knight [40 hp] + +Round 76 Gul'dan [63 hp] VS. Knight [40 hp] + Gul'dan strikes and deals 14 damage to Knight [26 hp] + Knight strikes and deals 6 damage to Gul'dan [57 hp] + +Round 77 Gul'dan [57 hp] VS. Knight [26 hp] + Gul'dan strikes and deals 14 damage to Knight [12 hp] + Knight strikes and deals 6 damage to Gul'dan [51 hp] + +Round 78 Gul'dan [51 hp] VS. Knight [12 hp] + Knight strikes and deals 6 damage to Gul'dan [45 hp] + Gul'dan strikes and deals 12 damage to Knight [0 hp] + Knight died of fatal blow from Gul'dan! + +Round 79 Gul'dan [45 hp] VS. Footman [100 hp] + Footman strikes and deals 1 damage to Gul'dan [44 hp] + Gul'dan strikes and deals 20 damage to Footman [80 hp] + +Round 80 Gul'dan [44 hp] VS. Footman [80 hp] + Gul'dan strikes and deals 16 damage to Footman [64 hp] + Footman strikes and deals 1 damage to Gul'dan [43 hp] + +Round 81 Gul'dan [43 hp] VS. Footman [64 hp] + Gul'dan strikes and deals 16 damage to Footman [48 hp] + Footman strikes and deals 1 damage to Gul'dan [42 hp] + +Round 82 Gul'dan [42 hp] VS. Footman [48 hp] + Footman strikes and deals 1 damage to Gul'dan [41 hp] + Gul'dan strikes and deals 16 damage to Footman [32 hp] + +Round 83 Gul'dan [41 hp] VS. Footman [32 hp] + Gul'dan strikes and deals 16 damage to Footman [16 hp] + Footman strikes and deals 1 damage to Gul'dan [40 hp] + +Round 84 Gul'dan [40 hp] VS. Footman [16 hp] + Footman strikes and deals 1 damage to Gul'dan [39 hp] + Gul'dan strikes and deals 16 damage to Footman [0 hp] + Footman died of fatal blow from Gul'dan! + +Round 85 Gul'dan [39 hp] VS. Archer [100 hp] + Gul'dan strikes and deals 17 damage to Archer [83 hp] + Archer strikes and deals 6 damage to Gul'dan [33 hp] + +Round 86 Gul'dan [33 hp] VS. Archer [83 hp] + Gul'dan strikes and deals 15 damage to Archer [68 hp] + Archer strikes and deals 6 damage to Gul'dan [27 hp] + +Round 87 Gul'dan [27 hp] VS. Archer [68 hp] + Gul'dan strikes and deals 17 damage to Archer [51 hp] + Archer strikes and deals 6 damage to Gul'dan [21 hp] + +Round 88 Gul'dan [21 hp] VS. Archer [51 hp] + Archer strikes and deals 6 damage to Gul'dan [15 hp] + Gul'dan strikes and deals 17 damage to Archer [34 hp] + +Round 89 Gul'dan [15 hp] VS. Archer [34 hp] + Gul'dan strikes and deals 17 damage to Archer [17 hp] + Archer strikes and deals 6 damage to Gul'dan [9 hp] + +Round 90 Gul'dan [9 hp] VS. Archer [17 hp] + Gul'dan strikes and deals 17 damage to Archer [0 hp] + Archer died of fatal blow from Gul'dan! + +Round 91 Gul'dan [9 hp] VS. Knight [100 hp] + Gul'dan strikes and deals 18 damage to Knight [82 hp] + Knight strikes and deals 9 damage to Gul'dan [0 hp] + Gul'dan died of fatal blow from Knight! + +Round 92 Spearman [100 hp] VS. Knight [82 hp] + Knight strikes and deals 12 damage to Spearman [88 hp] + Spearman strikes and deals 9 damage to Knight [73 hp] + +Round 93 Spearman [88 hp] VS. Knight [73 hp] + Knight strikes and deals 10 damage to Spearman [78 hp] + Spearman strikes and deals 9 damage to Knight [64 hp] + +Round 94 Spearman [78 hp] VS. Knight [64 hp] + Spearman strikes and deals 9 damage to Knight [55 hp] + Knight strikes and deals 12 damage to Spearman [66 hp] + +Round 95 Spearman [66 hp] VS. Knight [55 hp] + Knight strikes and deals 12 damage to Spearman [54 hp] + Spearman strikes and deals 9 damage to Knight [46 hp] + +Round 96 Spearman [54 hp] VS. Knight [46 hp] + Spearman strikes and deals 9 damage to Knight [37 hp] + Knight strikes and deals 12 damage to Spearman [42 hp] + +Round 97 Spearman [42 hp] VS. Knight [37 hp] + Spearman strikes and deals 9 damage to Knight [28 hp] + Knight strikes and deals 12 damage to Spearman [30 hp] + +Round 98 Spearman [30 hp] VS. Knight [28 hp] + Knight strikes and deals 12 damage to Spearman [18 hp] + Spearman strikes and deals 9 damage to Knight [19 hp] + +Round 99 Spearman [18 hp] VS. Knight [19 hp] + Knight strikes and deals 12 damage to Spearman [6 hp] + Spearman strikes and deals 9 damage to Knight [10 hp] + +Round 100 Spearman [6 hp] VS. Knight [10 hp] + Spearman strikes and deals 9 damage to Knight [1 hp] + Knight strikes and deals 6 damage to Spearman [0 hp] + Spearman died of fatal blow from Knight! + +Round 101 Raider [100 hp] VS. Knight [1 hp] + Raider strikes and deals 1 damage to Knight [0 hp] + Knight died of fatal blow from Raider! + +Round 102 Raider [100 hp] VS. Archer [100 hp] + Archer strikes and deals 9 damage to Raider [91 hp] + Raider strikes and deals 12 damage to Archer [88 hp] + +Round 103 Raider [91 hp] VS. Archer [88 hp] + Raider strikes and deals 10 damage to Archer [78 hp] + Archer strikes and deals 9 damage to Raider [82 hp] + +Round 104 Raider [82 hp] VS. Archer [78 hp] + Raider strikes and deals 12 damage to Archer [66 hp] + Archer strikes and deals 9 damage to Raider [73 hp] + +Round 105 Raider [73 hp] VS. Archer [66 hp] + Raider strikes and deals 12 damage to Archer [54 hp] + Archer strikes and deals 9 damage to Raider [64 hp] + +Round 106 Raider [64 hp] VS. Archer [54 hp] + Archer strikes and deals 9 damage to Raider [55 hp] + Raider strikes and deals 12 damage to Archer [42 hp] + +Round 107 Raider [55 hp] VS. Archer [42 hp] + Raider strikes and deals 12 damage to Archer [30 hp] + Archer strikes and deals 9 damage to Raider [46 hp] + +Round 108 Raider [46 hp] VS. Archer [30 hp] + Archer strikes and deals 9 damage to Raider [37 hp] + Raider strikes and deals 12 damage to Archer [18 hp] + +Round 109 Raider [37 hp] VS. Archer [18 hp] + Archer strikes and deals 9 damage to Raider [28 hp] + Raider strikes and deals 12 damage to Archer [6 hp] + +Round 110 Raider [28 hp] VS. Archer [6 hp] + Archer strikes and deals 9 damage to Raider [19 hp] + Raider strikes and deals 6 damage to Archer [0 hp] + Archer died of fatal blow from Raider! + +Round 111 Raider [19 hp] VS. Footman [100 hp] + Footman strikes and deals 4 damage to Raider [15 hp] + Raider strikes and deals 15 damage to Footman [85 hp] + +Round 112 Raider [15 hp] VS. Footman [85 hp] + Footman strikes and deals 4 damage to Raider [11 hp] + Raider strikes and deals 11 damage to Footman [74 hp] + +Round 113 Raider [11 hp] VS. Footman [74 hp] + Raider strikes and deals 11 damage to Footman [63 hp] + Footman strikes and deals 4 damage to Raider [7 hp] + +Round 114 Raider [7 hp] VS. Footman [63 hp] + Footman strikes and deals 4 damage to Raider [3 hp] + Raider strikes and deals 11 damage to Footman [52 hp] + +Round 115 Raider [3 hp] VS. Footman [52 hp] + Raider strikes and deals 11 damage to Footman [41 hp] + Footman strikes and deals 3 damage to Raider [0 hp] + Raider died of fatal blow from Footman! + + The Human Army wins the battle! \ No newline at end of file diff --git a/src/main/resources/battle-files/The Human Army.csv b/src/main/resources/battle-files/The Human Army.csv new file mode 100644 index 0000000000000000000000000000000000000000..f14bd669545fec4bf3e66597b5770c45d0438a7d --- /dev/null +++ b/src/main/resources/battle-files/The Human Army.csv @@ -0,0 +1,11 @@ +The Human Army +CommanderUnit,Mountain King,180 +CavalryUnit,Knight,100 +CavalryUnit,Knight,100 +CavalryUnit,Knight,100 +RangedUnit,Archer,100 +RangedUnit,Archer,100 +RangedUnit,Archer,100 +InfantryUnit,Footman,100 +InfantryUnit,Footman,100 +InfantryUnit,Footman,100 diff --git a/src/main/resources/battle-files/The Orcish Horde.csv b/src/main/resources/battle-files/The Orcish Horde.csv new file mode 100644 index 0000000000000000000000000000000000000000..2074cff9085f4d7c6be737f94149ec0cf602551b --- /dev/null +++ b/src/main/resources/battle-files/The Orcish Horde.csv @@ -0,0 +1,11 @@ +The Orcish Horde +CommanderUnit,Gul'dan,180 +CavalryUnit,Raider,100 +CavalryUnit,Raider,100 +CavalryUnit,Raider,100 +RangedUnit,Spearman,100 +RangedUnit,Spearman,100 +RangedUnit,Spearman,100 +InfantryUnit,Grunt,100 +InfantryUnit,Grunt,100 +InfantryUnit,Grunt,100 diff --git a/src/main/resources/battle-log/BattleLog.txt b/src/main/resources/battle-log/BattleLog.txt deleted file mode 100644 index 95b6bde383ab9622d8155f521311e7a7dedda7d5..0000000000000000000000000000000000000000 --- a/src/main/resources/battle-log/BattleLog.txt +++ /dev/null @@ -1,597 +0,0 @@ - -Round 1 - Grunt [100 HP] against Knight [100 HP] - Knight [100 HP] strikes and deals 15 damage to Grunt [100 HP][-15 HP] - Grunt [85 HP] then deals 4 damage to Knight [100 HP][-4 HP] - -Round 2 - Grunt [85 HP] against Knight [96 HP] - Grunt [85 HP] strikes and deals 4 damage to Knight [96 HP][-4 HP] - Knight [92 HP] then deals 11 damage to Grunt [85 HP][-11 HP] - -Round 3 - Grunt [74 HP] against Knight [92 HP] - Grunt [74 HP] strikes and deals 4 damage to Knight [92 HP][-4 HP] - Knight [88 HP] then deals 11 damage to Grunt [74 HP][-11 HP] - -Round 4 - Grunt [63 HP] against Knight [88 HP] - Knight [88 HP] strikes and deals 11 damage to Grunt [63 HP][-11 HP] - Grunt [52 HP] then deals 4 damage to Knight [88 HP][-4 HP] - -Round 5 - Grunt [52 HP] against Knight [84 HP] - Grunt [52 HP] strikes and deals 4 damage to Knight [84 HP][-4 HP] - Knight [80 HP] then deals 11 damage to Grunt [52 HP][-11 HP] - -Round 6 - Grunt [41 HP] against Knight [80 HP] - Knight [80 HP] strikes and deals 11 damage to Grunt [41 HP][-11 HP] - Grunt [30 HP] then deals 4 damage to Knight [80 HP][-4 HP] - -Round 7 - Grunt [30 HP] against Knight [76 HP] - Grunt [30 HP] strikes and deals 4 damage to Knight [76 HP][-4 HP] - Knight [72 HP] then deals 11 damage to Grunt [30 HP][-11 HP] - -Round 8 - Grunt [19 HP] against Knight [72 HP] - Knight [72 HP] strikes and deals 11 damage to Grunt [19 HP][-11 HP] - Grunt [8 HP] then deals 4 damage to Knight [72 HP][-4 HP] - -Round 9 - Grunt [8 HP] against Knight [68 HP] - Grunt [8 HP] strikes and deals 4 damage to Knight [68 HP][-4 HP] - Knight [64 HP] then deals 8 damage to Grunt [8 HP][-8 HP] - - Grunt died of fatal blow from Knight! - -Round 10 - Raider [100 HP] against Knight [64 HP] - Knight [64 HP] strikes and deals 13 damage to Raider [100 HP][-13 HP] - Raider [87 HP] then deals 13 damage to Knight [64 HP][-13 HP] - -Round 11 - Raider [87 HP] against Knight [51 HP] - Raider [87 HP] strikes and deals 9 damage to Knight [51 HP][-9 HP] - Knight [42 HP] then deals 9 damage to Raider [87 HP][-9 HP] - -Round 12 - Raider [78 HP] against Knight [42 HP] - Knight [42 HP] strikes and deals 9 damage to Raider [78 HP][-9 HP] - Raider [69 HP] then deals 9 damage to Knight [42 HP][-9 HP] - -Round 13 - Raider [69 HP] against Knight [33 HP] - Knight [33 HP] strikes and deals 9 damage to Raider [69 HP][-9 HP] - Raider [60 HP] then deals 9 damage to Knight [33 HP][-9 HP] - -Round 14 - Raider [60 HP] against Knight [24 HP] - Knight [24 HP] strikes and deals 9 damage to Raider [60 HP][-9 HP] - Raider [51 HP] then deals 9 damage to Knight [24 HP][-9 HP] - -Round 15 - Raider [51 HP] against Knight [15 HP] - Raider [51 HP] strikes and deals 9 damage to Knight [15 HP][-9 HP] - Knight [6 HP] then deals 9 damage to Raider [51 HP][-9 HP] - -Round 16 - Raider [42 HP] against Knight [6 HP] - Raider [42 HP] strikes and deals 6 damage to Knight [6 HP][-6 HP] - - Knight died of fatal blow from Raider! - -Round 17 - Raider [42 HP] against Footman [100 HP] - Raider [42 HP] strikes and deals 15 damage to Footman [100 HP][-15 HP] - Footman [85 HP] then deals 4 damage to Raider [42 HP][-4 HP] - -Round 18 - Raider [38 HP] against Footman [85 HP] - Raider [38 HP] strikes and deals 11 damage to Footman [85 HP][-11 HP] - Footman [74 HP] then deals 4 damage to Raider [38 HP][-4 HP] - -Round 19 - Raider [34 HP] against Footman [74 HP] - Raider [34 HP] strikes and deals 11 damage to Footman [74 HP][-11 HP] - Footman [63 HP] then deals 4 damage to Raider [34 HP][-4 HP] - -Round 20 - Raider [30 HP] against Footman [63 HP] - Raider [30 HP] strikes and deals 11 damage to Footman [63 HP][-11 HP] - Footman [52 HP] then deals 4 damage to Raider [30 HP][-4 HP] - -Round 21 - Raider [26 HP] against Footman [52 HP] - Footman [52 HP] strikes and deals 4 damage to Raider [26 HP][-4 HP] - Raider [22 HP] then deals 11 damage to Footman [52 HP][-11 HP] - -Round 22 - Raider [22 HP] against Footman [41 HP] - Footman [41 HP] strikes and deals 4 damage to Raider [22 HP][-4 HP] - Raider [18 HP] then deals 11 damage to Footman [41 HP][-11 HP] - -Round 23 - Raider [18 HP] against Footman [30 HP] - Raider [18 HP] strikes and deals 11 damage to Footman [30 HP][-11 HP] - Footman [19 HP] then deals 4 damage to Raider [18 HP][-4 HP] - -Round 24 - Raider [14 HP] against Footman [19 HP] - Raider [14 HP] strikes and deals 11 damage to Footman [19 HP][-11 HP] - Footman [8 HP] then deals 4 damage to Raider [14 HP][-4 HP] - -Round 25 - Raider [10 HP] against Footman [8 HP] - Raider [10 HP] strikes and deals 8 damage to Footman [8 HP][-8 HP] - - Footman died of fatal blow from Raider! - -Round 26 - Raider [10 HP] against Mountain King [180 HP] - Mountain King [180 HP] strikes and deals 10 damage to Raider [10 HP][-10 HP] - - Raider died of fatal blow from Mountain King! - -Round 27 - Grunt [100 HP] against Mountain King [180 HP] - Mountain King [180 HP] strikes and deals 15 damage to Grunt [100 HP][-15 HP] - Grunt [85 HP] then deals 4 damage to Mountain King [180 HP][-4 HP] - -Round 28 - Grunt [85 HP] against Mountain King [176 HP] - Grunt [85 HP] strikes and deals 4 damage to Mountain King [176 HP][-4 HP] - Mountain King [172 HP] then deals 11 damage to Grunt [85 HP][-11 HP] - -Round 29 - Grunt [74 HP] against Mountain King [172 HP] - Mountain King [172 HP] strikes and deals 11 damage to Grunt [74 HP][-11 HP] - Grunt [63 HP] then deals 4 damage to Mountain King [172 HP][-4 HP] - -Round 30 - Grunt [63 HP] against Mountain King [168 HP] - Grunt [63 HP] strikes and deals 4 damage to Mountain King [168 HP][-4 HP] - Mountain King [164 HP] then deals 11 damage to Grunt [63 HP][-11 HP] - -Round 31 - Grunt [52 HP] against Mountain King [164 HP] - Mountain King [164 HP] strikes and deals 11 damage to Grunt [52 HP][-11 HP] - Grunt [41 HP] then deals 4 damage to Mountain King [164 HP][-4 HP] - -Round 32 - Grunt [41 HP] against Mountain King [160 HP] - Grunt [41 HP] strikes and deals 4 damage to Mountain King [160 HP][-4 HP] - Mountain King [156 HP] then deals 11 damage to Grunt [41 HP][-11 HP] - -Round 33 - Grunt [30 HP] against Mountain King [156 HP] - Mountain King [156 HP] strikes and deals 11 damage to Grunt [30 HP][-11 HP] - Grunt [19 HP] then deals 4 damage to Mountain King [156 HP][-4 HP] - -Round 34 - Grunt [19 HP] against Mountain King [152 HP] - Mountain King [152 HP] strikes and deals 11 damage to Grunt [19 HP][-11 HP] - Grunt [8 HP] then deals 4 damage to Mountain King [152 HP][-4 HP] - -Round 35 - Grunt [8 HP] against Mountain King [148 HP] - Grunt [8 HP] strikes and deals 4 damage to Mountain King [148 HP][-4 HP] - Mountain King [144 HP] then deals 8 damage to Grunt [8 HP][-8 HP] - - Grunt died of fatal blow from Mountain King! - -Round 36 - Spearman [100 HP] against Mountain King [144 HP] - Spearman [100 HP] strikes and deals 9 damage to Mountain King [144 HP][-9 HP] - Mountain King [135 HP] then deals 12 damage to Spearman [100 HP][-12 HP] - -Round 37 - Spearman [88 HP] against Mountain King [135 HP] - Mountain King [135 HP] strikes and deals 10 damage to Spearman [88 HP][-10 HP] - Spearman [78 HP] then deals 9 damage to Mountain King [135 HP][-9 HP] - -Round 38 - Spearman [78 HP] against Mountain King [126 HP] - Mountain King [126 HP] strikes and deals 12 damage to Spearman [78 HP][-12 HP] - Spearman [66 HP] then deals 9 damage to Mountain King [126 HP][-9 HP] - -Round 39 - Spearman [66 HP] against Mountain King [117 HP] - Spearman [66 HP] strikes and deals 9 damage to Mountain King [117 HP][-9 HP] - Mountain King [108 HP] then deals 12 damage to Spearman [66 HP][-12 HP] - -Round 40 - Spearman [54 HP] against Mountain King [108 HP] - Spearman [54 HP] strikes and deals 9 damage to Mountain King [108 HP][-9 HP] - Mountain King [99 HP] then deals 12 damage to Spearman [54 HP][-12 HP] - -Round 41 - Spearman [42 HP] against Mountain King [99 HP] - Mountain King [99 HP] strikes and deals 12 damage to Spearman [42 HP][-12 HP] - Spearman [30 HP] then deals 9 damage to Mountain King [99 HP][-9 HP] - -Round 42 - Spearman [30 HP] against Mountain King [90 HP] - Mountain King [90 HP] strikes and deals 12 damage to Spearman [30 HP][-12 HP] - Spearman [18 HP] then deals 9 damage to Mountain King [90 HP][-9 HP] - -Round 43 - Spearman [18 HP] against Mountain King [81 HP] - Mountain King [81 HP] strikes and deals 12 damage to Spearman [18 HP][-12 HP] - Spearman [6 HP] then deals 9 damage to Mountain King [81 HP][-9 HP] - -Round 44 - Spearman [6 HP] against Mountain King [72 HP] - Spearman [6 HP] strikes and deals 9 damage to Mountain King [72 HP][-9 HP] - Mountain King [63 HP] then deals 6 damage to Spearman [6 HP][-6 HP] - - Spearman died of fatal blow from Mountain King! - -Round 45 - Spearman [100 HP] against Mountain King [63 HP] - Spearman [100 HP] strikes and deals 9 damage to Mountain King [63 HP][-9 HP] - Mountain King [54 HP] then deals 12 damage to Spearman [100 HP][-12 HP] - -Round 46 - Spearman [88 HP] against Mountain King [54 HP] - Mountain King [54 HP] strikes and deals 10 damage to Spearman [88 HP][-10 HP] - Spearman [78 HP] then deals 9 damage to Mountain King [54 HP][-9 HP] - -Round 47 - Spearman [78 HP] against Mountain King [45 HP] - Mountain King [45 HP] strikes and deals 12 damage to Spearman [78 HP][-12 HP] - Spearman [66 HP] then deals 9 damage to Mountain King [45 HP][-9 HP] - -Round 48 - Spearman [66 HP] against Mountain King [36 HP] - Spearman [66 HP] strikes and deals 9 damage to Mountain King [36 HP][-9 HP] - Mountain King [27 HP] then deals 12 damage to Spearman [66 HP][-12 HP] - -Round 49 - Spearman [54 HP] against Mountain King [27 HP] - Mountain King [27 HP] strikes and deals 12 damage to Spearman [54 HP][-12 HP] - Spearman [42 HP] then deals 9 damage to Mountain King [27 HP][-9 HP] - -Round 50 - Spearman [42 HP] against Mountain King [18 HP] - Mountain King [18 HP] strikes and deals 12 damage to Spearman [42 HP][-12 HP] - Spearman [30 HP] then deals 9 damage to Mountain King [18 HP][-9 HP] - -Round 51 - Spearman [30 HP] against Mountain King [9 HP] - Spearman [30 HP] strikes and deals 9 damage to Mountain King [9 HP][-9 HP] - - Mountain King died of fatal blow from Spearman! - -Round 52 - Spearman [30 HP] against Archer [100 HP] - Spearman [30 HP] strikes and deals 8 damage to Archer [100 HP][-8 HP] - Archer [92 HP] then deals 10 damage to Spearman [30 HP][-10 HP] - -Round 53 - Spearman [20 HP] against Archer [92 HP] - Archer [92 HP] strikes and deals 12 damage to Spearman [20 HP][-12 HP] - Spearman [8 HP] then deals 10 damage to Archer [92 HP][-10 HP] - -Round 54 - Spearman [8 HP] against Archer [82 HP] - Spearman [8 HP] strikes and deals 12 damage to Archer [82 HP][-12 HP] - Archer [70 HP] then deals 8 damage to Spearman [8 HP][-8 HP] - - Spearman died of fatal blow from Archer! - -Round 55 - Grunt [100 HP] against Archer [70 HP] - Archer [70 HP] strikes and deals 11 damage to Grunt [100 HP][-11 HP] - Grunt [89 HP] then deals 5 damage to Archer [70 HP][-5 HP] - -Round 56 - Grunt [89 HP] against Archer [65 HP] - Archer [65 HP] strikes and deals 11 damage to Grunt [89 HP][-11 HP] - Grunt [78 HP] then deals 7 damage to Archer [65 HP][-7 HP] - -Round 57 - Grunt [78 HP] against Archer [58 HP] - Archer [58 HP] strikes and deals 11 damage to Grunt [78 HP][-11 HP] - Grunt [67 HP] then deals 7 damage to Archer [58 HP][-7 HP] - -Round 58 - Grunt [67 HP] against Archer [51 HP] - Archer [51 HP] strikes and deals 11 damage to Grunt [67 HP][-11 HP] - Grunt [56 HP] then deals 7 damage to Archer [51 HP][-7 HP] - -Round 59 - Grunt [56 HP] against Archer [44 HP] - Archer [44 HP] strikes and deals 11 damage to Grunt [56 HP][-11 HP] - Grunt [45 HP] then deals 7 damage to Archer [44 HP][-7 HP] - -Round 60 - Grunt [45 HP] against Archer [37 HP] - Grunt [45 HP] strikes and deals 7 damage to Archer [37 HP][-7 HP] - Archer [30 HP] then deals 11 damage to Grunt [45 HP][-11 HP] - -Round 61 - Grunt [34 HP] against Archer [30 HP] - Archer [30 HP] strikes and deals 11 damage to Grunt [34 HP][-11 HP] - Grunt [23 HP] then deals 7 damage to Archer [30 HP][-7 HP] - -Round 62 - Grunt [23 HP] against Archer [23 HP] - Archer [23 HP] strikes and deals 11 damage to Grunt [23 HP][-11 HP] - Grunt [12 HP] then deals 7 damage to Archer [23 HP][-7 HP] - -Round 63 - Grunt [12 HP] against Archer [16 HP] - Archer [16 HP] strikes and deals 11 damage to Grunt [12 HP][-11 HP] - Grunt [1 HP] then deals 7 damage to Archer [16 HP][-7 HP] - -Round 64 - Grunt [1 HP] against Archer [9 HP] - Grunt [1 HP] strikes and deals 7 damage to Archer [9 HP][-7 HP] - Archer [2 HP] then deals 1 damage to Grunt [1 HP][-1 HP] - - Grunt died of fatal blow from Archer! - -Round 65 - Gul'dan [180 HP] against Archer [2 HP] - Gul'dan [180 HP] strikes and deals 2 damage to Archer [2 HP][-2 HP] - - Archer died of fatal blow from Gul'dan! - -Round 66 - Gul'dan [180 HP] against Knight [100 HP] - Gul'dan [180 HP] strikes and deals 13 damage to Knight [100 HP][-13 HP] - Knight [87 HP] then deals 13 damage to Gul'dan [180 HP][-13 HP] - -Round 67 - Gul'dan [167 HP] against Knight [87 HP] - Knight [87 HP] strikes and deals 9 damage to Gul'dan [167 HP][-9 HP] - Gul'dan [158 HP] then deals 9 damage to Knight [87 HP][-9 HP] - -Round 68 - Gul'dan [158 HP] against Knight [78 HP] - Gul'dan [158 HP] strikes and deals 9 damage to Knight [78 HP][-9 HP] - Knight [69 HP] then deals 9 damage to Gul'dan [158 HP][-9 HP] - -Round 69 - Gul'dan [149 HP] against Knight [69 HP] - Gul'dan [149 HP] strikes and deals 9 damage to Knight [69 HP][-9 HP] - Knight [60 HP] then deals 9 damage to Gul'dan [149 HP][-9 HP] - -Round 70 - Gul'dan [140 HP] against Knight [60 HP] - Knight [60 HP] strikes and deals 9 damage to Gul'dan [140 HP][-9 HP] - Gul'dan [131 HP] then deals 9 damage to Knight [60 HP][-9 HP] - -Round 71 - Gul'dan [131 HP] against Knight [51 HP] - Knight [51 HP] strikes and deals 9 damage to Gul'dan [131 HP][-9 HP] - Gul'dan [122 HP] then deals 9 damage to Knight [51 HP][-9 HP] - -Round 72 - Gul'dan [122 HP] against Knight [42 HP] - Gul'dan [122 HP] strikes and deals 9 damage to Knight [42 HP][-9 HP] - Knight [33 HP] then deals 9 damage to Gul'dan [122 HP][-9 HP] - -Round 73 - Gul'dan [113 HP] against Knight [33 HP] - Knight [33 HP] strikes and deals 9 damage to Gul'dan [113 HP][-9 HP] - Gul'dan [104 HP] then deals 9 damage to Knight [33 HP][-9 HP] - -Round 74 - Gul'dan [104 HP] against Knight [24 HP] - Knight [24 HP] strikes and deals 9 damage to Gul'dan [104 HP][-9 HP] - Gul'dan [95 HP] then deals 9 damage to Knight [24 HP][-9 HP] - -Round 75 - Gul'dan [95 HP] against Knight [15 HP] - Gul'dan [95 HP] strikes and deals 9 damage to Knight [15 HP][-9 HP] - Knight [6 HP] then deals 9 damage to Gul'dan [95 HP][-9 HP] - -Round 76 - Gul'dan [86 HP] against Knight [6 HP] - Knight [6 HP] strikes and deals 9 damage to Gul'dan [86 HP][-9 HP] - Gul'dan [77 HP] then deals 6 damage to Knight [6 HP][-6 HP] - - Knight died of fatal blow from Gul'dan! - -Round 77 - Gul'dan [77 HP] against Archer [100 HP] - Archer [100 HP] strikes and deals 9 damage to Gul'dan [77 HP][-9 HP] - Gul'dan [68 HP] then deals 12 damage to Archer [100 HP][-12 HP] - -Round 78 - Gul'dan [68 HP] against Archer [88 HP] - Gul'dan [68 HP] strikes and deals 10 damage to Archer [88 HP][-10 HP] - Archer [78 HP] then deals 9 damage to Gul'dan [68 HP][-9 HP] - -Round 79 - Gul'dan [59 HP] against Archer [78 HP] - Archer [78 HP] strikes and deals 9 damage to Gul'dan [59 HP][-9 HP] - Gul'dan [50 HP] then deals 12 damage to Archer [78 HP][-12 HP] - -Round 80 - Gul'dan [50 HP] against Archer [66 HP] - Gul'dan [50 HP] strikes and deals 12 damage to Archer [66 HP][-12 HP] - Archer [54 HP] then deals 9 damage to Gul'dan [50 HP][-9 HP] - -Round 81 - Gul'dan [41 HP] against Archer [54 HP] - Gul'dan [41 HP] strikes and deals 12 damage to Archer [54 HP][-12 HP] - Archer [42 HP] then deals 9 damage to Gul'dan [41 HP][-9 HP] - -Round 82 - Gul'dan [32 HP] against Archer [42 HP] - Archer [42 HP] strikes and deals 9 damage to Gul'dan [32 HP][-9 HP] - Gul'dan [23 HP] then deals 12 damage to Archer [42 HP][-12 HP] - -Round 83 - Gul'dan [23 HP] against Archer [30 HP] - Archer [30 HP] strikes and deals 9 damage to Gul'dan [23 HP][-9 HP] - Gul'dan [14 HP] then deals 12 damage to Archer [30 HP][-12 HP] - -Round 84 - Gul'dan [14 HP] against Archer [18 HP] - Gul'dan [14 HP] strikes and deals 12 damage to Archer [18 HP][-12 HP] - Archer [6 HP] then deals 9 damage to Gul'dan [14 HP][-9 HP] - -Round 85 - Gul'dan [5 HP] against Archer [6 HP] - Gul'dan [5 HP] strikes and deals 6 damage to Archer [6 HP][-6 HP] - - Archer died of fatal blow from Gul'dan! - -Round 86 - Gul'dan [5 HP] against Footman [100 HP] - Footman [100 HP] strikes and deals 4 damage to Gul'dan [5 HP][-4 HP] - Gul'dan [1 HP] then deals 15 damage to Footman [100 HP][-15 HP] - -Round 87 - Gul'dan [1 HP] against Footman [85 HP] - Footman [85 HP] strikes and deals 1 damage to Gul'dan [1 HP][-1 HP] - - Gul'dan died of fatal blow from Footman! - -Round 88 - Spearman [100 HP] against Footman [85 HP] - Footman [85 HP] strikes and deals 3 damage to Spearman [100 HP][-3 HP] - Spearman [97 HP] then deals 11 damage to Footman [85 HP][-11 HP] - -Round 89 - Spearman [97 HP] against Footman [74 HP] - Footman [74 HP] strikes and deals 5 damage to Spearman [97 HP][-5 HP] - Spearman [92 HP] then deals 11 damage to Footman [74 HP][-11 HP] - -Round 90 - Spearman [92 HP] against Footman [63 HP] - Spearman [92 HP] strikes and deals 11 damage to Footman [63 HP][-11 HP] - Footman [52 HP] then deals 7 damage to Spearman [92 HP][-7 HP] - -Round 91 - Spearman [85 HP] against Footman [52 HP] - Spearman [85 HP] strikes and deals 11 damage to Footman [52 HP][-11 HP] - Footman [41 HP] then deals 7 damage to Spearman [85 HP][-7 HP] - -Round 92 - Spearman [78 HP] against Footman [41 HP] - Spearman [78 HP] strikes and deals 11 damage to Footman [41 HP][-11 HP] - Footman [30 HP] then deals 7 damage to Spearman [78 HP][-7 HP] - -Round 93 - Spearman [71 HP] against Footman [30 HP] - Spearman [71 HP] strikes and deals 11 damage to Footman [30 HP][-11 HP] - Footman [19 HP] then deals 7 damage to Spearman [71 HP][-7 HP] - -Round 94 - Spearman [64 HP] against Footman [19 HP] - Spearman [64 HP] strikes and deals 11 damage to Footman [19 HP][-11 HP] - Footman [8 HP] then deals 7 damage to Spearman [64 HP][-7 HP] - -Round 95 - Spearman [57 HP] against Footman [8 HP] - Footman [8 HP] strikes and deals 7 damage to Spearman [57 HP][-7 HP] - Spearman [50 HP] then deals 8 damage to Footman [8 HP][-8 HP] - - Footman died of fatal blow from Spearman! - -Round 96 - Spearman [50 HP] against Archer [100 HP] - Spearman [50 HP] strikes and deals 8 damage to Archer [100 HP][-8 HP] - Archer [92 HP] then deals 10 damage to Spearman [50 HP][-10 HP] - -Round 97 - Spearman [40 HP] against Archer [92 HP] - Spearman [40 HP] strikes and deals 10 damage to Archer [92 HP][-10 HP] - Archer [82 HP] then deals 12 damage to Spearman [40 HP][-12 HP] - -Round 98 - Spearman [28 HP] against Archer [82 HP] - Spearman [28 HP] strikes and deals 12 damage to Archer [82 HP][-12 HP] - Archer [70 HP] then deals 12 damage to Spearman [28 HP][-12 HP] - -Round 99 - Spearman [16 HP] against Archer [70 HP] - Spearman [16 HP] strikes and deals 12 damage to Archer [70 HP][-12 HP] - Archer [58 HP] then deals 12 damage to Spearman [16 HP][-12 HP] - -Round 100 - Spearman [4 HP] against Archer [58 HP] - Archer [58 HP] strikes and deals 4 damage to Spearman [4 HP][-4 HP] - - Spearman died of fatal blow from Archer! - -Round 101 - Raider [100 HP] against Archer [58 HP] - Raider [100 HP] strikes and deals 14 damage to Archer [58 HP][-14 HP] - Archer [44 HP] then deals 9 damage to Raider [100 HP][-9 HP] - -Round 102 - Raider [91 HP] against Archer [44 HP] - Archer [44 HP] strikes and deals 9 damage to Raider [91 HP][-9 HP] - Raider [82 HP] then deals 12 damage to Archer [44 HP][-12 HP] - -Round 103 - Raider [82 HP] against Archer [32 HP] - Archer [32 HP] strikes and deals 9 damage to Raider [82 HP][-9 HP] - Raider [73 HP] then deals 12 damage to Archer [32 HP][-12 HP] - -Round 104 - Raider [73 HP] against Archer [20 HP] - Raider [73 HP] strikes and deals 12 damage to Archer [20 HP][-12 HP] - Archer [8 HP] then deals 9 damage to Raider [73 HP][-9 HP] - -Round 105 - Raider [64 HP] against Archer [8 HP] - Archer [8 HP] strikes and deals 9 damage to Raider [64 HP][-9 HP] - Raider [55 HP] then deals 8 damage to Archer [8 HP][-8 HP] - - Archer died of fatal blow from Raider! - -Round 106 - Raider [55 HP] against Footman [100 HP] - Footman [100 HP] strikes and deals 4 damage to Raider [55 HP][-4 HP] - Raider [51 HP] then deals 15 damage to Footman [100 HP][-15 HP] - -Round 107 - Raider [51 HP] against Footman [85 HP] - Footman [85 HP] strikes and deals 4 damage to Raider [51 HP][-4 HP] - Raider [47 HP] then deals 11 damage to Footman [85 HP][-11 HP] - -Round 108 - Raider [47 HP] against Footman [74 HP] - Raider [47 HP] strikes and deals 11 damage to Footman [74 HP][-11 HP] - Footman [63 HP] then deals 4 damage to Raider [47 HP][-4 HP] - -Round 109 - Raider [43 HP] against Footman [63 HP] - Footman [63 HP] strikes and deals 4 damage to Raider [43 HP][-4 HP] - Raider [39 HP] then deals 11 damage to Footman [63 HP][-11 HP] - -Round 110 - Raider [39 HP] against Footman [52 HP] - Footman [52 HP] strikes and deals 4 damage to Raider [39 HP][-4 HP] - Raider [35 HP] then deals 11 damage to Footman [52 HP][-11 HP] - -Round 111 - Raider [35 HP] against Footman [41 HP] - Footman [41 HP] strikes and deals 4 damage to Raider [35 HP][-4 HP] - Raider [31 HP] then deals 11 damage to Footman [41 HP][-11 HP] - -Round 112 - Raider [31 HP] against Footman [30 HP] - Raider [31 HP] strikes and deals 11 damage to Footman [30 HP][-11 HP] - Footman [19 HP] then deals 4 damage to Raider [31 HP][-4 HP] - -Round 113 - Raider [27 HP] against Footman [19 HP] - Raider [27 HP] strikes and deals 11 damage to Footman [19 HP][-11 HP] - Footman [8 HP] then deals 4 damage to Raider [27 HP][-4 HP] - -Round 114 - Raider [23 HP] against Footman [8 HP] - Raider [23 HP] strikes and deals 8 damage to Footman [8 HP][-8 HP] - - Footman died of fatal blow from Raider! - - The Orcish Horde wins the battle! diff --git a/src/main/resources/icon.png b/src/main/resources/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..9a39746f55f3b5d73d5064b98c1b0c0926e8da22 Binary files /dev/null and b/src/main/resources/icon.png differ diff --git a/src/main/resources/war_games_view.fxml b/src/main/resources/war_games_view.fxml new file mode 100644 index 0000000000000000000000000000000000000000..593a428628124a285c6aae19474d1d2aa9b4a133 --- /dev/null +++ b/src/main/resources/war_games_view.fxml @@ -0,0 +1,309 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<?import javafx.geometry.Insets?> +<?import javafx.scene.control.Button?> +<?import javafx.scene.control.Label?> +<?import javafx.scene.control.ListView?> +<?import javafx.scene.control.TextArea?> +<?import javafx.scene.control.TextField?> +<?import javafx.scene.layout.AnchorPane?> +<?import javafx.scene.layout.ColumnConstraints?> +<?import javafx.scene.layout.GridPane?> +<?import javafx.scene.layout.HBox?> +<?import javafx.scene.layout.RowConstraints?> +<?import javafx.scene.layout.StackPane?> +<?import javafx.scene.layout.VBox?> +<?import javafx.scene.shape.Rectangle?> +<?import javafx.scene.text.Font?> +<?import javafx.scene.text.Text?> + +<AnchorPane minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="1000.0" style="-fx-background-color: A2C4C9;" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="edu.ntnu.idatt2001.runarin.wargames.frontend.controllers.WarGamesController"> + <children> + <VBox minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="300.0"> + <children> + <Label fx:id="nameArmyOne" text="[Initialise army from file]"> + <VBox.margin> + <Insets left="20.0" right="10.0" top="20.0" /> + </VBox.margin> + <font> + <Font name="System Bold" size="18.0" /> + </font> + </Label> + <Label text="Army overview:"> + <VBox.margin> + <Insets bottom="5.0" left="15.0" right="10.0" top="10.0" /> + </VBox.margin> + <font> + <Font name="System Bold" size="14.0" /> + </font> + </Label> + <StackPane prefHeight="100.0" prefWidth="200.0"> + <children> + <Rectangle arcHeight="5.0" arcWidth="5.0" fill="WHITE" height="100.0" stroke="BLACK" strokeType="INSIDE" width="280.0" /> + <StackPane> + <children> + <GridPane prefHeight="63.0" prefWidth="280.0"> + <columnConstraints> + <ColumnConstraints hgrow="SOMETIMES" maxWidth="160.0" minWidth="10.0" prefWidth="160.0" /> + <ColumnConstraints hgrow="SOMETIMES" maxWidth="135.0" minWidth="10.0" prefWidth="120.0" /> + </columnConstraints> + <rowConstraints> + <RowConstraints maxHeight="65.0" minHeight="10.0" prefHeight="32.0" vgrow="SOMETIMES" /> + <RowConstraints maxHeight="46.0" minHeight="9.0" prefHeight="21.0" vgrow="SOMETIMES" /> + <RowConstraints maxHeight="59.0" minHeight="10.0" prefHeight="21.0" vgrow="SOMETIMES" /> + <RowConstraints maxHeight="59.0" minHeight="6.0" prefHeight="7.0" vgrow="SOMETIMES" /> + </rowConstraints> + <children> + <Label fx:id="armyOneNumberOfUnits" text="0" GridPane.halignment="RIGHT"> + <GridPane.margin> + <Insets left="10.0" right="10.0" /> + </GridPane.margin> + </Label> + <Label fx:id="armyOneNumberOfCommanders" text="0" GridPane.halignment="RIGHT" GridPane.rowIndex="1"> + <GridPane.margin> + <Insets left="10.0" right="30.0" /> + </GridPane.margin> + </Label> + <Label fx:id="armyOneNumberOfCavalry" text="0" GridPane.halignment="RIGHT" GridPane.rowIndex="2"> + <GridPane.margin> + <Insets left="10.0" right="30.0" /> + </GridPane.margin> + </Label> + <Label fx:id="armyOneNumberOfInfantry" text="0" GridPane.columnIndex="1" GridPane.halignment="RIGHT" GridPane.rowIndex="1"> + <GridPane.margin> + <Insets right="30.0" /> + </GridPane.margin></Label> + <Label fx:id="armyOneNumberOfRanged" text="0" GridPane.columnIndex="1" GridPane.halignment="RIGHT" GridPane.rowIndex="2"> + <GridPane.margin> + <Insets right="30.0" /> + </GridPane.margin></Label> + <Text strokeType="OUTSIDE" strokeWidth="0.0" text="Total number of units:"> + <GridPane.margin> + <Insets left="10.0" /> + </GridPane.margin> + </Text> + <Text strokeType="OUTSIDE" strokeWidth="0.0" text="Commander unit:" GridPane.rowIndex="1"> + <GridPane.margin> + <Insets left="10.0" /> + </GridPane.margin> + </Text> + <Text strokeType="OUTSIDE" strokeWidth="0.0" text="Cavalry units:" GridPane.rowIndex="2"> + <GridPane.margin> + <Insets left="10.0" /> + </GridPane.margin> + </Text> + <Text strokeType="OUTSIDE" strokeWidth="0.0" text="Infantry units:" GridPane.columnIndex="1" GridPane.rowIndex="1" /> + <Text strokeType="OUTSIDE" strokeWidth="0.0" text="Ranged units:" GridPane.columnIndex="1" GridPane.rowIndex="2" /> + </children> + <StackPane.margin> + <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> + </StackPane.margin> + </GridPane> + </children> + </StackPane> + </children> + </StackPane> + <ListView fx:id="listViewArmyOneUnits" focusTraversable="false" minHeight="200.0" minWidth="-Infinity" prefWidth="200.0"> + <VBox.margin> + <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> + </VBox.margin> + </ListView> + <HBox> + <children> + <Button mnemonicParsing="false" onAction="#btnArmyOneSelectFile" text="Select army file ..."> + <HBox.margin> + <Insets left="10.0" right="10.0" /> + </HBox.margin> + </Button> + <TextField fx:id="filePathArmyOne" prefHeight="25.0" prefWidth="150.0" text="path/to/army/file.csv" /> + </children> + <VBox.margin> + <Insets bottom="10.0" /> + </VBox.margin> + </HBox> + <Button mnemonicParsing="false" onAction="#btnInitialiseArmyOne" text="Initialise army from file"> + <VBox.margin> + <Insets bottom="20.0" left="10.0" right="10.0" /> + </VBox.margin> + </Button> + </children> + </VBox> + <VBox layoutX="300.0" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="400.0"> + <children> + <Label text="Choose terrain and start simulation"> + <VBox.margin> + <Insets bottom="10.0" left="90.0" right="90.0" top="40.0" /> + </VBox.margin> + <font> + <Font size="14.0" /> + </font> + </Label> + <Button fx:id="idBtnStartBattle" contentDisplay="TOP" disable="true" mnemonicParsing="false" onAction="#btnStartBattle" prefHeight="30.0" prefWidth="120.0" text="Start battle!"> + <font> + <Font size="16.0" /> + </font> + <VBox.margin> + <Insets bottom="20.0" left="140.0" right="140.0" top="10.0" /> + </VBox.margin> + </Button> + <HBox maxHeight="-Infinity" prefHeight="25.0" prefWidth="200.0"> + <children> + <Button fx:id="idBtnForest" mnemonicParsing="false" onAction="#btnForest" prefHeight="25.0" prefWidth="80.0" text="Forest"> + <HBox.margin> + <Insets left="60.0" right="10.0" /> + </HBox.margin> + <font> + <Font size="14.0" /> + </font> + </Button> + <Button fx:id="idBtnHill" mnemonicParsing="false" onAction="#btnHill" prefHeight="25.0" prefWidth="80.0" text="Hill"> + <HBox.margin> + <Insets left="10.0" right="10.0" /> + </HBox.margin> + <font> + <Font size="14.0" /> + </font> + </Button> + <Button fx:id="idBtnPlains" mnemonicParsing="false" onAction="#btnPlains" prefHeight="25.0" prefWidth="80.0" text="Plains"> + <HBox.margin> + <Insets left="10.0" right="60.0" /> + </HBox.margin> + <font> + <Font size="14.0" /> + </font> + </Button> + </children> + <VBox.margin> + <Insets /> + </VBox.margin> + </HBox> + <Label text="Battle log:"> + <VBox.margin> + <Insets left="5.0" top="20.0" /> + </VBox.margin> + <font> + <Font name="System Bold" size="14.0" /> + </font> + </Label> + <TextArea fx:id="textFieldBattleLog" editable="false" focusTraversable="false" minHeight="280.0" minWidth="300.0" prefHeight="350.0" promptText="Add units to respective armies and choose terrain before starting simulation."> + <VBox.margin> + <Insets top="10.0" /> + </VBox.margin> + </TextArea> + </children> + </VBox> + <VBox layoutX="700.0" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="300.0"> + <children> + <Label fx:id="nameArmyTwo" text="[Initialise army from file]"> + <VBox.margin> + <Insets left="20.0" right="10.0" top="20.0" /> + </VBox.margin> + <font> + <Font name="System Bold" size="18.0" /> + </font> + </Label> + <Label text="Army overview:"> + <VBox.margin> + <Insets bottom="5.0" left="15.0" right="10.0" top="10.0" /> + </VBox.margin> + <font> + <Font name="System Bold" size="14.0" /> + </font> + </Label> + <StackPane prefHeight="100.0" prefWidth="200.0"> + <children> + <Rectangle arcHeight="5.0" arcWidth="5.0" fill="WHITE" height="100.0" stroke="BLACK" strokeType="INSIDE" width="280.0" /> + <StackPane> + <children> + <GridPane prefHeight="63.0" prefWidth="280.0"> + <columnConstraints> + <ColumnConstraints hgrow="SOMETIMES" maxWidth="160.0" minWidth="10.0" prefWidth="160.0" /> + <ColumnConstraints hgrow="SOMETIMES" maxWidth="135.0" minWidth="10.0" prefWidth="120.0" /> + </columnConstraints> + <rowConstraints> + <RowConstraints maxHeight="65.0" minHeight="10.0" prefHeight="32.0" vgrow="SOMETIMES" /> + <RowConstraints maxHeight="46.0" minHeight="9.0" prefHeight="21.0" vgrow="SOMETIMES" /> + <RowConstraints maxHeight="59.0" minHeight="10.0" prefHeight="21.0" vgrow="SOMETIMES" /> + <RowConstraints maxHeight="59.0" minHeight="6.0" prefHeight="7.0" vgrow="SOMETIMES" /> + </rowConstraints> + <children> + <Label fx:id="armyTwoNumberOfUnits" text="0" GridPane.halignment="RIGHT"> + <GridPane.margin> + <Insets left="10.0" right="10.0" /> + </GridPane.margin> + </Label> + <Label fx:id="armyTwoNumberOfCommanders" text="0" GridPane.halignment="RIGHT" GridPane.rowIndex="1"> + <GridPane.margin> + <Insets left="10.0" right="30.0" /> + </GridPane.margin> + </Label> + <Label fx:id="armyTwoNumberOfCavalry" text="0" GridPane.halignment="RIGHT" GridPane.rowIndex="2"> + <GridPane.margin> + <Insets left="10.0" right="30.0" /> + </GridPane.margin> + </Label> + <Label fx:id="armyTwoNumberOfInfantry" text="0" GridPane.columnIndex="1" GridPane.halignment="RIGHT" GridPane.rowIndex="1"> + <GridPane.margin> + <Insets right="30.0" /> + </GridPane.margin></Label> + <Label fx:id="armyTwoNumberOfRanged" text="0" GridPane.columnIndex="1" GridPane.halignment="RIGHT" GridPane.rowIndex="2"> + <GridPane.margin> + <Insets right="30.0" /> + </GridPane.margin></Label> + <Text strokeType="OUTSIDE" strokeWidth="0.0" text="Total number of units:"> + <GridPane.margin> + <Insets left="10.0" /> + </GridPane.margin> + </Text> + <Text strokeType="OUTSIDE" strokeWidth="0.0" text="Commander unit:" GridPane.rowIndex="1"> + <GridPane.margin> + <Insets left="10.0" /> + </GridPane.margin> + </Text> + <Text strokeType="OUTSIDE" strokeWidth="0.0" text="Cavalry units:" GridPane.rowIndex="2"> + <GridPane.margin> + <Insets left="10.0" /> + </GridPane.margin> + </Text> + <Text strokeType="OUTSIDE" strokeWidth="0.0" text="Infantry units:" GridPane.columnIndex="1" GridPane.rowIndex="1" /> + <Text strokeType="OUTSIDE" strokeWidth="0.0" text="Ranged units:" GridPane.columnIndex="1" GridPane.rowIndex="2" /> + </children> + <StackPane.margin> + <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> + </StackPane.margin> + </GridPane> + </children> + </StackPane> + </children> + </StackPane> + <ListView fx:id="listViewArmyTwoUnits" focusTraversable="false" minHeight="200.0" minWidth="-Infinity" prefWidth="200.0"> + <VBox.margin> + <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> + </VBox.margin> + </ListView> + <HBox> + <children> + <Button mnemonicParsing="false" onAction="#btnArmyTwoSelectFile" text="Select army file ..."> + <HBox.margin> + <Insets left="10.0" right="10.0" /> + </HBox.margin> + </Button> + <TextField fx:id="filePathArmyTwo" prefHeight="25.0" prefWidth="150.0" text="path/to/army/file.csv"> + <HBox.margin> + <Insets /> + </HBox.margin> + </TextField> + </children> + <VBox.margin> + <Insets bottom="10.0" /> + </VBox.margin> + </HBox> + <Button mnemonicParsing="false" onAction="#btnInitialiseArmyTwo" text="Initialise army from file"> + <VBox.margin> + <Insets bottom="20.0" left="10.0" right="10.0" /> + </VBox.margin> + </Button> + </children> + </VBox> + </children> +</AnchorPane> diff --git a/src/test/java/edu/ntnu/idatt2001/runarin/wargames/backend/armies/ArmyTest.java b/src/test/java/edu/ntnu/idatt2001/runarin/wargames/backend/armies/ArmyTest.java index 1119eb5f741bf933bf0a00d7cedd55e5f9694ceb..3856aa85d110bc059e2a5fef637ca382f2a5d16e 100644 --- a/src/test/java/edu/ntnu/idatt2001/runarin/wargames/backend/armies/ArmyTest.java +++ b/src/test/java/edu/ntnu/idatt2001/runarin/wargames/backend/armies/ArmyTest.java @@ -6,6 +6,7 @@ import java.io.IOException; import java.util.ArrayList; import edu.ntnu.idatt2001.runarin.wargames.backend.exceptions.CorruptedFileException; +import edu.ntnu.idatt2001.runarin.wargames.backend.filehandling.FileHandler; import edu.ntnu.idatt2001.runarin.wargames.backend.units.Unit; import edu.ntnu.idatt2001.runarin.wargames.backend.units.specialised.CavalryUnit; import edu.ntnu.idatt2001.runarin.wargames.backend.units.specialised.CommanderUnit; @@ -99,6 +100,21 @@ public class ArmyTest { } } + @Test + public void readArmyNameFromFile() { + /* + This test asserts that the army name is returned from a file. + */ + try { + String file = "src/main/resources/test-files/TestArmy-valid.csv"; + String armyName = FileHandler.readArmyNameFromFile(file); + assertEquals("Test Army", armyName); + } catch (IOException e) { + assertNull(e.getMessage()); + } + + } + @Test public void readContentOfFileAndAddItsContentOfUnitsToArmy() { /* @@ -114,25 +130,25 @@ public class ArmyTest { assertEquals(19, army.getAllUnits().size()); assertEquals(""" [ - | Grunt | HP = 100 | Attack power = 15 | Armor points = 10 |,\s - | Grunt | HP = 100 | Attack power = 15 | Armor points = 10 |,\s - | Grunt | HP = 100 | Attack power = 15 | Armor points = 10 |,\s - | Spearman | HP = 100 | Attack power = 15 | Armor points = 8 |,\s - | Spearman | HP = 100 | Attack power = 15 | Armor points = 8 |,\s - | Spearman | HP = 100 | Attack power = 15 | Armor points = 8 |,\s - | Raider | HP = 100 | Attack power = 20 | Armor points = 12 |,\s - | Raider | HP = 100 | Attack power = 20 | Armor points = 12 |,\s - | Raider | HP = 100 | Attack power = 20 | Armor points = 12 |,\s - | Gul'dan | HP = 180 | Attack power = 25 | Armor points = 15 |,\s - | Raider | HP = 100 | Attack power = 20 | Armor points = 12 |,\s - | Raider | HP = 100 | Attack power = 20 | Armor points = 12 |,\s - | Raider | HP = 100 | Attack power = 20 | Armor points = 12 |,\s - | Spearman | HP = 100 | Attack power = 15 | Armor points = 8 |,\s - | Spearman | HP = 100 | Attack power = 15 | Armor points = 8 |,\s - | Spearman | HP = 100 | Attack power = 15 | Armor points = 8 |,\s - | Grunt | HP = 100 | Attack power = 15 | Armor points = 10 |,\s - | Grunt | HP = 100 | Attack power = 15 | Armor points = 10 |,\s - | Grunt | HP = 100 | Attack power = 15 | Armor points = 10 |]""", + Grunt [100 hp] InfantryUnit,\s + Grunt [100 hp] InfantryUnit,\s + Grunt [100 hp] InfantryUnit,\s + Spearman [100 hp] RangedUnit,\s + Spearman [100 hp] RangedUnit,\s + Spearman [100 hp] RangedUnit,\s + Raider [100 hp] CavalryUnit,\s + Raider [100 hp] CavalryUnit,\s + Raider [100 hp] CavalryUnit,\s + Gul'dan [180 hp] CommanderUnit,\s + Raider [100 hp] CavalryUnit,\s + Raider [100 hp] CavalryUnit,\s + Raider [100 hp] CavalryUnit,\s + Spearman [100 hp] RangedUnit,\s + Spearman [100 hp] RangedUnit,\s + Spearman [100 hp] RangedUnit,\s + Grunt [100 hp] InfantryUnit,\s + Grunt [100 hp] InfantryUnit,\s + Grunt [100 hp] InfantryUnit]""", army.getAllUnits().toString()); } catch (IOException e) { @@ -265,9 +281,9 @@ public class ArmyTest { assertEquals(3, army.getInfantryUnits().size()); assertEquals(""" [ - | Grunt | HP = 100 | Attack power = 15 | Armor points = 10 |,\s - | Grunt | HP = 100 | Attack power = 15 | Armor points = 10 |,\s - | Grunt | HP = 100 | Attack power = 15 | Armor points = 10 |]""", + Grunt [100 hp] InfantryUnit,\s + Grunt [100 hp] InfantryUnit,\s + Grunt [100 hp] InfantryUnit]""", army.getInfantryUnits().toString()); } @@ -279,9 +295,9 @@ public class ArmyTest { assertEquals(3, army.getRangedUnits().size()); assertEquals(""" [ - | Spearman | HP = 100 | Attack power = 15 | Armor points = 8 |,\s - | Spearman | HP = 100 | Attack power = 15 | Armor points = 8 |,\s - | Spearman | HP = 100 | Attack power = 15 | Armor points = 8 |]""", + Spearman [100 hp] RangedUnit,\s + Spearman [100 hp] RangedUnit,\s + Spearman [100 hp] RangedUnit]""", army.getRangedUnits().toString()); } @@ -293,9 +309,9 @@ public class ArmyTest { assertEquals(3, army.getCavalryUnits().size()); assertEquals(""" [ - | Raider | HP = 100 | Attack power = 20 | Armor points = 12 |,\s - | Raider | HP = 100 | Attack power = 20 | Armor points = 12 |,\s - | Raider | HP = 100 | Attack power = 20 | Armor points = 12 |]""", + Raider [100 hp] CavalryUnit,\s + Raider [100 hp] CavalryUnit,\s + Raider [100 hp] CavalryUnit]""", army.getCavalryUnits().toString()); } @@ -305,7 +321,7 @@ public class ArmyTest { Asserts that the filtered units list only contains the specified instance of commander units. */ assertEquals(1, army.getCommanderUnits().size()); - assertEquals("[\n| Gul'dan | HP = 180 | Attack power = 25 | Armor points = 15 |]", + assertEquals("[\nGul'dan [180 hp] CommanderUnit]", army.getCommanderUnits().toString()); } } @@ -434,17 +450,17 @@ public class ArmyTest { horde.addUnit(new InfantryUnit("Grunt", 100)); horde.addUnit(new RangedUnit("Spearman", 100)); horde.addUnit(new CavalryUnit("Raider", 100)); - horde.addUnit(new CommanderUnit("Gul'dan", 100)); + horde.addUnit(new CommanderUnit("Gul'dan", 180)); ArrayList<Unit> testArrayList = horde.getAllUnits(); - assertEquals("\n| Grunt | HP = 100 | Attack power = 15 | Armor points = 10 |", + assertEquals("\nGrunt [100 hp] InfantryUnit", testArrayList.get(0).toString()); - assertEquals("\n| Spearman | HP = 100 | Attack power = 15 | Armor points = 8 |", + assertEquals("\nSpearman [100 hp] RangedUnit", testArrayList.get(1).toString()); - assertEquals("\n| Raider | HP = 100 | Attack power = 20 | Armor points = 12 |", + assertEquals("\nRaider [100 hp] CavalryUnit", testArrayList.get(2).toString()); - assertEquals("\n| Gul'dan | HP = 100 | Attack power = 25 | Armor points = 15 |", + assertEquals("\nGul'dan [180 hp] CommanderUnit", testArrayList.get(3).toString()); } diff --git a/src/test/java/edu/ntnu/idatt2001/runarin/wargames/backend/armies/BattleTest.java b/src/test/java/edu/ntnu/idatt2001/runarin/wargames/backend/armies/BattleTest.java index f10cad92e96b5fe25d5b016efd239165b5774b55..71fcd522c48999fa7a00055d09344160ed9d847f 100644 --- a/src/test/java/edu/ntnu/idatt2001/runarin/wargames/backend/armies/BattleTest.java +++ b/src/test/java/edu/ntnu/idatt2001/runarin/wargames/backend/armies/BattleTest.java @@ -1,5 +1,6 @@ package edu.ntnu.idatt2001.runarin.wargames.backend.armies; +import edu.ntnu.idatt2001.runarin.wargames.backend.exceptions.ArmyEmptyOfUnitsException; import edu.ntnu.idatt2001.runarin.wargames.backend.units.TerrainType; import edu.ntnu.idatt2001.runarin.wargames.backend.units.specialised.CavalryUnit; import edu.ntnu.idatt2001.runarin.wargames.backend.units.specialised.CommanderUnit; @@ -7,33 +8,64 @@ import edu.ntnu.idatt2001.runarin.wargames.backend.units.specialised.InfantryUni import edu.ntnu.idatt2001.runarin.wargames.backend.units.specialised.RangedUnit; import org.junit.jupiter.api.Test; +import java.io.IOException; + import static org.junit.jupiter.api.Assertions.*; public class BattleTest { @Test public void constructorThrowsIllegalArgumentExceptionWhenAnArmyIsNull() { + /* + Test asserts that a battling army cannot be null. + */ try { Army horde = new Army("The Horde"); Army alliance = new Army("The Alliance"); - Battle grandWar = new Battle(null, alliance); + Battle battle = new Battle(null, alliance); fail(); - } catch (IllegalArgumentException e) { - assertEquals("There must be two armies as input.", e.getMessage()); + } catch (IOException e) { + assertEquals("Two armies must be initialised to run simulation.", e.getMessage()); } } @Test public void constructorThrowsIllegalArgumentExceptionWhenArmyIsToBattleItself() { + /* + Test asserts that an army cannot be set to fight itself and throws exception. + */ try { Army alliance = new Army("The Alliance"); - Battle grandWar = new Battle(alliance, alliance); + Battle battle = new Battle(alliance, alliance); fail(); - } catch (IllegalArgumentException e) { + } catch (IllegalArgumentException | IOException e) { assertEquals("An army cannot battle itself.", e.getMessage()); } } + @Test + public void simulationMethodThrowsExceptionWhenInitialisedWithAnArmyWithNoUnits() { + /* + Test asserts that if a simulation is initialised with an army + that has no units, an ArmyEmptyOfUnitsException is thrown. + */ + try { + Army horde = new Army("The Horde"); + horde.addUnit(new InfantryUnit("Grunt", 100)); + Army alliance = new Army("The Alliance"); + + Battle battle = new Battle(horde, alliance); + battle.simulate(TerrainType.FOREST); + + fail(); + } catch (ArmyEmptyOfUnitsException e) { + assertEquals("The Alliance has no units left to fight in the simulation. " + + "Press the \"Initialise army from file\"-button to rebuild the army.", e.getMessage()); + } catch (IOException e) { + assertNull(e.getMessage()); + } + } + @Test public void toStringTestToCheckTotalToStringWithNameAndNumberOfUnitsAfterAddingUnitsToBothArmies() { /* @@ -42,7 +74,12 @@ public class BattleTest { Army horde = new Army("The Horde"); Army alliance = new Army("The Alliance"); - Battle grandWar = new Battle(horde, alliance); + Battle battle = null; + try { + battle = new Battle(horde, alliance); + } catch (IOException e) { + assertNull(e.getMessage()); + } // Adds x number of grunt units to the horde army. for (int i = 0; i < 3; i++) { @@ -52,7 +89,8 @@ public class BattleTest { for (int i = 0; i < 3; i++) { alliance.addUnit(new InfantryUnit("Footman", 100)); } - assertEquals("Battle between The Horde [3 unit(s)] and The Alliance [3 unit(s)]", grandWar.toString()); + assertNotNull(battle); + assertEquals("Battle between The Horde [3 unit(s)] and The Alliance [3 unit(s)]", battle.toString()); } @Test @@ -67,9 +105,12 @@ public class BattleTest { horde.addUnit(new CommanderUnit("Gul'dan", 9000)); alliance.addUnit(new InfantryUnit("Footman", 100)); - Battle grandWar = new Battle(horde, alliance); - - assertEquals("The Horde [1 unit(s)]", grandWar.simulate(TerrainType.HILL).toString()); + try { + Battle battle = new Battle(horde, alliance); + assertEquals("The Horde [1 unit(s)]", battle.simulate(TerrainType.HILL).toString()); + } catch (IOException e) { + assertNull(e.getMessage()); + } } @Test @@ -86,6 +127,7 @@ public class BattleTest { Army horde = new Army("The Orcish Horde"); Army alliance = new Army("The Human Army"); + // Adds x number of grunt units to the horde army. for (int i = 0; i < 3; i++) { horde.addUnit(new InfantryUnit("Grunt", 100)); @@ -111,13 +153,18 @@ public class BattleTest { alliance.addUnit(new CavalryUnit("Knight", 100)); } // Adds commanders to the respective armies. - horde.addUnit(new CavalryUnit("Gul'dan", 180)); - alliance.addUnit(new CavalryUnit("Mountain King", 180)); + horde.addUnit(new CommanderUnit("Gul'dan", 180)); + alliance.addUnit(new CommanderUnit("Mountain King", 180)); - Battle battle = new Battle(horde, alliance); - - Army winningArmy = battle.simulate(TerrainType.HILL); + Army winningArmy = null; + try { + Battle battle = new Battle(horde, alliance); + winningArmy = battle.simulate(TerrainType.HILL); + } catch (IOException e) { + assertNull(e.getMessage()); + } + assertNotNull(winningArmy); if (!winningArmy.equals(alliance)) assertFalse(alliance.hasUnits()); else {assertFalse(horde.hasUnits());} } diff --git a/src/test/java/edu/ntnu/idatt2001/runarin/wargames/backend/units/UnitFactoryTest.java b/src/test/java/edu/ntnu/idatt2001/runarin/wargames/backend/units/UnitFactoryTest.java index 763fa32ff4512ed18d298e15fb521e5c3634e1c3..f17b9a283b7ca697e4a8068ccaaa11395f97e9eb 100644 --- a/src/test/java/edu/ntnu/idatt2001/runarin/wargames/backend/units/UnitFactoryTest.java +++ b/src/test/java/edu/ntnu/idatt2001/runarin/wargames/backend/units/UnitFactoryTest.java @@ -16,7 +16,7 @@ public class UnitFactoryTest { */ Unit unit = UnitFactory.getUnit(UnitType.INFANTRY, "Grunt", 100); - assertEquals("\n| Grunt | HP = 100 | Attack power = 15 | Armor points = 10 |", unit.toString()); + assertEquals("\nGrunt [100 hp] InfantryUnit", unit.toString()); } @Test @@ -31,7 +31,7 @@ public class UnitFactoryTest { assertEquals(4, units.size()); for (Unit unit : units) { - assertEquals("\n| Archer | HP = 100 | Attack power = 15 | Armor points = 8 |", + assertEquals("\nArcher [100 hp] RangedUnit", unit.toString()); } } diff --git a/src/test/java/edu/ntnu/idatt2001/runarin/wargames/backend/units/specialised/CavalryUnitTest.java b/src/test/java/edu/ntnu/idatt2001/runarin/wargames/backend/units/specialised/CavalryUnitTest.java index f2aae70abeb3f14a527938c25cf49d5e9b162183..e3b7b1ef9de721a8a41ba2351d6ef7d85b241409 100644 --- a/src/test/java/edu/ntnu/idatt2001/runarin/wargames/backend/units/specialised/CavalryUnitTest.java +++ b/src/test/java/edu/ntnu/idatt2001/runarin/wargames/backend/units/specialised/CavalryUnitTest.java @@ -13,7 +13,7 @@ public class CavalryUnitTest { Instantiate a unit to check its toString. */ CavalryUnit testUnit = new CavalryUnit("Knight", 100); - assertEquals(testUnit.toString(), "\n| Knight | HP = 100 | Attack power = 20 | Armor points = 12 |"); + assertEquals(testUnit.toString(), "\nKnight [100 hp] CavalryUnit"); } @Test diff --git a/src/test/java/edu/ntnu/idatt2001/runarin/wargames/backend/units/specialised/CommanderUnitTest.java b/src/test/java/edu/ntnu/idatt2001/runarin/wargames/backend/units/specialised/CommanderUnitTest.java index e0198973b3cf447db7b2f29d87aa093d17bb56f5..04a4be5ddaa2c87494497595e1239705d45f0460 100644 --- a/src/test/java/edu/ntnu/idatt2001/runarin/wargames/backend/units/specialised/CommanderUnitTest.java +++ b/src/test/java/edu/ntnu/idatt2001/runarin/wargames/backend/units/specialised/CommanderUnitTest.java @@ -14,7 +14,7 @@ public class CommanderUnitTest { Instantiate a unit to check its toString. */ CommanderUnit testUnit = new CommanderUnit("Mountain King", 180); - assertEquals(testUnit.toString(), "\n| Mountain King | HP = 180 | Attack power = 25 | Armor points = 15 |"); + assertEquals(testUnit.toString(), "\nMountain King [180 hp] CommanderUnit"); } @Test diff --git a/src/test/java/edu/ntnu/idatt2001/runarin/wargames/backend/units/specialised/InfantryUnitTest.java b/src/test/java/edu/ntnu/idatt2001/runarin/wargames/backend/units/specialised/InfantryUnitTest.java index a045d41d686c1d6c7e6c33ef81ff9b209d3c8f4a..ab2734c790c88ec2938ffbc53266de6149295ccb 100644 --- a/src/test/java/edu/ntnu/idatt2001/runarin/wargames/backend/units/specialised/InfantryUnitTest.java +++ b/src/test/java/edu/ntnu/idatt2001/runarin/wargames/backend/units/specialised/InfantryUnitTest.java @@ -14,7 +14,7 @@ public class InfantryUnitTest { Instantiate a unit to check its toString. */ InfantryUnit testUnit = new InfantryUnit("Footman", 100); - assertEquals(testUnit.toString(), "\n| Footman | HP = 100 | Attack power = 15 | Armor points = 10 |"); + assertEquals(testUnit.toString(), "\nFootman [100 hp] InfantryUnit"); } @Test diff --git a/src/test/java/edu/ntnu/idatt2001/runarin/wargames/backend/units/specialised/RangedUnitTest.java b/src/test/java/edu/ntnu/idatt2001/runarin/wargames/backend/units/specialised/RangedUnitTest.java index 06c4e13947979157ef042369567c18d3773b2f37..e1ed4cad306de9ac92cbe12b14b64a9d7e7d13f6 100644 --- a/src/test/java/edu/ntnu/idatt2001/runarin/wargames/backend/units/specialised/RangedUnitTest.java +++ b/src/test/java/edu/ntnu/idatt2001/runarin/wargames/backend/units/specialised/RangedUnitTest.java @@ -13,7 +13,7 @@ public class RangedUnitTest { Instantiate a unit to check its toString. */ RangedUnit testUnit = new RangedUnit("Archer", 100); - assertEquals(testUnit.toString(), "\n| Archer | HP = 100 | Attack power = 15 | Armor points = 8 |"); + assertEquals(testUnit.toString(), "\nArcher [100 hp] RangedUnit"); } @Test