From ee054c35d2758d2915769dd0e87203d0f79ab69b Mon Sep 17 00:00:00 2001 From: Zabuzard Date: Mon, 1 Dec 2025 09:06:01 +0100 Subject: [PATCH] Submission --- .../org/togetherjava/event/elevator/Main.java | 14 ++-- .../event/elevator/elevators/Elevator.java | 74 +++++++++++++++++-- .../elevator/elevators/ElevatorPanel.java | 1 + .../elevator/elevators/ElevatorSystem.java | 64 +++++++++++++++- .../elevator/elevators/FloorPanelSystem.java | 2 + .../elevator/humans/ElevatorListener.java | 5 +- .../event/elevator/humans/Human.java | 70 ++++++++++++++++-- 7 files changed, 211 insertions(+), 19 deletions(-) diff --git a/Contest/Assignment/src/org/togetherjava/event/elevator/Main.java b/Contest/Assignment/src/org/togetherjava/event/elevator/Main.java index e9e4159..05f7ead 100644 --- a/Contest/Assignment/src/org/togetherjava/event/elevator/Main.java +++ b/Contest/Assignment/src/org/togetherjava/event/elevator/Main.java @@ -1,6 +1,8 @@ package org.togetherjava.event.elevator; import org.togetherjava.event.elevator.elevators.Elevator; +import org.togetherjava.event.elevator.elevators.ElevatorSystem; +import org.togetherjava.event.elevator.elevators.TravelDirection; import org.togetherjava.event.elevator.humans.Human; import org.togetherjava.event.elevator.simulation.Simulation; @@ -14,18 +16,19 @@ public final class Main { * @param args Not supported */ public static void main(final String[] args) { + // Select a desired simulation for trying out your code. // Start with the simple simulations first, try out the bigger systems once you got it working. // Eventually try out the randomly generated systems. If you want to debug a problem you encountered // with one of them, note down the seed that it prints at the beginning and then use the variant that takes this seed. // That way, it will generate the same system again, and you can repeat the test. - Simulation simulation = Simulation.createSingleElevatorSingleHumanSimulation(); + // Simulation simulation = Simulation.createSingleElevatorSingleHumanSimulation(); // Simulation simulation = Simulation.createSimpleSimulation(); - // Simulation simulation = Simulation.createRandomSimulation(5, 50, 10); + Simulation simulation = Simulation.createRandomSimulation(5, 50, 10); // Simulation simulation = Simulation.createRandomSimulation(putDesiredSeedHere, 5, 50, 10); - +// simulation.printSummary(); - +// System.out.println("Starting simulation..."); simulation.start(); simulation.prettyPrint(); @@ -33,7 +36,7 @@ public static void main(final String[] args) { while (!simulation.isDone()) { System.out.println("\tSimulation step " + simulation.getStepCount()); simulation.step(); - simulation.prettyPrint(); + simulation.prettyPrint(); if (simulation.getStepCount() >= 100_000) { throw new IllegalStateException("Simulation aborted. All humans should have arrived" @@ -41,7 +44,6 @@ public static void main(final String[] args) { } } System.out.println("Simulation is done."); - simulation.printResult(); } } diff --git a/Contest/Assignment/src/org/togetherjava/event/elevator/elevators/Elevator.java b/Contest/Assignment/src/org/togetherjava/event/elevator/elevators/Elevator.java index 51333b2..070e6af 100644 --- a/Contest/Assignment/src/org/togetherjava/event/elevator/elevators/Elevator.java +++ b/Contest/Assignment/src/org/togetherjava/event/elevator/elevators/Elevator.java @@ -2,6 +2,8 @@ import java.util.StringJoiner; import java.util.concurrent.atomic.AtomicInteger; +import java.util.ArrayList; +import java.util.List; /** * A single elevator that can serve a given amount of floors. @@ -16,6 +18,7 @@ public final class Elevator implements ElevatorPanel { private final int minFloor; private final int floorsServed; private int currentFloor; + private List destinations; /** * Creates a new elevator. @@ -37,35 +40,74 @@ public Elevator(int minFloor, int floorsServed, int currentFloor) { this.minFloor = minFloor; this.currentFloor = currentFloor; this.floorsServed = floorsServed; + this.destinations = new ArrayList<>(); } + /** + * The unique ID of the elevator. + * + * @return the unique ID of the elevator + */ @Override public int getId() { return id; } + /** + * The lowest floor the elevator can service. + * + * @return the lowest floor the elevator can service. + */ public int getMinFloor() { return minFloor; } + /** + * The amount of floors the elevator can service. + * + * @return the amount of floors the elevator can service. + */ public int getFloorsServed() { return floorsServed; } + /** + * The floor the elevator is currently at. + * + * @return the floor the elevator is currently at. + */ @Override public int getCurrentFloor() { return currentFloor; } + /** + * The chosen Elevator will store this destination in it,s arrayList so it knows + * which direction to move in and when it has arrived. + * It will not store the same destination twice. + * + * @param destinationFloor stores the destination of the humans entering it + */ @Override public void requestDestinationFloor(int destinationFloor) { - // TODO Implement. This represents a human or the elevator system - // itself requesting this elevator to eventually move to the given floor. - // The elevator is supposed to memorize the destination in a way that - // it can ensure to eventually reach it. + + if(!destinations.contains(destinationFloor)){ + destinations.add(destinationFloor); + } + System.out.println("Request for destination floor received"); } + // create a method that will store the destinations in order: + // closest to the current floor. So every time an elevator moved one floor, + // we have to call this method as wel, because humans entering add to the + // array. + + /** + * Moving the elevator one floor in the correct direction and + * when it arrived at it,s destination it will remove that floor from + * it,s arrayList: destinations. + */ public void moveOneFloor() { // TODO Implement. Essentially there are three possibilities: // - move up one floor @@ -76,9 +118,31 @@ public void moveOneFloor() { // meaning that the average time waiting (either in corridor or inside the elevator) // is minimized across all humans. // It is essential that this method updates the currentFloor field accordingly. - System.out.println("Request to move a floor received"); + + // try to let an empty elevator help an elevator with more humans to transport. + //System.out.println("Request to move a floor received on elevator id: " + getId() + "--- " + getCurrentFloor()); + System.out.println(destinations); + if(destinations.isEmpty()){ + return; + } + + int destination = destinations.get(0); + + if (this.currentFloor < destination) { + this.currentFloor++; + } else if (this.currentFloor > destination) { + this.currentFloor--; + } else { + System.out.println("Elevator " + id + " ARRIVED at floor " + currentFloor); + destinations.remove(0); + } } + /** + * Prints the data of the fields of class Elevator + * + * @return the data of the fields of class Elevator. + **/ @Override public synchronized String toString() { return new StringJoiner(", ", Elevator.class.getSimpleName() + "[", "]").add("id=" + id) diff --git a/Contest/Assignment/src/org/togetherjava/event/elevator/elevators/ElevatorPanel.java b/Contest/Assignment/src/org/togetherjava/event/elevator/elevators/ElevatorPanel.java index 386ec77..9d29314 100644 --- a/Contest/Assignment/src/org/togetherjava/event/elevator/elevators/ElevatorPanel.java +++ b/Contest/Assignment/src/org/togetherjava/event/elevator/elevators/ElevatorPanel.java @@ -3,6 +3,7 @@ /** * The system inside an elevator which provides information about the elevator and can be * used to request a destination floor. + * This interface represents all the actions that an elevator will want to expose to humans. */ public interface ElevatorPanel { /** diff --git a/Contest/Assignment/src/org/togetherjava/event/elevator/elevators/ElevatorSystem.java b/Contest/Assignment/src/org/togetherjava/event/elevator/elevators/ElevatorSystem.java index fadfe56..5728c3c 100644 --- a/Contest/Assignment/src/org/togetherjava/event/elevator/elevators/ElevatorSystem.java +++ b/Contest/Assignment/src/org/togetherjava/event/elevator/elevators/ElevatorSystem.java @@ -16,19 +16,33 @@ public final class ElevatorSystem implements FloorPanelSystem { private final List elevators = new ArrayList<>(); private final List elevatorListeners = new ArrayList<>(); + /** + * Registers all Elevator fields in an ArrayList + * @param elevator a single elevator with it,s fields data, created in the Elevator class. + */ public void registerElevator(Elevator elevator) { elevators.add(elevator); } + /** + * Registers all ElevatorListeners objects (humans) in an ArrayList + * @param listener a single human with it,s fields data, created in the Human class. + */ public void registerElevatorListener(ElevatorListener listener) { elevatorListeners.add(listener); } /** * Upon calling this, the system is ready to receive elevator requests. Elevators may now start moving. + * Every human in the arrayList listeners calls this method. + * {@link org.togetherjava.event.elevator.humans.Human#onElevatorSystemReady(FloorPanelSystem)} } */ public void ready() { - elevatorListeners.forEach(listener -> listener.onElevatorSystemReady(this)); + // elevatorListeners.forEach(listener -> listener.onElevatorSystemReady(this)); + + for (ElevatorListener listener : elevatorListeners) { + listener.onElevatorSystemReady(this); + } } @Override @@ -39,11 +53,57 @@ public void requestElevator(int atFloor, TravelDirection desiredTravelDirection) // The human can then enter the elevator and request their actual destination within the elevator. // Ideally this has to select the best elevator among all which can reduce the time // for the human spending waiting (either in corridor or in the elevator itself). - System.out.println("Request for elevator received"); + + if (elevators.isEmpty()){ + return; + } + int calculateDistance = 0; + + Elevator chosenElevator = this.elevators.get(0); + if (chosenElevator.getCurrentFloor() < atFloor){ + calculateDistance = atFloor - chosenElevator.getCurrentFloor(); + } else if (chosenElevator.getCurrentFloor() > atFloor){ + calculateDistance = chosenElevator.getCurrentFloor() - atFloor; + } + + for (Elevator elevator : elevators) { + + int distance = 0; + if (elevator.getCurrentFloor() < atFloor){ + distance = atFloor - elevator.getCurrentFloor(); + } else if (elevator.getCurrentFloor() > atFloor){ + distance = elevator.getCurrentFloor() - atFloor; + } + + if (calculateDistance > distance) { + calculateDistance = distance; + chosenElevator = elevator; + } + } + //System.out.println("calculate distance = " + calculateDistance); + + // elevator panel is now being used: + chosenElevator.requestDestinationFloor(atFloor); + System.out.println("Request for elevator received at Floor: " + atFloor); + System.out.println("chosen Elevator = " + chosenElevator); } + + /** + * First it runs the {@link org.togetherjava.event.elevator.elevators.Elevator#moveOneFloor()} method on every elevator. + * Then it lets every elevator in the elevator list tell every human in the listener list + * that it has moved one Floor. + */ public void moveOneFloor() { + // think about this one, could be more efficient? + elevators.forEach(Elevator::moveOneFloor); + // loops through the elevators and moves all the elevators in the arrayList + elevators.forEach(elevator -> elevatorListeners.forEach(listener -> listener.onElevatorArrivedAtFloor(elevator))); + // nested loop, looping through all elevators and tells all humans on which floor it has arrived. + // this part specifically can be done more efficiently as also mentioned in the Javadoc + // inside the ElevatorListener Interface + // currentEnteredElevatorId?? } } diff --git a/Contest/Assignment/src/org/togetherjava/event/elevator/elevators/FloorPanelSystem.java b/Contest/Assignment/src/org/togetherjava/event/elevator/elevators/FloorPanelSystem.java index 8043228..84156e2 100644 --- a/Contest/Assignment/src/org/togetherjava/event/elevator/elevators/FloorPanelSystem.java +++ b/Contest/Assignment/src/org/togetherjava/event/elevator/elevators/FloorPanelSystem.java @@ -2,6 +2,8 @@ /** * The system in corridors that allows requesting elevators to the current floor. + * This interface represents the action that the elevator system itself exposes to humans + * standing on the corridor. */ public interface FloorPanelSystem { /** diff --git a/Contest/Assignment/src/org/togetherjava/event/elevator/humans/ElevatorListener.java b/Contest/Assignment/src/org/togetherjava/event/elevator/humans/ElevatorListener.java index a124b1b..bda78e7 100644 --- a/Contest/Assignment/src/org/togetherjava/event/elevator/humans/ElevatorListener.java +++ b/Contest/Assignment/src/org/togetherjava/event/elevator/humans/ElevatorListener.java @@ -6,10 +6,13 @@ /** * Listeners to elevator events. This is mostly interesting for * humans who can then request elevators to move to desired floors. + * This interface represents all the actions that a human will be interested in. */ public interface ElevatorListener { /** - * Fired when the elevator system is ready to receive requests. Elevators can now move. + * Fired when the elevator system is ready (elevators are created) + * to receive requests. Elevators can now move. + * * * @param floorPanelSystem the system in the corridor that allows * requesting elevators to the current floor diff --git a/Contest/Assignment/src/org/togetherjava/event/elevator/humans/Human.java b/Contest/Assignment/src/org/togetherjava/event/elevator/humans/Human.java index 0af2511..5129faa 100644 --- a/Contest/Assignment/src/org/togetherjava/event/elevator/humans/Human.java +++ b/Contest/Assignment/src/org/togetherjava/event/elevator/humans/Human.java @@ -1,7 +1,6 @@ package org.togetherjava.event.elevator.humans; -import org.togetherjava.event.elevator.elevators.ElevatorPanel; -import org.togetherjava.event.elevator.elevators.FloorPanelSystem; +import org.togetherjava.event.elevator.elevators.*; import java.util.OptionalInt; import java.util.StringJoiner; @@ -39,30 +38,73 @@ public Human(int startingFloor, int destinationFloor) { this.startingFloor = startingFloor; this.destinationFloor = destinationFloor; - currentState = State.IDLE; + this.currentEnteredElevatorId = null; } + /** + * The state the human is currently in. + * + * @return the State the human is in + */ public State getCurrentState() { return currentState; } + /** + * The floor the human currently stands at. + * + * @return the floor the human currently stands at + */ public int getStartingFloor() { return startingFloor; } + + /** + * The foor the human wants to reach. + * + * @return the floor the human wants to reach. + */ public int getDestinationFloor() { return destinationFloor; } + + /** + * This method will set the human State to WAITING and set the travelDirection + * Then it will call the requestElevator system. + * @param floorPanelSystem the system in the corridor that allows + * requesting elevators to the current floor + */ @Override public void onElevatorSystemReady(FloorPanelSystem floorPanelSystem) { // TODO Implement. The system is now ready and the human should leave // their initial IDLE state, requesting an elevator by clicking on the buttons of // the floor panel system. The human will now enter the WAITING_FOR_ELEVATOR state. - System.out.println("Ready-event received"); + // System.out.println("Ready-event received"); + + currentState = State.WAITING_FOR_ELEVATOR; + TravelDirection chosenDirection = null; + + if(this.startingFloor < this.destinationFloor) { + chosenDirection = TravelDirection.UP; + } else if(this.startingFloor > this.destinationFloor){ + chosenDirection = TravelDirection.DOWN; + } + + floorPanelSystem.requestElevator(getStartingFloor(), chosenDirection); } + /** + * his method will set the human State to TRAVELING. + * It will give the human the ID of the elevator it entered. + * Then it will call the requestDestination method, setting the destination. + * If the elevator arrived at the destination it will set the State to ARRIVED + * and the ID to null. + * @param elevatorPanel the system inside the elevator which provides information + * about the elevator and can be used to request a destination floor. + */ @Override public void onElevatorArrivedAtFloor(ElevatorPanel elevatorPanel) { // TODO Implement. If the human is currently waiting for an elevator and @@ -70,7 +112,21 @@ public void onElevatorArrivedAtFloor(ElevatorPanel elevatorPanel) { // elevator and request their actual destination floor. The state has to change to TRAVELING_WITH_ELEVATOR. // If the human is currently traveling with this elevator and the event represents // arrival at the human's destination floor, the human can now exit the elevator. - System.out.println("Arrived-event received"); + //System.out.println("Arrived-event received"); + + int elevatorId = elevatorPanel.getId(); + int elevatorFloor = elevatorPanel.getCurrentFloor(); + if (this.currentState == State.WAITING_FOR_ELEVATOR && this.startingFloor == elevatorFloor) { + this.currentState = State.TRAVELING_WITH_ELEVATOR; + this.currentEnteredElevatorId = elevatorId; + elevatorPanel.requestDestinationFloor(this.destinationFloor); + return; + } + if (this.currentState == State.TRAVELING_WITH_ELEVATOR && elevatorFloor == this.destinationFloor + && this.currentEnteredElevatorId == elevatorId) { + this.currentState = State.ARRIVED; + this.currentEnteredElevatorId = null; + } } public OptionalInt getCurrentEnteredElevatorId() { @@ -79,6 +135,10 @@ public OptionalInt getCurrentEnteredElevatorId() { : OptionalInt.of(currentEnteredElevatorId); } + /** + * returns the data of the Human class fields. + * @return the data of the Human class fields. + */ @Override public String toString() { return new StringJoiner(", ", Human.class.getSimpleName() + "[", "]")