Lift better abstractions

This commit is contained in:
Imbus 2024-09-26 01:02:17 +02:00
parent 09cd85f364
commit 2c50014eaf
3 changed files with 103 additions and 39 deletions

View file

@ -2,10 +2,14 @@ package lift;
class Door {
private boolean open;
private int passengersEntering;
private int passengersExiting;
/** Create a new closed door */
public Door() {
open = false;
passengersEntering = 0;
passengersExiting = 0;
}
/** Returns true if door is open */
@ -22,4 +26,21 @@ class Door {
public void close() {
open = false;
}
public int getEntering() {
return passengersEntering;
}
public void setEntering(int passengers) {
this.passengersEntering = passengers;
}
public int getExiting() {
return passengersExiting;
}
public void setExiting(int passengers) {
this.passengersExiting = passengers;
}
}

View file

@ -18,9 +18,9 @@ public class LiftMonitor {
/** Current direction of the lift */
private Direction direction;
/** number of passengers waiting to enter the lift at the various floors */
private int[] waitEntry;
// private int[] waitEntry;
/** number of passengers (in lift) waiting to leave at the various floors */
private int[] waitExit;
// private int[] waitExit;
/** number of passengers currently in the lift */
private int load;
/** view object passed from main */
@ -32,6 +32,9 @@ public class LiftMonitor {
/** Counter of number of passengers currently exiting the elevator */
private int passengersExiting;
private PassengerQueue waitEntry;
private PassengerQueue waitExit;
/** Create new LiftMonitor */
public LiftMonitor(LiftView v, int floors) {
floor = 0;
@ -39,8 +42,8 @@ public class LiftMonitor {
moving = true;
direction = Direction.UP;
door = new Door();
waitEntry = new int[nfloors];
waitExit = new int[nfloors];
waitEntry = new PassengerQueue(nfloors);
waitExit = new PassengerQueue(nfloors);
load = 0;
view = v;
passengersEntering = 0;
@ -49,7 +52,7 @@ public class LiftMonitor {
/** Increases the number of waiting passengers on given floor */
public synchronized void increaseWaitEntry(int passengerFloor) {
waitEntry[passengerFloor]++;
waitEntry.inc(passengerFloor);
notifyAll();
}
@ -64,8 +67,9 @@ public class LiftMonitor {
throw new Error("Monitor.enterLift interrupted " + e);
}
}
waitEntry[floor]--;
waitExit[passengerDestination]++;
waitEntry.dec(floor);
waitExit.inc(passengerDestination);
load++;
passengersEntering++;
notifyAll();
@ -86,7 +90,7 @@ public class LiftMonitor {
throw new Error("Monitor.exitLift interrupted " + e);
}
}
waitExit[passengerDestination]--;
waitExit.dec(passengerDestination);
load--;
passengersExiting++;
notifyAll();
@ -104,9 +108,7 @@ public class LiftMonitor {
* on any floor.
*/
public synchronized int[] liftContinue() {
while (Arrays.stream(waitEntry).sum() == 0 &&
Arrays.stream(waitExit).sum() == 0) {
while (waitEntry.isEmpty() && waitExit.isEmpty()) {
try {
wait();
} catch (InterruptedException e) {
@ -115,7 +117,7 @@ public class LiftMonitor {
}
/** Stops the elevator to allow passengers to enter or exit */
while (waitEntry[floor] > 0 && load != 4 || waitExit[floor] > 0 ||
while (waitEntry.get(floor) > 0 && load != 4 || waitExit.get(floor) > 0 ||
passengersEntering > 0 || passengersExiting > 0) {
if (!door.isOpen()) {
view.openDoors(floor);
@ -160,16 +162,13 @@ public class LiftMonitor {
* to enter or exit on floors either above or below the elevator
*/
private void calculateDirection() {
if (Arrays.stream(waitEntry, floor, nfloors).sum() == 0 &&
Arrays.stream(waitExit, floor, nfloors).sum() == 0 && floor != 0) {
direction = Direction.DOWN;
} else if (Arrays.stream(waitEntry, 0, floor + 1).sum() == 0 &&
Arrays.stream(waitExit, 0, floor + 1).sum() == 0 && floor != 6) {
direction = Direction.UP;
} else if (floor == nfloors - 1) {
direction = Direction.DOWN;
} else if (floor == 0) {
direction = Direction.UP;
boolean noPassengersAbove = (waitEntry.totalAbove(floor) == 0 && waitExit.totalAbove(floor) == 0);
boolean noPassengersBelow = (waitEntry.totalBelow(floor) == 0 && waitExit.totalBelow(floor) == 0);
if (floor == 0 || noPassengersBelow) {
direction = Direction.UP; // Always go up if at ground floor or no passengers below
} else if (floor == nfloors - 1 || noPassengersAbove) {
direction = Direction.DOWN; // Always go down if at the top floor or no passengers above
}
}
}

View file

@ -0,0 +1,44 @@
package lift;
import java.util.Arrays;
public class PassengerQueue {
private int[] waitRecord;
public PassengerQueue(int nfloors) {
this.waitRecord = new int[nfloors];
}
public void inc(int floor) {
this.waitRecord[floor]++;
}
public void dec(int floor) {
this.waitRecord[floor]--;
}
public int get(int floor) {
return this.waitRecord[floor];
}
public void set(int floor, int value) {
this.waitRecord[floor] = value;
}
public int total() {
return Arrays.stream(this.waitRecord).sum();
}
public boolean isEmpty() {
return this.total() == 0;
}
public int totalBelow(int floor) {
return Arrays.stream(this.waitRecord).limit(floor).sum();
}
public int totalAbove(int floor) {
return Arrays.stream(this.waitRecord).skip(floor + 1).sum();
}
}