diff --git a/src/main/java/edu/ntnu/idatt2001/carljgu/battle/Battle.java b/src/main/java/edu/ntnu/idatt2001/carljgu/battle/Battle.java index 03d5a0ac2b38a960ebed93fac16a054d230648d1..2854d96b04eb0976cf3233c31b94796c910b0e3e 100644 --- a/src/main/java/edu/ntnu/idatt2001/carljgu/battle/Battle.java +++ b/src/main/java/edu/ntnu/idatt2001/carljgu/battle/Battle.java @@ -11,7 +11,7 @@ import java.util.Random; * Class Battle that simulates a battle between two armies. * * @author Carl Gützkow - * @version 1.2 13.02.2022 + * @version 1.3 30.04.2022 */ public class Battle { @@ -34,13 +34,16 @@ public class Battle { * * @param armyOne Army - the first army * @param armyTwo Army - the second army - * @throws IllegalArgumentException thrown if one of the armies are empty. + * @param terrain Terrain - on what terrain the battle is fought on. + * @throws IllegalArgumentException thrown if one of the armies are empty, + * if armies are equal or if terrain is not defined * @throws NullPointerException thrown if one of the armies are null object */ public Battle(Army armyOne, Army armyTwo, Terrain terrain) throws IllegalArgumentException { if (armyOne == null || armyTwo == null) throw new NullPointerException("Army is not defined"); if (!armyOne.hasUnits() || !armyTwo.hasUnits()) throw new IllegalArgumentException("Army can not be empty"); if (Objects.equals(armyOne, armyTwo)) throw new IllegalArgumentException("Armies can not be the same"); + if (terrain == null) throw new IllegalArgumentException("Terrain is not defined"); this.armyOne = armyOne; this.armyTwo = armyTwo; this.terrain = terrain; @@ -70,9 +73,9 @@ public class Battle { /** * Gets the terrain where - * the attack occurs. + * the battle occurs. * - * @return terrain - Terrain - the specified terrain. + * @return terrain - Terrain - on what terrain the battle is fought on. */ public Terrain getTerrain() { return terrain; diff --git a/src/main/java/edu/ntnu/idatt2001/carljgu/client/App.java b/src/main/java/edu/ntnu/idatt2001/carljgu/client/App.java index 5309aaa4791f8fa2d1a4029efdb1491d5bee35ed..9f43d4b31315a295d848f67ced40a128e659336a 100644 --- a/src/main/java/edu/ntnu/idatt2001/carljgu/client/App.java +++ b/src/main/java/edu/ntnu/idatt2001/carljgu/client/App.java @@ -31,7 +31,8 @@ public class App extends Application { Scene scene = null; try { FXMLLoader fxmlLoader = new FXMLLoader(App.class.getClassLoader().getResource("wargames.fxml")); - scene = new Scene(fxmlLoader.load(), 1280, 720); + scene = new Scene(fxmlLoader.load(), 1300, 740); + scene.getStylesheets().add("stylesheet.css"); } catch (IOException | IllegalStateException e) { System.out.println(e.getMessage()); } diff --git a/src/main/java/edu/ntnu/idatt2001/carljgu/client/BattleController.java b/src/main/java/edu/ntnu/idatt2001/carljgu/client/BattleController.java index 4a80f417e4458d3ec594d5ed7210e2edce39c4b3..41e2fbd00beaad183a3c23a4462671134ba07777 100644 --- a/src/main/java/edu/ntnu/idatt2001/carljgu/client/BattleController.java +++ b/src/main/java/edu/ntnu/idatt2001/carljgu/client/BattleController.java @@ -16,6 +16,8 @@ import java.util.Optional; import java.util.ResourceBundle; import javafx.fxml.Initializable; +import javafx.scene.control.Button; +import javafx.scene.control.ChoiceBox; import javafx.fxml.FXML; import javafx.scene.control.ButtonType; import javafx.scene.control.ListView; @@ -26,12 +28,20 @@ import static javafx.scene.control.Alert.AlertType.*; /** * A controller class which * handles events in the fxml file. + * This includes requesting to import + * armies and simulate the battle * - * @version 1.5 13.04.2022 + * @version 1.6 30.04.2022 * @author Carl Gützkow */ public class BattleController implements Initializable { + @FXML + private ChoiceBox<Terrain> terrainChoiceBox = new ChoiceBox<>(); + + @FXML + private Button resetArmiesButton, resetAndBattleButton; + @FXML private Text armyOneImportPath, armyOneName, armyOneToString; @@ -99,6 +109,10 @@ public class BattleController implements Initializable { scores[0] = 0; scores[1] = 0; score.setText(scores[0] + " - " + scores[1]); + + boolean bothArmiesNotImported = armies[0] == null || armies[1] == null; + resetArmiesButton.setDisable(bothArmiesNotImported); + resetAndBattleButton.setDisable(bothArmiesNotImported); } /** @@ -139,7 +153,7 @@ public class BattleController implements Initializable { armyOne = new Army(armies[0].getName(), unitsOne); armyTwo = new Army(armies[1].getName(), unitsTwo); - battle = new Battle(armyOne, armyTwo, Terrain.PLAINS); + battle = new Battle(armyOne, armyTwo, terrainChoiceBox.getValue()); attackList.getItems().clear(); @@ -266,6 +280,13 @@ public class BattleController implements Initializable { armies[0] = armyOne; armies[1] = armyTwo; + resetArmiesButton.setDisable(true); + resetAndBattleButton.setDisable(true); + + terrainChoiceBox.getItems().clear(); + terrainChoiceBox.getItems().addAll(Terrain.PLAINS, Terrain.FOREST, Terrain.HILL); + terrainChoiceBox.setValue(Terrain.PLAINS); + setDoubleClickSelectionModeOnListView(0); setDoubleClickSelectionModeOnListView(1); diff --git a/src/main/resources/stylesheet.css b/src/main/resources/stylesheet.css new file mode 100644 index 0000000000000000000000000000000000000000..ea7f51aa8d8e1cdfa714d3e91ecabd2744dd7c8a --- /dev/null +++ b/src/main/resources/stylesheet.css @@ -0,0 +1,9 @@ +.root{ + -fx-font-size: 20pt; + -fx-font-family: "Arial"; +} + +.vbox { + -fx-background-color: #98bb84; + -fx-border-color: red; +} \ No newline at end of file diff --git a/src/main/resources/wargames.fxml b/src/main/resources/wargames.fxml index 7a25d667f13f86956f3b733a51624b988774a41e..8a46e1167fbfc3755478b9d6ce1512819338685e 100644 --- a/src/main/resources/wargames.fxml +++ b/src/main/resources/wargames.fxml @@ -2,6 +2,7 @@ <?import javafx.geometry.Insets?> <?import javafx.scene.control.Button?> +<?import javafx.scene.control.ChoiceBox?> <?import javafx.scene.control.Label?> <?import javafx.scene.control.ListView?> <?import javafx.scene.control.ScrollPane?> @@ -13,175 +14,186 @@ <?import javafx.scene.text.Font?> <?import javafx.scene.text.Text?> -<ScrollPane fitToHeight="true" fitToWidth="true" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" - minWidth="-Infinity" prefHeight="720.0" prefWidth="1280.0" xmlns="http://javafx.com/javafx/17" - xmlns:fx="http://javafx.com/fxml/1" fx:controller="edu.ntnu.idatt2001.carljgu.client.BattleController"> +<ScrollPane fitToHeight="true" fitToWidth="true" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="720.0" prefWidth="1280.0" xmlns="http://javafx.com/javafx/18" xmlns:fx="http://javafx.com/fxml/1" fx:controller="edu.ntnu.idatt2001.carljgu.client.BattleController"> <HBox alignment="CENTER" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"> <VBox alignment="CENTER" maxWidth="1.7976931348623157E308" HBox.hgrow="ALWAYS"> <HBox.margin> - <Insets bottom="50.0" left="50.0" right="50.0" top="50.0"/> + <Insets bottom="50.0" left="50.0" right="50.0" top="40.0" /> </HBox.margin> - <Text fx:id="armyOneName" strokeType="OUTSIDE" strokeWidth="0.0" text="No army selected" - VBox.vgrow="ALWAYS"> + <Text fx:id="armyOneName" strokeType="OUTSIDE" strokeWidth="0.0" text="No army selected" VBox.vgrow="ALWAYS"> <font> - <Font name="Times New Roman" size="36.0"/> + <Font name="Arial" size="36.0" /> </font> <VBox.margin> - <Insets bottom="10.0" top="10.0"/> + <Insets bottom="10.0" top="10.0" /> </VBox.margin> </Text> - <Text fx:id="armyOneToString" strokeType="OUTSIDE" strokeWidth="0.0" text="Import an army" - textAlignment="CENTER" wrappingWidth="301.96319580078125" VBox.vgrow="ALWAYS"> + <Text fx:id="armyOneToString" strokeType="OUTSIDE" strokeWidth="0.0" text="Import an army" textAlignment="CENTER" wrappingWidth="301.96319580078125" VBox.vgrow="ALWAYS"> <font> - <Font size="18.0"/> + <Font name="Arial" size="20.0" /> </font> <VBox.margin> - <Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/> + <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> </VBox.margin> </Text> <HBox alignment="CENTER"> <VBox.margin> - <Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/> + <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> </VBox.margin> <ImageView fitHeight="40.0" fitWidth="40.0" preserveRatio="true"> <HBox.margin> - <Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/> + <Insets bottom="5.0" left="5.0" right="5.0" top="5.0" /> </HBox.margin> - <Image url="@icons/folder.png"/> + <Image url="@icons/folder.png" /> </ImageView> <Button alignment="CENTER" mnemonicParsing="false" onAction="#importArmyOne" text="Import army"> <HBox.margin> - <Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/> + <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> </HBox.margin> </Button> </HBox> - <Text fx:id="armyOneImportPath" strokeType="OUTSIDE" strokeWidth="0.0"/> + <Text fx:id="armyOneImportPath" strokeType="OUTSIDE" strokeWidth="0.0" /> <TitledPane animated="false" collapsible="false" maxHeight="500.0" text="Units" VBox.vgrow="ALWAYS"> <font> - <Font name="System Bold" size="18.0"/> + <Font name="Arial" size="18.0" /> </font> - <ListView fx:id="armyOneUnitsListView" prefHeight="200.0" prefWidth="200.0"/> + <ListView fx:id="armyOneUnitsListView" prefHeight="200.0" prefWidth="200.0" /> </TitledPane> </VBox> - <VBox alignment="TOP_CENTER" maxWidth="1.7976931348623157E308" prefWidth="100.0" HBox.hgrow="ALWAYS"> + <VBox alignment="TOP_CENTER" maxWidth="1.7976931348623157E308" minWidth="400.0" prefWidth="500.0" HBox.hgrow="ALWAYS"> <HBox.margin> - <Insets bottom="50.0" left="25.0" right="25.0" top="10.0"/> + <Insets bottom="50.0" left="15.0" right="15.0" top="10.0" /> </HBox.margin> <Label text="Wargames"> <font> - <Font name="Times New Roman Bold" size="48.0"/> + <Font name="Arial Bold" size="48.0" /> </font> <VBox.margin> - <Insets bottom="40.0"/> + <Insets bottom="40.0" /> </VBox.margin> </Label> <Text strokeType="OUTSIDE" strokeWidth="0.0" text="VS."> <font> - <Font size="36.0"/> + <Font name="Arial" size="36.0" /> </font> <VBox.margin> - <Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/> + <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> </VBox.margin> </Text> <HBox alignment="CENTER"> - <Button mnemonicParsing="false" onAction="#resetArmies" text="Reset armies"> + <Button mnemonicParsing="false" onAction="#resetArmies" text="Reset armies" fx:id="resetArmiesButton"> <font> - <Font size="16.0"/> + <Font name="Arial" size="20.0" /> </font> <HBox.margin> - <Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/> + <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> </HBox.margin> </Button> - <Button mnemonicParsing="false" onAction="#runSimulation" text="Reset and run"> + <Button mnemonicParsing="false" onAction="#runSimulation" text="Reset and battle" fx:id="resetAndBattleButton"> <font> - <Font size="16.0"/> + <Font name="Arial" size="20.0" /> </font> <HBox.margin> - <Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/> + <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> </HBox.margin> </Button> </HBox> + <HBox prefHeight="100.0" prefWidth="200.0" /> + <HBox alignment="CENTER"> + <children> + <Text strokeType="OUTSIDE" strokeWidth="0.0" text="Choose terrain:"> + <font> + <Font name="Arial" size="20.0" /> + </font> + <HBox.margin> + <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> + </HBox.margin> + </Text> + <ChoiceBox fx:id="terrainChoiceBox" accessibleText="Choose terrain" prefWidth="200.0"> + <HBox.margin> + <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> + </HBox.margin> + </ChoiceBox> + </children> + </HBox> <Text strokeType="OUTSIDE" strokeWidth="0.0" text="Last simulation:"> <VBox.margin> - <Insets bottom="10.0" left="20.0" right="20.0" top="20.0"/> + <Insets bottom="10.0" left="20.0" right="20.0" top="20.0" /> </VBox.margin> <font> - <Font size="24.0"/> + <Font name="Arial" size="24.0" /> </font> </Text> <Text fx:id="lastSimulation" strokeType="OUTSIDE" strokeWidth="0.0" text="No simulation run"> <font> - <Font size="16.0"/> + <Font name="Arial" size="20.0" /> </font> </Text> <Text strokeType="OUTSIDE" strokeWidth="0.0" text="Times armies have won:"> <font> - <Font size="24.0"/> + <Font name="Arial" size="24.0" /> </font> <VBox.margin> - <Insets bottom="10.0" left="20.0" right="20.0" top="20.0"/> + <Insets bottom="10.0" left="20.0" right="20.0" top="20.0" /> </VBox.margin> </Text> <Text fx:id="score" strokeType="OUTSIDE" strokeWidth="0.0" text="0 - 0"> <font> - <Font size="16.0"/> + <Font name="Arial" size="20.0" /> </font> </Text> - <TitledPane animated="false" collapsible="false" maxHeight="1.7976931348623157E308" minHeight="200.0" - text="Simulation attacks" VBox.vgrow="ALWAYS"> + <TitledPane animated="false" collapsible="false" maxHeight="1.7976931348623157E308" minHeight="200.0" text="Simulation attack log. Earliest first" VBox.vgrow="ALWAYS"> <VBox.margin> - <Insets bottom="10.0" left="10.0" right="10.0" top="30.0"/> + <Insets bottom="10.0" left="10.0" right="10.0" top="20.0" /> </VBox.margin> <font> - <Font name="System Bold" size="16.0"/> + <Font name="Arial" size="20.0" /> </font> - <ListView fx:id="attackList"/> + <ListView fx:id="attackList" /> </TitledPane> </VBox> <VBox alignment="CENTER" HBox.hgrow="ALWAYS"> <HBox.margin> - <Insets bottom="50.0" left="50.0" right="50.0" top="50.0"/> + <Insets bottom="40.0" left="40.0" right="40.0" top="40.0" /> </HBox.margin> - <Text fx:id="armyTwoName" strokeType="OUTSIDE" strokeWidth="0.0" text="No army selected" - VBox.vgrow="ALWAYS"> + <Text fx:id="armyTwoName" strokeType="OUTSIDE" strokeWidth="0.0" text="No army selected" VBox.vgrow="ALWAYS"> <font> - <Font name="Times New Roman" size="36.0"/> + <Font name="Arial" size="36.0" /> </font> <VBox.margin> - <Insets bottom="10.0" top="10.0"/> + <Insets bottom="10.0" top="10.0" /> </VBox.margin> </Text> - <Text fx:id="armyTwoToString" strokeType="OUTSIDE" strokeWidth="0.0" text="Import an army" - textAlignment="CENTER" wrappingWidth="301.96319580078125" VBox.vgrow="ALWAYS"> + <Text fx:id="armyTwoToString" strokeType="OUTSIDE" strokeWidth="0.0" text="Import an army" textAlignment="CENTER" wrappingWidth="301.96319580078125" VBox.vgrow="ALWAYS"> <font> - <Font size="18.0"/> + <Font name="Arial" size="20.0" /> </font> <VBox.margin> - <Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/> + <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> </VBox.margin> </Text> <HBox alignment="CENTER" maxWidth="1.7976931348623157E308"> <VBox.margin> - <Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/> + <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> </VBox.margin> <ImageView fitHeight="40.0" fitWidth="40.0" preserveRatio="true"> <HBox.margin> - <Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/> + <Insets bottom="5.0" left="5.0" right="5.0" top="5.0" /> </HBox.margin> - <Image url="@icons/folder.png"/> + <Image url="@icons/folder.png" /> </ImageView> <Button alignment="CENTER" mnemonicParsing="false" onAction="#importArmyTwo" text="Import army"> <HBox.margin> - <Insets bottom="10.0" left="10.0" right="10.0" top="10.0"/> + <Insets bottom="10.0" left="10.0" right="10.0" top="10.0" /> </HBox.margin> </Button> </HBox> - <Text fx:id="armyTwoImportPath" strokeType="OUTSIDE" strokeWidth="0.0" VBox.vgrow="ALWAYS"/> + <Text fx:id="armyTwoImportPath" strokeType="OUTSIDE" strokeWidth="0.0" VBox.vgrow="ALWAYS" /> <TitledPane animated="false" collapsible="false" maxHeight="500.0" text="Units" VBox.vgrow="ALWAYS"> <font> - <Font name="System Bold" size="18.0"/> + <Font name="Arial" size="18.0" /> </font> - <ListView fx:id="armyTwoUnitsListView" prefHeight="200.0" prefWidth="200.0"/> + <ListView fx:id="armyTwoUnitsListView" prefHeight="200.0" prefWidth="200.0" /> </TitledPane> </VBox> </HBox>