Created
August 2, 2019 14:49
-
-
Save cahilfoley/e360d4f6feab499b284ea10b0f1386fa to your computer and use it in GitHub Desktop.
Elevator Saga
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
init: function(elevators, floors) { | |
const priorities = { | |
CAPACITY: 'CAPACITY', | |
DISTANCE: 'DISTANCE', | |
WAITING: 'WAITING' | |
} | |
const priority = priorities.DISTANCE | |
const needsPickup = floors.reduce((acc, floor) => { | |
acc[floor.floorNum()] = { | |
waiting: 0, | |
lastVisit: Date.now() | |
} | |
return acc | |
}, {}) | |
function pickNextFloor(currentFloor = 0) { | |
return (floors | |
.map(floor => { | |
const floorNum = floor.floorNum() | |
return { | |
floor: floorNum, | |
distance: Math.abs(currentFloor - floorNum), | |
numWaiting: needsPickup[floorNum].waiting, | |
lastVisit: needsPickup[floorNum].lastVisit | |
} | |
}) | |
.filter(floor => floor.numWaiting > 0) | |
.sort((a, b) => { | |
switch (priority) { | |
case priorities.CAPACITY: | |
return a.numWaiting - b.numWaiting | |
case priorities.WAITING: | |
return a.lastVisit - b.lastVisit | |
case priorities.DISTANCE: | |
return a.distance - b.distance | |
default: | |
return (a.waiting + a.distance) - (b.waiting + b.distance) | |
} | |
})[0] || {}).floor | |
} | |
function queueFloor(floorNum) { | |
needsPickup[floorNum].waiting++ | |
console.log('queueFloor', floorNum, needsPickup) | |
elevators.forEach(elevator => elevator.processQueue()) | |
} | |
elevators.forEach(elevator => { | |
elevator.processQueue = function() { | |
console.log('processing queue', elevator) | |
if (elevator.destinationQueue.length === 0) { | |
const nextStop = pickNextFloor(elevator.currentFloor()) | |
if (typeof nextStop === 'number') elevator.goToFloor(nextStop) | |
} | |
} | |
elevator.on('stopped_at_floor', floorNumber => { | |
needsPickup[floorNumber].waiting = 0 | |
needsPickup[floorNumber].lastVisit = Date.now() | |
elevator.destinationQueue = elevator.destinationQueue.filter(stop => stop !== floorNumber) | |
const floorDistances = elevator.destinationQueue.map(floor => { | |
return { | |
floor, | |
distance: Math.abs(floorNumber - floor), | |
numWaiting: needsPickup[floor].waiting, | |
lastVisit: needsPickup[floor].lastVisit | |
} | |
}) | |
elevator.destinationQueue = floorDistances | |
.sort((a, b) => { | |
switch (priority) { | |
case priorities.CAPACITY: | |
return a.numWaiting - b.numWaiting | |
case priorities.WAITING: | |
return a.lastVisit - b.lastVisit | |
case priorities.DISTANCE: | |
return a.distance - b.distance | |
default: | |
return (a.waiting + a.distance) - (b.waiting + b.distance) | |
} | |
}) | |
.map(({ floor }) => floor) | |
elevator.checkDestinationQueue() | |
elevator.processQueue() | |
}) | |
elevator.on('floor_button_pressed', elevator.goToFloor) | |
}) | |
floors.forEach(floor => { | |
const queueThisFloor = () => queueFloor(floor.floorNum()) | |
floor.on('up_button_pressed', queueThisFloor) | |
floor.on('down_button_pressed', queueThisFloor) | |
}) | |
}, | |
update: function(dt, elevators, floors) { | |
// We normally don't need to do anything here | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment