From 2c50014eaf51bced897837a6a1df83b1bc3eb9db Mon Sep 17 00:00:00 2001 From: Imbus <> Date: Thu, 26 Sep 2024 01:02:17 +0200 Subject: [PATCH] Lift better abstractions --- lift/src/lift/Door.java | 55 +++++++++++++++++++++---------- lift/src/lift/LiftMonitor.java | 43 ++++++++++++------------ lift/src/lift/PassengerQueue.java | 44 +++++++++++++++++++++++++ 3 files changed, 103 insertions(+), 39 deletions(-) create mode 100644 lift/src/lift/PassengerQueue.java diff --git a/lift/src/lift/Door.java b/lift/src/lift/Door.java index d7058cd..45c573f 100644 --- a/lift/src/lift/Door.java +++ b/lift/src/lift/Door.java @@ -1,25 +1,46 @@ package lift; class Door { - private boolean open; + private boolean open; + private int passengersEntering; + private int passengersExiting; - /** Create a new closed door */ - public Door() { - open = false; - } + /** Create a new closed door */ + public Door() { + open = false; + passengersEntering = 0; + passengersExiting = 0; + } - /** Returns true if door is open */ - public boolean isOpen() { - return open; - } + /** Returns true if door is open */ + public boolean isOpen() { + return open; + } - /** Open the door */ - public void open() { - open = true; - } + /** Open the door */ + public void open() { + 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; - } } \ No newline at end of file diff --git a/lift/src/lift/LiftMonitor.java b/lift/src/lift/LiftMonitor.java index 2cc02d9..9c87a8d 100644 --- a/lift/src/lift/LiftMonitor.java +++ b/lift/src/lift/LiftMonitor.java @@ -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 } } } diff --git a/lift/src/lift/PassengerQueue.java b/lift/src/lift/PassengerQueue.java new file mode 100644 index 0000000..b0fa1ef --- /dev/null +++ b/lift/src/lift/PassengerQueue.java @@ -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(); + } +} +