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

@ -1,25 +1,46 @@
package lift; package lift;
class Door { class Door {
private boolean open; private boolean open;
private int passengersEntering;
private int passengersExiting;
/** Create a new closed door */ /** Create a new closed door */
public Door() { public Door() {
open = false; open = false;
} passengersEntering = 0;
passengersExiting = 0;
}
/** Returns true if door is open */ /** Returns true if door is open */
public boolean isOpen() { public boolean isOpen() {
return open; return open;
} }
/** Open the door */ /** Open the door */
public void open() { public void open() {
open = true; open = true;
} }
/** Close the 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;
}
/** Close the door */
public void close() {
open = false;
}
} }

View file

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

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();
}
}