Last active
April 14, 2025 11:53
-
-
Save typhoon2099/a7dd0730b000c2d315d1fc620a0ed6d2 to your computer and use it in GitHub Desktop.
Elevator Saga
This file contains hidden or 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) { | |
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