diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework3/Lennon/LennonSimulationProgram.java b/assignments/src/MV3500Cohort2024JulySeptember/homework3/Lennon/LennonSimulationProgram.java index a6bf39142a82b9a8f07e507e3acb7540398aac60..4e5c65a0b2f97634f6b851f69af48c13eec3e490 100644 --- a/assignments/src/MV3500Cohort2024JulySeptember/homework3/Lennon/LennonSimulationProgram.java +++ b/assignments/src/MV3500Cohort2024JulySeptember/homework3/Lennon/LennonSimulationProgram.java @@ -11,9 +11,13 @@ import edu.nps.moves.dis7.enumerations.*; import edu.nps.moves.dis7.pdus.*; import edu.nps.moves.dis7.utilities.DisChannel; import edu.nps.moves.dis7.utilities.PduFactory; +import static java.lang.Math.max; +import static java.lang.Math.min; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; +import java.util.Random; +import java.util.Scanner; import java.util.logging.Level; import java.util.logging.Logger; @@ -137,7 +141,7 @@ public class LennonSimulationProgram disChannel.getDisNetworkInterface().setVerbose(true); // sending and receipt disChannel.printlnTRACE ("just checking: hasVerboseSending()=" + disChannel.getDisNetworkInterface().hasVerboseSending() + ", hasVerboseReceipt()=" + disChannel.getDisNetworkInterface().hasVerboseReceipt()); - disChannel.getPduRecorder().setVerbose(true); + disChannel.getPduRecorder().setVerbose(false); // TODO confirm whether recorder is explicitly started by programmer (or not) @@ -205,10 +209,10 @@ public class LennonSimulationProgram { try { - final int SIMULATION_MAX_LOOP_COUNT = 10; // set number of turns in the game also avoid infinite loops. + final int SIMULATION_MAX_LOOP_COUNT = 20; // set number of turns in the game; also avoid infinite loops. int simulationLoopCount = 0; // variable, initialized at 0 boolean simulationComplete = false; // sentinel variable as termination condition, are we done yet? - final int NUMBER_MINES = 5; // preset number of mines to be placed + final int NUMBER_MINES = 30; // preset number of mines to be placed // TODO reset Clock Time for today's date and timestamp to zero, providing consistent outputs for each simulation run String timeMessage = "Simulation time " + simulationTimeSeconds + " at LocalDateTime " + LocalDateTime.now(); disChannel.sendCommentPdu(simulationTimeSeconds, DisChannel.COMMENTPDU_TIME, timeMessage); @@ -217,12 +221,36 @@ public class LennonSimulationProgram // =================================================================================================== // loop the simulation while allowed, programmer can set additional conditions to break out and finish + Random random = new Random(); + Scanner scanner = new Scanner(System.in); List<double[]> minefield = new ArrayList<>(); + //set start point at (0,0) + entityStatePdu_1.getEntityLocation().setX(0.0); + entityStatePdu_1.getEntityLocation().setY(0.0); + double[] start = {entityStatePdu_1.getEntityLocation().getX(), entityStatePdu_1.getEntityLocation().getY()}; + + //exit square is somewhere on the middle third of the far right edge of the minefield (space 3-6) + double exitY = random.nextInt(4)+3; + double[] exit = {9, exitY}; + for (int i = 0; i < NUMBER_MINES; i++){ - //double x = Random.nextInt(); - //double[] mine = [] + //random placement of the mines within the 10x10 grid + double x = random.nextInt(10); + double y = random.nextInt(10) ; + double[] mine = {x,y}; + //No mine placed at the start position or on the exit space + if ((mine[0] == start[0] && mine[1] == start[1]) || (mine[0] == exit[0] && mine[1] == exit[1])){ + continue; + } + //add mines to the minefield list + minefield.add(mine); } + + System.out.println("\nYou are in a minefield. The exit is at (" + exit[0] + ", " + exit[1] + + "). \nWhen prompted, use the WASD keys to pick a move. \nCareful, you only have so many moves, and there are plenty of mines!"); + System.out.flush(); + while (simulationLoopCount < SIMULATION_MAX_LOOP_COUNT) // are we done yet? { simulationLoopCount++; // good practice: increment loop counter as first action in that loop @@ -230,35 +258,77 @@ public class LennonSimulationProgram // ============================================================================================= // * your own simulation code starts here! ***************************************************** // ============================================================================================= - + System.out.println("=========================================================================="); + System.out.println("\nMove "+ simulationLoopCount+ " of " + SIMULATION_MAX_LOOP_COUNT); + System.out.println("Current Location: (" + entityStatePdu_1.getEntityLocation().getX()+","+ entityStatePdu_1.getEntityLocation().getY() + "); Exit: (" + exit[0] + ", " + exit[1] + ")."); + System.out.println("Where would you like to move now?" ); // are there any other variables to modify at the beginning of your loop? - - // are your reading any DIS PDUs from the network? check for them here + boolean validMove = false; + String move = null; + while (!validMove){ + move = scanner.nextLine().toUpperCase(); + switch(move){ + case("W") -> { + entityStatePdu_1.getEntityLocation().setY(min(9.0, entityStatePdu_1.getEntityLocation().getY() + 1.0)); + validMove = true; + } + case("A") -> { + entityStatePdu_1.getEntityLocation().setX(max(0.0, entityStatePdu_1.getEntityLocation().getX() - 1.0)); + validMove = true; + } + case("S") -> { + entityStatePdu_1.getEntityLocation().setY(max(0.0, entityStatePdu_1.getEntityLocation().getY() - 1.0)); + validMove = true; + } + case("D") -> { + entityStatePdu_1.getEntityLocation().setX(min(9.0, entityStatePdu_1.getEntityLocation().getX() + 1.0)); + validMove = true; + } + default -> System.out.println("Not a valid move. Try again"); + } + } // compute a track, update an ESPDU, whatever it is that your model is doing... - // Where is my entity? Insert changes in position; this sample only changes X position. - entityStatePdu_1.getEntityLocation().setX(entityStatePdu_1.getEntityLocation().getX() + 1.0); // 1m per timestep + // decide whether to fire, and then update the firePdu. Hmmm, you might want a target to shoot at! // etc. etc. your code goes here for your simulation of interest - // something happens between my simulation entities, la de da de da... - System.out.println ("... My simulation just did something, no really..."); System.out.flush(); // make sure this arrives to user even if other threads somehow become deadlocked // make your reports: narrative code for CommentPdu here (set all to empty strings to avoid sending) - narrativeMessage1 = "MV3500 ExampleSimulationProgram"; + narrativeMessage1 = "MV3500 LennonSimulationProgram"; narrativeMessage2 = "runSimulation() loop " + simulationLoopCount; narrativeMessage3 = ""; // intentionally blank for testing // your loop termination condition goes here - if (simulationLoopCount > MAX_LOOP_COUNT) // for example + + //Check for entity to reach exit + if (entityStatePdu_1.getEntityLocation().getX() == exit[0] && entityStatePdu_1.getEntityLocation().getY() == exit[1]){ + System.out.println("You've escaped the minefield. Good job."); + narrativeMessage3 = "Entity escaped successfully."; + simulationComplete = true; + } + //Check for turn limit reached + else if (simulationLoopCount >= SIMULATION_MAX_LOOP_COUNT) { + System.out.println("You've run out of time. You lose."); + narrativeMessage3 = "Entity ran out of time."; simulationComplete = true; - } + } + + //Check for entity to hit mine + for (double[] mine : minefield){ + if (entityStatePdu_1.getEntityLocation().getX() == mine[0]&& entityStatePdu_1.getEntityLocation().getY() == mine[1]){ + System.out.println("BOOM! you hit a mine. You're dead."); + narrativeMessage3 = "Entity hit a mine and was destroyed."; + simulationComplete = true; + } + } + System.out.println(""); // ============================================================================================= // * your own simulation code is finished here! ************************************************ // ============================================================================================= @@ -266,7 +336,7 @@ public class LennonSimulationProgram // staying synchronized with timestep: wait duration for elapsed time in this loop // Thread.sleep needs a (long) parameter for milliseconds, which are clumsy to use sometimes Thread.sleep((long)(getSimulationTimeStepDuration() * 1000)); // units of seconds * (1000 msec/sec) = milliseconds - System.out.println ("... [Pausing for " + getSimulationTimeStepDuration() + " seconds]"); + //System.out.println ("... [Pausing for " + getSimulationTimeStepDuration() + " seconds]"); // OK now send the status PDUs for this loop, and then continue System.out.println ("... sending PDUs of interest for simulation step " + simulationLoopCount + ", monitor loopback to confirm sent"); diff --git a/assignments/src/MV3500Cohort2024JulySeptember/homework3/Lennon/README.md b/assignments/src/MV3500Cohort2024JulySeptember/homework3/Lennon/README.md new file mode 100644 index 0000000000000000000000000000000000000000..c5aadebfdcbc089649b153eb705bb84c6286336b --- /dev/null +++ b/assignments/src/MV3500Cohort2024JulySeptember/homework3/Lennon/README.md @@ -0,0 +1,38 @@ +## Homework 3: Example Simulation Recording using OpenDIS Network Streams + +<!-- Viewable at https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/assignments/src/MV3500Cohort2024JulySeptember/homework3/README.md --> + +### Assignment + +1. Adapt the functionality for [OpenDIS ExampleSimulationProgram](../../../../examples/src/OpenDis7Examples/ExampleSimulationProgram.java), modifying provided code +2. Experiment with the enumeration values that set up each entity and PDU. What works for you? What makes sense for your future work? +3. Adapt or replace the UML diagrams to describe what you have going on. +4. Record, save and replay your result stream using [PduRecorder](https://savage.nps.edu/opendis7-java/javadoc/edu/nps/moves/dis7/utilities/stream/PduRecorder.html) or [Wireshark](https://www.wireshark.org) + * see local [assignments/src/pduLog](../../../pduLog) subdirectory for latest opendis log files + * Coming soon, we will also (again have) [X3D-Edit](https://savage.nps.edu/X3D-Edit) for DIS stream recording/replay +5. Observe good-practice conventions in the [assignments README](../../../README.md) and [current-course README](../README.md) instructions. + +This assignment presents a Problem Prototyping opportunity. +While some minimal functionality is expected, the general outline of +a networking problem and proposed solution holds great interest. +Think of it as warmup preparation for your future work. + +This is also a freeplay opportunity. +You have the option to pick one or more of the provided course example programs +and adapt the source to demonstrate a new client-server handshake protocol of interest. + +Be sure to provide a rationale that justifies why the networking choices you made +(TCP/UDP, unicast/multicast, etc.) are the best for the problem you are addressing. + +You may find that the prior [homework2 README](../homework2/README.md) still provides +helpful details on what specific deliverables are expected in each homework assignment. + +Team efforts are encouraged, though if you choose a team approach be sure to justify why. +This is a good warmup prior to final projects. Have fun with Java networking! + +### Prior Assignment, August 2019 + +In 2019, students worked together on a single project to check wireless multicast connectivity recently deployed on NPS campus. + +See their experimental results in the [NPS Multicast Connectivity Report](../../MV3500Cohort2019JulySeptember/homework3). + diff --git a/build.properties b/build.properties index 9758be32e7c04e4d2adb7d4bcb96f8dfd4528517..401b692d7ddf7a3e39105df0dbb812841263aeee 100644 --- a/build.properties +++ b/build.properties @@ -31,5 +31,6 @@ mac.run.args=${common.run.args} \ dot.viskit.dir=${user.home}/.${product.shortname} c_app.xml=${viskit.dir}/configuration/c_app.xml c_gui.xml=${viskit.dir}/configuration/c_gui.xml +proj.xml=${viskit.dir}/configuration/viskitProject.xml splash.image=${viskit.dir}/configuration/ViskitSplash2.png diff --git a/build.xml b/build.xml index 6223df117e8f940eb31b536f90dfa0daab754ec1..52600ba1db0af2eb4f507158ca66538eae12ac22 100644 --- a/build.xml +++ b/build.xml @@ -327,6 +327,7 @@ POSSIBILITY OF SUCH DAMAGE. <!-- ${c_app.xml} and ${c_gui.xml} are properties in the build.properties definitions --> <copy todir="${dot.viskit.dir}" file="${c_app.xml}" verbose="true"/> <copy todir="${dot.viskit.dir}" file="${c_gui.xml}" verbose="true"/> + <copy todir="examples/src/ViskitOpenDis7Examples" file="${proj.xml}" overwrite="true"/> </target> </project> \ No newline at end of file diff --git a/examples/src/ViskitOpenDis7Examples/viskitProject.xml b/examples/src/ViskitOpenDis7Examples/viskitProject.xml index 9fb374249ecf197464b52cf4fff3f53b7dc083cd..f6152d4509d127907441b7f919d5faf2fdaf9e91 100644 --- a/examples/src/ViskitOpenDis7Examples/viskitProject.xml +++ b/examples/src/ViskitOpenDis7Examples/viskitProject.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<ViskitProject name="ViskitOpenDis7Examples"> +<ViskitProject> <AnalystReports name="AnalystReports" /> <AssembliesDirectory name="Assemblies" /> <EventGraphsDirectory name="EventGraphs" /> @@ -13,5 +13,4 @@ <extraClassPaths> <path value="C:/Users/RJRRLocal/MOVES/Q5/MV3500/src/NetworkedGraphicsMV3500/examples/src/ViskitOpenDis7Examples/lib/Networked_Graphics_MV3500_examples.jar" /> </extraClassPaths> -</ViskitProject> - +</ViskitProject> \ No newline at end of file diff --git a/viskit/MyViskitProjects/DefaultProject/EventGraphs/examples/ArrivalProcess.xml b/viskit/MyViskitProjects/DefaultProject/EventGraphs/examples/ArrivalProcess.xml old mode 100755 new mode 100644 diff --git a/viskit/MyViskitProjects/DefaultProject/EventGraphs/examples/TransferLineComponent.xml b/viskit/MyViskitProjects/DefaultProject/EventGraphs/examples/TransferLineComponent.xml index 63bce207d2bcb60e15209ffd48e2487df9d6cafc..c9e8ddec9b611c19ffb4524e41bda0e529db23c9 100644 --- a/viskit/MyViskitProjects/DefaultProject/EventGraphs/examples/TransferLineComponent.xml +++ b/viskit/MyViskitProjects/DefaultProject/EventGraphs/examples/TransferLineComponent.xml @@ -1,91 +1,68 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes"?> -<SimEntity extend="SimEntityBase" name="TransferLineComponent" package="examples" version="0.0.2" xsi:noNamespaceSchemaLocation="http://diana.nps.edu/Simkit/simkit.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> +<SimEntity name="TransferLineComponent" package="examples" version="0.0.2" extend="SimEntityBase" xsi:noNamespaceSchemaLocation="http://diana.nps.edu/Simkit/simkit.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <Comment>TODO: Fix me, I'm currently broken!! tdn 8/29/24</Comment> <Parameter name="totalNumberServers" type="int[]"/> <Parameter name="serviceTime" type="simkit.random.RandomVariate[]"/> <StateVariable name="numberAvailableServers" type="int[totalNumberServers.length]"/> <StateVariable name="numberInQueue" type="int[totalNumberServers.length]"/> <Event name="Run"> <LocalVariable name="j" type="int" value="0"> - <Comment/> + <Comment></Comment> </LocalVariable> - <LocalVariable name="_idxvar_0" type="int" value="0"> - <Comment>used internally</Comment> - </LocalVariable> - <LocalVariable name="_idxvar_1" type="int" value="0"> - <Comment>used internally</Comment> - </LocalVariable> - <StateTransition index="_idxvar_0" state="numberAvailableServers"> - <Assignment value="totalNumberServers[_idxvar_0]"/> + <StateTransition state="numberAvailableServers" index="j> + <Assignment value="totalNumberServers[j]"/> </StateTransition> - <StateTransition index="_idxvar_1" state="numberInQueue"> + <StateTransition state="numberInQueue" index="_idxvar_1"> <Assignment value="0"/> </StateTransition> - <Schedule delay="0.0" event="InitializeWorkcenter"> + <Schedule delay="0.0" event="InitializeWorkcenter" priority="DEFAULT"> <EdgeParameter value="0"/> </Schedule> - <Coordinate x="0" y="0"/> + <Coordinate x="0.0" y="0.0"/> </Event> <Event name="InitializeWorkcenter"> <Argument name="i" type="int"/> - <LocalVariable name="_idxvar_26" type="int" value="i"> - <Comment>used internally</Comment> - </LocalVariable> - <LocalVariable name="_idxvar_27" type="int" value="i"> - <Comment>used internally</Comment> - </LocalVariable> - <StateTransition index="_idxvar_26" state="numberInQueue"> + <StateTransition state="numberInQueue" index="_idxvar_26"> <Assignment value="0"/> </StateTransition> - <StateTransition index="_idxvar_27" state="numberAvailableServers"> + <StateTransition state="numberAvailableServers" index="_idxvar_27"> <Assignment value="totalNumberServers[i]"/> </StateTransition> - <Schedule condition="i < totalNumberServers.length - 1" event="InitializeWorkcenter"> + <Schedule event="InitializeWorkcenter" condition="i < totalNumberServers.length - 1" priority="DEFAULT"> <EdgeParameter value="i+1"/> </Schedule> - <Coordinate x="120" y="0"/> + <Coordinate x="120.0" y="0.0"/> </Event> <Event name="Arrival"> <Argument name="i" type="int"/> - <LocalVariable name="_idxvar_47" type="int" value="i"> - <Comment>used internally</Comment> - </LocalVariable> - <StateTransition index="_idxvar_47" state="numberInQueue"> + <StateTransition state="numberInQueue" index="_idxvar_47"> <Assignment value="numberInQueue[i] + 1"/> </StateTransition> - <Schedule condition="getNumberAvailableServers(i) > 0" event="StartService"> + <Schedule event="StartService" condition="getNumberAvailableServers(i) > 0" priority="DEFAULT"> <EdgeParameter value="i"/> </Schedule> - <Coordinate x="0" y="180"/> + <Coordinate x="0.0" y="180.0"/> </Event> <Event name="StartService"> <Argument name="i" type="int"/> - <LocalVariable name="_idxvar_48" type="int" value="i"> - <Comment>used internally</Comment> - </LocalVariable> - <LocalVariable name="_idxvar_49" type="int" value="i"> - <Comment>used internally</Comment> - </LocalVariable> - <StateTransition index="_idxvar_48" state="numberInQueue"> + <StateTransition state="numberInQueue" index="_idxvar_48"> <Assignment value="numberInQueue[i] + 1"/> </StateTransition> - <StateTransition index="_idxvar_49" state="numberAvailableServers"> + <StateTransition state="numberAvailableServers" index="_idxvar_49"> <Assignment value="numberAvailableServers[i] - 1"/> </StateTransition> - <Schedule delay="serviceTime[i].generate()" event="EndService"> + <Schedule delay="serviceTime[i].generate()" event="EndService" priority="DEFAULT"> <EdgeParameter value="i"/> </Schedule> - <Coordinate x="160" y="100"/> + <Coordinate x="160.0" y="100.0"/> </Event> <Event name="EndService"> <Argument name="i" type="int"/> - <LocalVariable name="_idxvar_50" type="int" value="i"> - <Comment>used internally</Comment> - </LocalVariable> - <StateTransition index="_idxvar_50" state="numberAvailableServers"> + <StateTransition state="numberAvailableServers" index="_idxvar_50"> <Assignment value="numberAvailableServers[i]+1"/> </StateTransition> - <Schedule condition="getNumberInQueue(i) > 0" event="StartService"/> - <Schedule condition="i < totalNumberServers.length - 1" event="Arrival"/> - <Coordinate x="330" y="200"/> + <Schedule event="StartService" condition="getNumberInQueue(i) > 0" priority="DEFAULT"/> + <Schedule event="Arrival" condition="i < totalNumberServers.length - 1" priority="DEFAULT"/> + <Coordinate x="330.0" y="200.0"/> </Event> -</SimEntity> \ No newline at end of file +</SimEntity> diff --git a/viskit/MyViskitProjects/DefaultProject/viskitProject.xml b/viskit/MyViskitProjects/DefaultProject/viskitProject.xml index 1a7a1fb34bf2bcba5b570b67f0793a7e0b6c9c27..2c559b5ae10acad72b382aa05802a5cb304d07ed 100644 --- a/viskit/MyViskitProjects/DefaultProject/viskitProject.xml +++ b/viskit/MyViskitProjects/DefaultProject/viskitProject.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<ViskitProject name="DefaultProject"> +<ViskitProject> <AnalystReports name="AnalystReports" /> <AssembliesDirectory name="Assemblies" /> <EventGraphsDirectory name="EventGraphs" /> @@ -11,5 +11,7 @@ <LibDirectory name="lib" /> <Cached> </Cached> + <extraClassPaths> + </extraClassPaths> </ViskitProject> diff --git a/viskit/configuration/viskitProject.xml b/viskit/configuration/viskitProject.xml index 91c9a9e3e6ee9ec708e59c9cf3bedc2f97236e45..16ae0dd6c2bf553fd03c5c990e84d683c11d94af 100644 --- a/viskit/configuration/viskitProject.xml +++ b/viskit/configuration/viskitProject.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<ViskitProject name="DefaultProject"> +<ViskitProject> <AnalystReports name="AnalystReports" /> <AssembliesDirectory name="Assemblies" /> <EventGraphsDirectory name="EventGraphs" /> diff --git a/viskit/lib/viskit.jar b/viskit/lib/viskit.jar index fa2bd59262e5771603440b823ff8f2d664e1c123..3482568ad3c2beeabe3015e9c4c479154b6317d3 100644 Binary files a/viskit/lib/viskit.jar and b/viskit/lib/viskit.jar differ