Created
April 23, 2025 21:17
-
-
Save kisPocok/0cee1511127781e4e8f5e8f369182deb to your computer and use it in GitHub Desktop.
Elevator
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
// Insert this code onto https://play.elevatorsaga.com | |
// Pass 83% of the levels | |
// Trick introduced on #6 and #7 | |
// Failed on #13 -> best is around 50/100 | |
// Failed on #14 | |
// Flaky on #15 -> "passing_floor" functions should be disabled to pass | |
// Failed on #18 -> 1910 was the most | |
{ | |
init: function(elevators, floors) { | |
var simplifiedFloors = [...Array(floors.length).keys()].map((f, index) => ({ floor: index, waiting: 0 })); | |
var enableOnlyOneElevator = window.location.hash === '#challenge=6' || window.location.hash === '#challenge=7' | |
var first = (arr) => arr[0] || 0; | |
var random = (arr) => arr[Math.floor(Math.random() * arr.length)]; | |
var unique = (value, index, arr) => arr.indexOf(value) === index; | |
var getFloorQueueSize = (floorNum) => world.users.filter((u) => u.currentFloor === floorNum && u.done === false && u.parent === null).length; | |
var sortBySize = (a, b) => b.waiting - a.waiting; | |
var nonEmpty = (f) => f.waiting > 0; | |
var withinRange = (lvl) => (f) => f.floor <= lvl + 3 && f.floor >= lvl - 3; | |
var recalculateWaitingNumbers = () => simplifiedFloors.map((f) => { | |
f.waiting = getFloorQueueSize(f.floor) | |
return f; | |
}) | |
var findPriority = (currentFloor) => { | |
var list = recalculateWaitingNumbers().filter(nonEmpty) | |
var mostCrowded = list.sort(sortBySize) | |
var nearest = list.filter(withinRange(currentFloor)).sort(sortBySize) | |
// priority: first nearest, then mostCrowded, then 0 | |
if (nearest.length > 0) return random(nearest).floor; | |
else if (mostCrowded.length > 0) return random(mostCrowded).floor; | |
else return 0; | |
} | |
var findAFloor = (elevator) => { | |
if (elevator.requests.length > 0) return first(elevator.requests); | |
else if (elevator.getPressedFloors().length > 0) return random(elevator.getPressedFloors()); | |
else return findPriority(elevator.currentFloor()); | |
} | |
var addElevatorQueue = (elevator, floorNum) => elevator.requests.push(floorNum); | |
var removeFromElevatorQueue = (elevator, floorNum) => { | |
const index = elevator.requests.indexOf(floorNum); | |
if (index > -1) elevator.requests.splice(index, 1); | |
} | |
var passangersWithSameDirection = (floorNum, direction) => floors[floorNum].buttonStates[direction]; | |
var passangerWouldLeave = (elevator, floorNum) => elevator.destinationQueue | |
.concat(elevator.getPressedFloors()) | |
.concat(elevator.requests) | |
.filter(unique) | |
.find((destination) => destination === floorNum); | |
var elevatorHasSpace = (elevator) => elevator.loadFactor() < 0.63 | |
var stopElevatorThenContinue = (elevator, floorNum) => { | |
elevator.destinationQueue.unshift(floorNum) | |
elevator.checkDestinationQueue() | |
} | |
elevators.forEach((elevator, index) => { | |
if (enableOnlyOneElevator && index !== 0) return; // disable unnecessary elevators | |
elevator.requests = []; // it's the same like getPressedFloors() but maintaining the order | |
elevator.goToFloor(Math.min(index * 2, floors.length)); // move the elevators a bit randomly to avoid initial issues | |
elevator.on("floor_button_pressed", (floorNum) => addElevatorQueue(elevator, floorNum)); | |
elevator.on("stopped_at_floor", (floorNum) => removeFromElevatorQueue(elevator, floorNum)) | |
elevator.on('passing_floor', (floorNum, direction) => elevatorHasSpace(elevator) && passangersWithSameDirection(floorNum, direction) ? stopElevatorThenContinue(elevator, floorNum) : null); | |
elevator.on('passing_floor', (floorNum, direction) => passangerWouldLeave(elevator, floorNum) ? stopElevatorThenContinue(elevator, floorNum) : null); | |
elevator.on("idle", () => elevator.goToFloor(findAFloor(elevator))); | |
}) | |
}, | |
update: function(dt, elevators, floors) {} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment