From 82dab9f7c91b02e631e409b53a8822b11f28afde Mon Sep 17 00:00:00 2001 From: tjsus <tjsus@172.20.148.137> Date: Thu, 29 Aug 2024 11:43:31 -0700 Subject: [PATCH] Assignment 3 code modified to add comment PDU to update player 1 and player 2 grids. --- .../Smith/ExampleSimulationProgram.java | 121 ++++++++++++++---- 1 file changed, 95 insertions(+), 26 deletions(-) diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework3/Smith/ExampleSimulationProgram.java b/assignments/src/MV3500Cohort2024JulySeptember/homework3/Smith/ExampleSimulationProgram.java index 1e91768baf..502d7ccbcf 100644 --- a/assignments/src/MV3500Cohort2024JulySeptember/homework3/Smith/ExampleSimulationProgram.java +++ b/assignments/src/MV3500Cohort2024JulySeptember/homework3/Smith/ExampleSimulationProgram.java @@ -1,15 +1,17 @@ package MV3500Cohort2024JulySeptember.homework3.Smith; +import edu.nps.moves.dis7.enumerations.VariableRecordType; import edu.nps.moves.dis7.pdus.*; import edu.nps.moves.dis7.utilities.DisChannel; import edu.nps.moves.dis7.utilities.PduFactory; import java.util.logging.Level; import java.util.logging.Logger; -/** The purpose of this inheritable class is to provide an easily modifiable - * example simulation program that includes DIS-capable entities performing - * tasks of interest, and then reporting activity via PDUs to the network. - * Default program initialization includes PDU recording turned on by default. +/** + * The purpose of this inheritable class is to provide an easily modifiable + * example simulation program that includes DIS-capable entities performing + * tasks of interest, and then reporting activity via PDUs to the network. + * Default program initialization includes PDU recording turned on by default. */ public class ExampleSimulationProgram { @@ -32,6 +34,7 @@ public class ExampleSimulationProgram { private String descriptor = this.getClass().getSimpleName(); protected DisChannel disChannel; protected PduFactory pduFactory; + protected CommentPdu gridStatusPdu; protected FirePdu firePduPlayer1; protected FirePdu firePduPlayer2; protected MunitionDescriptor munitionDescriptor1 = new MunitionDescriptor(); @@ -45,17 +48,17 @@ public class ExampleSimulationProgram { private int player1SearchCol = 0; /** - * Constructor to create an instance of this class. - * Design goal: additional built-in initialization conveniences can go here - * to keep your efforts focused on the runSimulation() method. + * Constructor to create an instance of this class. Design goal: additional + * built-in initialization conveniences can go here to keep your efforts + * focused on the runSimulation() method. */ public ExampleSimulationProgram() { initialize(); } - /** - * Initialize the simulation program, setting up the DIS channel, - * PDUs, and the Battleship game grids. + /** + * Initialize the simulation program, setting up the DIS channel, PDUs, and + * the Battleship game grids. */ private void initialize() { initializeDisChannel(); @@ -64,9 +67,9 @@ public class ExampleSimulationProgram { disChannel.join(); } - /** - * Initialize the DIS channel for communication, setting verbose output - * for debugging and creating the PduFactory. + /** + * Initialize the DIS channel for communication, setting verbose output for + * debugging and creating the PduFactory. */ private void initializeDisChannel() { disChannel = new DisChannel(); @@ -83,10 +86,12 @@ public class ExampleSimulationProgram { private void initializeSimulationEntities() { firePduPlayer1 = pduFactory.makeFirePdu(); firePduPlayer2 = pduFactory.makeFirePdu(); + gridStatusPdu = pduFactory.makeCommentPdu(); } /** - * Set up the game grids for each player, marking empty water and ship positions. + * Set up the game grids for each player, marking empty water and ship + * positions. */ private void setupGrids() { // Initialize grids with empty water '~' @@ -107,8 +112,9 @@ public class ExampleSimulationProgram { } /** - * This runSimulationLoops() method is for you, a customizable programmer-modifiable - * code block for defining and running a new simulation of interest. + * This runSimulationLoops() method is for you, a customizable + * programmer-modifiable code block for defining and running a new + * simulation of interest. */ public void runSimulationLoops() { int turnCount = 0; @@ -149,7 +155,9 @@ public class ExampleSimulationProgram { } /** - * Systematically select the next target for Player 1 in a row-by-row manner. + * Systematically select the next target for Player 1 in a row-by-row + * manner. + * * @return the coordinates of the next target cell. */ private int[] selectNextTargetForPlayer1() { @@ -174,6 +182,7 @@ public class ExampleSimulationProgram { /** * Randomly select a target on the grid for Player 2's turn. + * * @return the coordinates of the randomly selected target cell. */ private int[] selectRandomTarget() { @@ -183,8 +192,10 @@ public class ExampleSimulationProgram { } /** - * Handles the firing action, checking if the target is a hit or miss, - * updating the grid, and sending the appropriate PDU. + * Handles the firing action, setting relevant data in the FirePdu, checking + * if the target is a hit or miss, updating the grid, and sending the + * appropriate PDU. + * * @param firePdu the FirePdu object to use for the shot. * @param grid the grid of the player being fired at. * @param target the coordinates of the target cell. @@ -194,25 +205,44 @@ public class ExampleSimulationProgram { int x = target[0]; int y = target[1]; - // Fire at the target position - firePdu.setDescriptor(munitionDescriptor1).setRange(100.0f); // Example fire properties + // Set relevant details in the FirePdu + firePdu.setFiringEntityID(new EntityID().setEntityID(player.equals("Player 1") ? 1 : 2)); + firePdu.setTargetEntityID(new EntityID().setEntityID(player.equals("Player 1") ? 1 : 2)); + Vector3Double fireLoc = new Vector3Double(); + fireLoc.setX(x); + fireLoc.setY(y); + fireLoc.setZ(0.0); + firePdu.setLocationInWorldCoordinates(fireLoc); + firePdu.setDescriptor(munitionDescriptor1); + firePdu.setRange(100.0f); + // Log the firing action + System.out.println(player + " fires at (" + x + ", " + y + ")."); + + // Determine hit or miss and update the game grid if (grid[x][y] == 'P') { - grid[x][y] = 'H'; // Hit + grid[x][y] = 'H'; // Mark as Hit + firePdu.setFireMissionIndex(1); // Indicate that this was a successful hit with an index of 1 System.out.println(player + " hits a ship at (" + x + ", " + y + ")!"); } else if (grid[x][y] == '~') { - grid[x][y] = 'M'; // Miss + grid[x][y] = 'M'; // Mark as Miss + firePdu.setFireMissionIndex(0); // Indicate that this was a miss with an index of 0 System.out.println(player + " misses at (" + x + ", " + y + ")."); } else { System.out.println(player + " fires at (" + x + ", " + y + ") but it's already hit/missed."); } - // Send the fire PDU to reflect the shot + // Send the enriched FirePdu to reflect the shot disChannel.sendSinglePdu(simulationTimeSeconds, firePdu); + + // Send the updated grid status of both players + sendGridStatus(); } /** - * Checks the win condition by verifying if all ships on the grid have been hit. + * Checks the win condition by verifying if all ships on the grid have been + * hit. + * * @param grid the grid to check. * @return true if all ships are hit; false otherwise. */ @@ -228,10 +258,49 @@ public class ExampleSimulationProgram { return true; // All ships have been hit } + /** + * Sends the current grid status of both players as a CommentPdu. + */ + private void sendGridStatus() { + // Construct a string representation of both grids + StringBuilder gridStatus = new StringBuilder(); + gridStatus.append("Player 1 Grid:\n"); + appendGridToString(gridStatus, player1Grid); + gridStatus.append("Player 2 Grid:\n"); + appendGridToString(gridStatus, player2Grid); + + // Set the grid status in the CommentPdu + gridStatusPdu.getVariableDatums().clear(); // Clear previous comments + gridStatusPdu.getVariableDatums().add(new VariableDatum() + .setVariableDatumID(VariableRecordType.OTHER) + .setVariableDatumValue(gridStatus.toString().getBytes()) + .setVariableDatumLengthInBytes(gridStatus.toString().getBytes().length)); + + // Send the CommentPdu containing the grid status + disChannel.sendSinglePdu(simulationTimeSeconds, gridStatusPdu); + } + + /** + * Appends the current grid status to a StringBuilder. + * + * @param sb the StringBuilder to append to. + * @param grid the grid to represent. + */ + private void appendGridToString(StringBuilder sb, char[][] grid) { + for (char[] row : grid) { + for (char cell : row) { + sb.append(cell).append(' '); + } + sb.append('\n'); + } + } + /** * Main method is first executed when a program instance is loaded. + * * @param args command-line parameters: network address and port. - * Command-line arguments are an array of optional String parameters that are passed from execution environment during invocation + * Command-line arguments are an array of optional String parameters that + * are passed from execution environment during invocation */ public static void main(String[] args) { ExampleSimulationProgram game = new ExampleSimulationProgram(); -- GitLab