Skip to content

Commit

Permalink
Submission
Browse files Browse the repository at this point in the history
  • Loading branch information
Zabuzard committed Aug 15, 2022
1 parent 3021c60 commit bf989af
Show file tree
Hide file tree
Showing 9 changed files with 143 additions and 26 deletions.
16 changes: 7 additions & 9 deletions Contest/Assignment/src/org/togetherjava/event/elevator/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,19 @@ public static void main(final String[] args) {
// 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.createSimpleSimulation();
// Simulation simulation = Simulation.createRandomSimulation(5, 50, 10);
// Simulation simulation = Simulation.createRandomSimulation(putDesiredSeedHere, 5, 50, 10);

simulation.printSummary();
//Simulation simulation = Simulation.createSingleElevatorSingleHumanSimulation();
//Simulation simulation = Simulation.createSimpleSimulation();
//Simulation simulation = Simulation.createRandomSimulation(6, 1, 3, 10);
Simulation simulation = Simulation.createRandomSimulation(4, 12, 1000, 23);

System.out.println("Starting simulation...");
simulation.start();
simulation.prettyPrint();
//simulation.prettyPrint();

while (!simulation.isDone()) {
System.out.println("\tSimulation step " + simulation.getStepCount());
//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"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.togetherjava.event.elevator.elevators;

import java.util.StringJoiner;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
Expand All @@ -16,6 +16,9 @@ public final class Elevator implements ElevatorPanel {
private final int minFloor;
private final int floorsServed;
private int currentFloor;
public List<Integer> humansInside = new ArrayList<>();
public List<Integer> humansWaiting = new ArrayList<>();
private TravelDirection travelDirection;

/**
* Creates a new elevator.
Expand All @@ -39,6 +42,18 @@ public Elevator(int minFloor, int floorsServed, int currentFloor) {
this.floorsServed = floorsServed;
}

public Optional<TravelDirection> 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;
Expand All @@ -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<Integer> getWaitingHumans() {
return humansWaiting;
}

@Override
public List<Integer> getHumansInside() {
return humansInside;
}

public void moveOneFloor() {
Expand All @@ -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<Integer> getComparator() {
return Comparator.comparingInt((floorNumber) -> Math.abs(floorNumber - currentFloor));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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<Integer> getWaitingHumans();

List<Integer> getHumansInside();
}
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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<Elevator> getElevatorFilter(TravelDirection desiredTravelDirection) {
return (elevator1) -> elevator1.getTravelDirection().isEmpty() || elevator1.getTravelDirection().get() == desiredTravelDirection;
}

private Comparator<Elevator> 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));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ public interface FloorPanelSystem {
* @param atFloor the floor to pick up the human at, must be within the range served by the system
* @param desiredTravelDirection the direction the human wants to travel into,
* can be used for determination of the best elevator
* @apiNote This represents a human standing in the corridor, pressing a button on the wall,
* requesting that an elevator comes to pick them up for travel into the given direction.
*/
void requestElevator(int atFloor, TravelDirection desiredTravelDirection);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@ public interface ElevatorListener {
*
* @param elevatorPanel the system inside the elevator which provides information
* about the elevator and can be used to request a destination floor.
* @implNote The default implementation fires this event from all elevators to all humans, not only to humans that are
* relevant (i.e. humans that can enter the elevator).
*/
void onElevatorArrivedAtFloor(ElevatorPanel elevatorPanel);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
/**
Expand Down Expand Up @@ -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
Expand All @@ -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() {
Expand Down
8 changes: 4 additions & 4 deletions Contest/Assignment/test/SanityTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -110,15 +110,15 @@ private static void verifySnapshotSanity(SimulationSnapshot previousSnapshot,

// Only if the human actually travelled around
if (human.getStartingFloor() != human.getDestinationFloor()) {
assertEquals(Human.State.TRAVELING_WITH_ELEVATOR, previousState,
"When a human exits an elevator, their previous state must be traveling. But '%s' was in state %s.".formatted(
human, previousState));

OptionalInt maybeElevatorId = previousHumanSnapshot.currentElevatorId();
assertTrue(maybeElevatorId.isPresent(), ERROR_MESSAGE_PRE
+ "When a human exits an elevator, they must have had a current elevator id previously. But '%s' does not.".formatted(
human));

assertEquals(Human.State.TRAVELING_WITH_ELEVATOR, previousState,
"When a human exits an elevator, their previous state must be traveling. But '%s' was in state %s.".formatted(
human, previousState));

ElevatorSnapshot currentElevatorSnapshot =
currentSnapshot.getElevatorSnapshot(maybeElevatorId.orElseThrow());
assertEquals(human.getDestinationFloor(),
Expand Down

0 comments on commit bf989af

Please sign in to comment.