Skip to content

Instantly share code, notes, and snippets.

@typhoon2099
Last active April 14, 2025 11:53
Show Gist options
  • Save typhoon2099/a7dd0730b000c2d315d1fc620a0ed6d2 to your computer and use it in GitHub Desktop.
Save typhoon2099/a7dd0730b000c2d315d1fc620a0ed6d2 to your computer and use it in GitHub Desktop.
Elevator Saga
{
init: function(elevators, floors) {
console.log("START");
const upIndicators = new Set();
const downIndicators = new Set();
// TODO: Let the floor button presses control the elevator queues (big rewrite)
const TOP_FLOOR_NUM = floors.length - 1;
const goingUp = floors => floors.filter(floor => floor.buttonStates.up === "activated");
const goingDown = floors => floors.filter(floor => floor.buttonStates.down === "activated");
const idleElevators = elevators => {
return elevators.filter(elevator => elevator.destinationQueue.length === 0);
};
const emptyElevators = elevators => {
return elevators.filter(elevator => elevator.loadFactor() === 0);
};
const setIndicators = (elevator, floorNum) => {
elevator.goingDownIndicator(elevator.currentFloor() >= floorNum);
elevator.goingUpIndicator(elevator.currentFloor() <= floorNum);
}
const currentDestinations = elevators => {
return elevators.map(elevator => elevator.destinationQueue[0]).filter(floor => floor !== undefined);
};
elevators.forEach((elevator, index) => {
elevator.on('idle', () => {
console.log('idle');
const up = goingUp(floors).map(floor => floor.floorNum());
up.sort();
//console.log('up', up)
if (up.length && up[0] !== elevator.currentFloor()) {
elevator.goToFloor(up[0]);
elevator.goingUpIndicator(true);
elevator.goingDownIndicator(false);
return;
}
const down = goingDown(floors).map(floor => floor.floorNum());
down.sort();
down.reverse();
//console.log('down', down);
if (down.length && down[0] !== elevator.currentFloor()) {
elevator.goToFloor(down[0]);
elevator.goingUpIndicator(false);
elevator.goingDownIndicator(true);
return;
}
});
elevator.on('stopped_at_floor', floorNum => {
// TODO: Clear indicators
if (floorNum === TOP_FLOOR_NUM) {
elevator.goingUpIndicator(false);
elevator.goingDownIndicator(true);
return;
}
if (floorNum === 0) {
elevator.goingUpIndicator(true);
elevator.goingDownIndicator(false);
return;
}
if (elevator.destinationQueue[0]) {
setIndicators(elevator, elevator.destinationQueue[0]);
return;
}
});
elevator.on("floor_button_pressed", floorNum => {
// TODO: Remove floors with no indicators on OR hasn't been pressed
console.log('floor_button_pressed', floorNum);
if (elevator.goingUpIndicator()) {
elevator.destinationQueue = [...new Set(elevator.getPressedFloors(), goingUp(floors).map(floor => floor.floorNum()))];
elevator.destinationQueue.sort();
}
if (elevator.goingDownIndicator()) {
elevator.destinationQueue = [...new Set(elevator.getPressedFloors(), goingDown(floors).map(floor => floor.floorNum()))];
elevator.destinationQueue.reverse();
elevator.destinationQueue.sort();
}
elevator.checkDestinationQueue();
setIndicators(elevator, elevator.destinationQueue[0]);
});
elevator.on("passing_floor", (floorNum, direction) => {
// TODO: Skip the floor if there's nobody there, and the button isn't pressed
if(elevator.loadFactor() > ((elevator.maxPassengerCount() - 1) /elevator.maxPassengerCount())) { return }
if (direction === "up" && elevator.goingUpIndicator()) {
const floorToStopOn = goingUp(floors).find(floor => floor.floorNum() === floorNum);
if (floorToStopOn) {
elevator.goToFloor(floorToStopOn.floorNum(), true);
}
}
if (direction === "down" && elevator.goingDownIndicator()) {
const floorToStopOn = goingDown(floors).find(floor => floor.floorNum() === floorNum);
if (floorToStopOn) {
elevator.goToFloor(floorToStopOn.floorNum(), true);
}
}
});
});
floors.forEach(floor => {
floor.on("up_button_pressed", function() {
console.log('up_button_pressed', floor.floorNum(), currentDestinations(elevators));
if (currentDestinations(elevators).includes(floor.floorNum())) { return }
console.log('looking for an elevator');
upIndicators.add(floor.floorNum());
console.log(upIndicators);
const candidates = idleElevators(emptyElevators(elevators));
if (candidates.length) {
console.log('Found one', candidates.length);
candidates[0].goToFloor(floor.floorNum());
candidates[0].goingUpIndicator(true);
candidates[0].goingDownIndicator(false);
}
});
floor.on("down_button_pressed", function() {
console.log('down_button_pressed', floor.floorNum(), currentDestinations(elevators));
if (currentDestinations(elevators).includes(floor.floorNum())) { return }
console.log('looking for an elevator');
downIndicators.add(floor.floorNum());
console.log(downIndicators);
const candidates = idleElevators(emptyElevators(elevators));
if (candidates.length) {
console.log('Found one', candidates.length);
candidates[0].goToFloor(floor.floorNum());
candidates[0].goingUpIndicator(false);
candidates[0].goingDownIndicator(true);
}
});
});
},
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