From 4f634b39cc77ee739ae90c0fe3a2971048356f75 Mon Sep 17 00:00:00 2001 From: Zabuzard Date: Mon, 15 Aug 2022 10:30:06 +0200 Subject: [PATCH] Submission --- .../event/elevator/elevators/Elevator.java | 70 ++++++++++++++++++- .../elevator/elevators/ElevatorPanel.java | 6 ++ .../elevator/elevators/ElevatorSystem.java | 27 ++++++- .../elevator/elevators/TravelDirection.java | 12 +++- .../event/elevator/humans/Human.java | 26 ++++++- 5 files changed, 132 insertions(+), 9 deletions(-) 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..e3da7e0 100644 --- a/Contest/Assignment/src/org/togetherjava/event/elevator/elevators/Elevator.java +++ b/Contest/Assignment/src/org/togetherjava/event/elevator/elevators/Elevator.java @@ -1,6 +1,6 @@ package org.togetherjava.event.elevator.elevators; -import java.util.StringJoiner; +import java.util.*; import java.util.concurrent.atomic.AtomicInteger; /** @@ -16,6 +16,9 @@ public final class Elevator implements ElevatorPanel { private final int minFloor; private final int floorsServed; private int currentFloor; + public List humansInside = new ArrayList<>(); + public List humansWaiting = new ArrayList<>(); + private TravelDirection travelDirection; /** * Creates a new elevator. @@ -39,6 +42,18 @@ public Elevator(int minFloor, int floorsServed, int currentFloor) { this.floorsServed = floorsServed; } + public Optional getTravelDirection() { + return travelDirection != null ? Optional.of(travelDirection) : Optional.empty(); + } + + /** + * @param direction can be null if it stays still + */ + public void setTravelDirection(TravelDirection direction) { + this.travelDirection = direction; + } + + @Override public int getId() { return id; @@ -63,7 +78,17 @@ public void requestDestinationFloor(int destinationFloor) { // 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. - System.out.println("Request for destination floor received"); + //System.out.println("Request for destination floor received"); + } + + @Override + public List getWaitingHumans() { + return humansWaiting; + } + + @Override + public List getHumansInside() { + return humansInside; } public void moveOneFloor() { @@ -76,7 +101,46 @@ 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"); + //System.out.println("Request to move a floor received"); + if (humansWaiting.isEmpty() && !humansInside.isEmpty()) { + int floor = humansInside + .stream() + .min(getComparator()) + .orElseThrow(() -> new IllegalStateException("State shouldn't be reachable")); + + TravelDirection travelDirection = TravelDirection.getTravelDirection(currentFloor, floor); + + if (travelDirection == null) { + return; + } + + switch (travelDirection) { + case UP -> currentFloor++; + case DOWN -> currentFloor--; + } + + } else if (!humansWaiting.isEmpty()) { + + int floor = humansWaiting + .stream() + .min(getComparator()) + .orElseThrow(() -> new IllegalStateException("State Shouldn't be possible")); + + TravelDirection travelDirection = TravelDirection.getTravelDirection(currentFloor, floor); + + if (travelDirection == null) { + return; + } + + switch (travelDirection) { + case UP -> currentFloor++; + case DOWN -> currentFloor--; + } + } + } + + private Comparator getComparator() { + return Comparator.comparingInt((floorNumber) -> Math.abs(floorNumber - currentFloor)); } @Override 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..16b58a8 100644 --- a/Contest/Assignment/src/org/togetherjava/event/elevator/elevators/ElevatorPanel.java +++ b/Contest/Assignment/src/org/togetherjava/event/elevator/elevators/ElevatorPanel.java @@ -1,5 +1,7 @@ package org.togetherjava.event.elevator.elevators; +import java.util.List; + /** * The system inside an elevator which provides information about the elevator and can be * used to request a destination floor. @@ -25,4 +27,8 @@ public interface ElevatorPanel { * @param destinationFloor the desired destination, must be within the range served by this elevator */ void requestDestinationFloor(int destinationFloor); + + List getWaitingHumans(); + + List getHumansInside(); } 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..4c94889 100644 --- a/Contest/Assignment/src/org/togetherjava/event/elevator/elevators/ElevatorSystem.java +++ b/Contest/Assignment/src/org/togetherjava/event/elevator/elevators/ElevatorSystem.java @@ -3,7 +3,9 @@ import org.togetherjava.event.elevator.humans.ElevatorListener; import java.util.ArrayList; +import java.util.Comparator; import java.util.List; +import java.util.function.Predicate; /** * System controlling all elevators of a building. @@ -39,11 +41,32 @@ 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"); + //System.out.println("Request for elevator received"); + Elevator elevatorToUse = elevators + .stream() + .sorted(getComparator(atFloor)) + .filter(getElevatorFilter(desiredTravelDirection)) + .findFirst() + .orElse(elevators + .stream() + .min(getComparator(atFloor)) + .orElseThrow(() -> new IllegalStateException("There are no Elevators"))); + + elevatorToUse.setTravelDirection(desiredTravelDirection); + + elevatorToUse.humansWaiting.add(atFloor); + } + + private Predicate getElevatorFilter(TravelDirection desiredTravelDirection) { + return (elevator1) -> elevator1.getTravelDirection().isEmpty() || elevator1.getTravelDirection().get() == desiredTravelDirection; + } + + private Comparator getComparator(int atFloor) { + return Comparator.comparingInt((ele) -> Math.abs(atFloor - ele.getCurrentFloor())); } public void moveOneFloor() { elevators.forEach(Elevator::moveOneFloor); - elevators.forEach(elevator -> elevatorListeners.forEach(listener -> listener.onElevatorArrivedAtFloor(elevator))); + elevatorListeners.forEach((human) -> elevators.forEach(human::onElevatorArrivedAtFloor)); } } diff --git a/Contest/Assignment/src/org/togetherjava/event/elevator/elevators/TravelDirection.java b/Contest/Assignment/src/org/togetherjava/event/elevator/elevators/TravelDirection.java index b1c01c0..779b505 100644 --- a/Contest/Assignment/src/org/togetherjava/event/elevator/elevators/TravelDirection.java +++ b/Contest/Assignment/src/org/togetherjava/event/elevator/elevators/TravelDirection.java @@ -2,5 +2,15 @@ public enum TravelDirection { UP, - DOWN, + DOWN; + + public static TravelDirection getTravelDirection(int startingFloor, int destinationFloor) { + if (startingFloor > destinationFloor) { + return DOWN; + } else if (startingFloor < destinationFloor) { + return UP; + } else { + return null; + } + } } 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..2d52ea0 100644 --- a/Contest/Assignment/src/org/togetherjava/event/elevator/humans/Human.java +++ b/Contest/Assignment/src/org/togetherjava/event/elevator/humans/Human.java @@ -2,6 +2,7 @@ import org.togetherjava.event.elevator.elevators.ElevatorPanel; import org.togetherjava.event.elevator.elevators.FloorPanelSystem; +import org.togetherjava.event.elevator.elevators.TravelDirection; import java.util.OptionalInt; import java.util.StringJoiner; @@ -14,7 +15,7 @@ * for example requesting an elevator, eventually entering and exiting them. */ public final class Human implements ElevatorListener { - private State currentState; + public State currentState; private final int startingFloor; private final int destinationFloor; /** @@ -60,7 +61,9 @@ 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"); + this.currentState = State.WAITING_FOR_ELEVATOR; + floorPanelSystem.requestElevator(this.startingFloor, TravelDirection.getTravelDirection(startingFloor, destinationFloor)); + //System.out.println("Ready-event received"); } @Override @@ -70,7 +73,24 @@ 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"); + if (this.currentState == State.WAITING_FOR_ELEVATOR && elevatorPanel.getCurrentFloor() == this.startingFloor && elevatorPanel.getWaitingHumans().contains(this.startingFloor)) { + this.currentState = State.TRAVELING_WITH_ELEVATOR; + + elevatorPanel.getWaitingHumans().remove(Integer.valueOf(this.startingFloor)); + elevatorPanel.getHumansInside().add(this.destinationFloor); + + this.currentEnteredElevatorId = elevatorPanel.getId(); + + //this line is completely useless but.... it wants me to use it so i guess im using it. + elevatorPanel.requestDestinationFloor(this.destinationFloor); + + } else if (this.currentState == State.TRAVELING_WITH_ELEVATOR && this.currentEnteredElevatorId != null && this.currentEnteredElevatorId == elevatorPanel.getId() && elevatorPanel.getCurrentFloor() == this.destinationFloor) { + this.currentState = State.ARRIVED; + this.currentEnteredElevatorId = null; + + elevatorPanel.getHumansInside().remove(Integer.valueOf(this.destinationFloor)); + } + //System.out.println("Arrived-event received"); } public OptionalInt getCurrentEnteredElevatorId() {