Last active
October 20, 2022 15:27
-
-
Save adamduren/c698ac45d9ff466c19145e006c4b0d73 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 DIR_UP = 'up'; | |
const DIR_DOWN = 'down'; | |
const pendingPickupDirectionDownFloors = new Set(); | |
const pendingPickupDirectionUpFloors = new Set(); | |
const buttonPressedHandlerFactory = (floor, direction) => () => { | |
console.log(`Button pressed on floor ${floor.floorNum()} going ${direction}`); | |
// If there is already an elevator on the floor, we don't need to do anything | |
if (elevators.some(elevator => elevator.currentFloor() === floor.floorNum())) { | |
console.log(`Elevator already on floor ${floor.floorNum()}`); | |
return; | |
} | |
// If an elevator is idle, we can just send it to the floor | |
for (const elevator of elevators) { | |
console.log(floor.floorNum(), direction, elevator.destinationQueue); | |
if (elevator.destinationQueue.length === 0) { | |
elevator.goToFloor(floor.floorNum()); | |
if (direction === DIR_DOWN) { | |
elevator.goingUpIndicator(true); | |
} else { | |
elevator.goingDownIndicator(true); | |
} | |
return; | |
} | |
} | |
// Otherwise, we need to add the floor to the pending pickup list | |
if (direction === DIR_UP) { | |
pendingPickupDirectionUpFloors.add(floor.floorNum()); | |
} else { | |
pendingPickupDirectionDownFloors.add(floor.floorNum()); | |
} | |
}; | |
const handlePassingFloorFactory = (elevator) => (floorNum, direction) => { | |
console.log('Passing floor', floorNum, direction); | |
const pendingPickupFloors = direction === DIR_UP ? pendingPickupDirectionUpFloors : pendingPickupDirectionDownFloors; | |
if (pendingPickupFloors.has(floorNum)) { | |
elevator.goToFloor(floorNum, true); | |
pendingPickupFloors.delete(floorNum); | |
// Remove floor if already in queue | |
const nextQueue = elevator.destinationQueue.filter((dest) => dest !== floorNum); | |
elevator.destinationQueue = nextQueue; | |
elevator.checkDestinationQueue(); | |
} | |
}; | |
const handleFloorButtonPressedFactory = (elevator) => (floorNum) => { | |
console.log('Floor button pressed', floorNum); | |
elevator.goToFloor(floorNum); | |
}; | |
const handleElevatorIdleFactory = (elevator) => () => { | |
console.log('Elevator idle'); | |
// Find next pickup floor | |
if (pendingPickupDirectionUpFloors.size > 0) { | |
const nextFloor = Math.min(...pendingPickupDirectionUpFloors); | |
elevator.goToFloor(nextFloor); | |
pendingPickupDirectionUpFloors.delete(nextFloor); | |
elevator.goingUpIndicator(true); | |
elevator.goingDownIndicator(false); | |
} else if (pendingPickupDirectionDownFloors.size > 0) { | |
const nextFloor = Math.max(...pendingPickupDirectionDownFloors); | |
elevator.goToFloor(nextFloor); | |
pendingPickupDirectionDownFloors.delete(nextFloor); | |
elevator.goingUpIndicator(false); | |
elevator.goingDownIndicator(true); | |
} | |
}; | |
// Give all the elevators the same config | |
for (const elevator of elevators) { | |
// Whenever the elevator is idle (has no more queued destinations) ... | |
elevator.on('idle', handleElevatorIdleFactory(elevator)); | |
elevator.on('floor_button_pressed', handleFloorButtonPressedFactory(elevator)) | |
elevator.on('passing_floor', handlePassingFloorFactory(elevator)); | |
} | |
for (const floor of floors) { | |
// Add to queue pickup queue when a button is pressed | |
floor.on('up_button_pressed', buttonPressedHandlerFactory(floor, DIR_UP)); | |
floor.on('down_button_pressed', buttonPressedHandlerFactory(floor, DIR_DOWN)); | |
} | |
}, | |
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