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).
+