Skip to content

Instantly share code, notes, and snippets.

@garyjoy
Created October 24, 2019 16:28
Show Gist options
  • Save garyjoy/bffd18084dfbd5d118cb9268fc03f36e to your computer and use it in GitHub Desktop.
Save garyjoy/bffd18084dfbd5d118cb9268fc03f36e to your computer and use it in GitHub Desktop.
Elevator Saga 02 - Getting better...
{
init: function(elevators, floors) {
console.clear()
const DO_NOT_STOP_THRESHOLD = 0.7
var floorsWaitingForUp = new Set()
var floorsWaitingForDown = new Set()
// TODO: You might consider making this a function of an Elevator object...
function refreshElevatorIndicator(elevator) {
var direction = directionOfNextStop(elevator)
if (direction == "up") {
goingUp(elevator)
}
else if (direction == "down") {
goingDown(elevator)
}
else if (elevator.currentFloor() === 0) {
goingUp(elevator)
}
else if (elevator.currentFloor() === floors.length - 1) {
goingDown(elevator)
}
else {
idle(elevator)
}
}
// TODO: You also might consider making these functions of an Elevator object...
function goingDown(elevator) {
elevator.goingUpIndicator(false)
elevator.goingDownIndicator(true)
console.debug(elevator.name + " is going down", elevator.destinationQueue)
}
function goingUp(elevator) {
elevator.goingUpIndicator(true)
elevator.goingDownIndicator(false)
console.debug(elevator.name + " is going up", elevator.destinationQueue)
}
function idle(elevator) {
elevator.goingUpIndicator(true)
elevator.goingDownIndicator(true)
console.debug(elevator.name + " is idle", elevator.destinationQueue)
}
// TODO: You might also want consider making this a function of an Elevator object...
function directionOfNextStop(elevator) {
if (elevator.destinationQueue.length === 0 || elevator.destinationQueue[0] === elevator.currentFloor()) {
return "stopped"
}
else if (elevator.destinationQueue[0] > elevator.currentFloor()) {
return "up"
}
else if (elevator.destinationQueue[0] < elevator.currentFloor()) {
return "down"
}
else {
console.warn("directionOfNextStop() isn't working how you expect it to...", elevator)
}
}
// TODO: You might also want consider making this a function of an Elevator object...
function smartGoToFloor(elevator, targetFloor) {
var startingDirection = directionOfNextStop(elevator)
// NOTE: There's an implicit expectation here that people will pay attention to the Elevator Indicators...
if (startingDirection === "stopped") {
elevator.goToFloor(targetFloor)
}
else if (startingDirection === "up") {
var insertBeforeIndex = 0;
while (insertBeforeIndex < elevator.destinationQueue.length && elevator.destinationQueue[insertBeforeIndex] < targetFloor) {++insertBeforeIndex}
elevator.destinationQueue.splice(insertBeforeIndex, 0, targetFloor)
elevator.checkDestinationQueue();
}
else if (startingDirection === "down") {
var insertBeforeIndex = 0;
while (insertBeforeIndex < elevator.destinationQueue.length && elevator.destinationQueue[insertBeforeIndex] > targetFloor) {++insertBeforeIndex}
elevator.destinationQueue.splice(insertBeforeIndex, 0, targetFloor)
elevator.checkDestinationQueue();
}
else {
console.warn("smartGoToFloor() isn't working how you expect it to...", elevator, targetFloor)
}
console.debug("Queue Updated for " + elevator.name, elevator.destinationQueue)
}
console.debug("Number of Floors = " + floors.length)
floors.forEach(floor => {
floor.on("up_button_pressed", function() {
floorsWaitingForUp.add(floor.floorNum())
console.debug("Up Call from Floor " + floor.floorNum(), floorsWaitingForUp)
})
floor.on("down_button_pressed", function() {
floorsWaitingForDown.add(floor.floorNum())
console.debug("Down Call from Floor " + floor.floorNum(), floorsWaitingForDown)
})
})
console.debug("Number of Elevators = " + elevators.length)
elevators.forEach(function (elevator, index) {
elevator.name = "Elevator " + (index + 1)
console.debug("Initial Queue for " + elevator.name, elevator.destinationQueue)
elevator.on("floor_button_pressed", function(floorNum) {
console.debug(elevator.name + " sent to Floor " + floorNum + " from " + elevator.currentFloor())
smartGoToFloor(elevator, floorNum)
refreshElevatorIndicator(elevator)
})
elevator.on("stopped_at_floor", function(floorNum) {
// TODO: floorsWaitingForUp/floorsWaitingForDown should be updated here because people will get in if the direction of travel is correct...
console.debug(elevator.name + " stopped at " + floorNum, elevator.destinationQueue)
refreshElevatorIndicator(elevator)
})
elevator.on("passing_floor", function(floorNum, direction) {
console.debug(elevator.name + " passing " + floorNum + " moving " + direction)
if (elevator.loadFactor() < DO_NOT_STOP_THRESHOLD) {
if (direction === "up" && floorsWaitingForUp.has(floorNum)) {
elevator.goToFloor(floorNum, true)
floorsWaitingForUp.delete(floorNum)
console.debug("Queue Updated for " + elevator.name, elevator.destinationQueue)
}
if (direction === "down" && floorsWaitingForDown.has(floorNum)) {
elevator.goToFloor(floorNum, true)
floorsWaitingForDown.delete(floorNum)
console.debug("Queue Updated for " + elevator.name, elevator.destinationQueue)
}
}
})
elevator.on("idle", function() {
console.debug(elevator.name + " was idle", elevator.destinationQueue)
// TODO: Don't priorise Up over Down...
if (floorsWaitingForUp.size > 0) {
let floorNum = floorsWaitingForUp.values().next().value
elevator.goToFloor(floorNum)
floorsWaitingForUp.delete(floorNum)
console.debug("Queue Updated for " + elevator.name, elevator.destinationQueue)
}
else if (floorsWaitingForDown.size > 0) {
let floorNum = floorsWaitingForDown.values().next().value
elevator.goToFloor(floorNum)
floorsWaitingForDown.delete(floorNum)
console.debug("Queue Updated for " + elevator.name, elevator.destinationQueue)
}
});
})
},
update: function(dt, elevators, floors) {
}
}
@garyjoy
Copy link
Author

garyjoy commented Oct 24, 2019

This is what I ended up with after about an hour. It will pass many of the challenges but there is still room for improvement...

  • Idle Elevators only look for work at the moment when they become Idle (then they sit and wait for a passenger on the current floor)
  • Idle Elevators should be smarter about work selection (e.g. an Idle Elevator on the (n-1)th floor should favour a waiting passenger from the nth floor rather than going back to the ground floor - subject to passenger wait times)

Points of note...

  • I gave Elevators names to help support...
  • Extensive logging to help debug and improve
  • Additional data structures (Sets) are used

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment