Skip to content

Instantly share code, notes, and snippets.

@onlyurei
Last active August 5, 2021 21:17
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save onlyurei/caf98978cd7bf8e64198 to your computer and use it in GitHub Desktop.
Save onlyurei/caf98978cd7bf8e64198 to your computer and use it in GitHub Desktop.
Solution for Elevator Saga game (http://www.elevatorsaga.com)
{
init: function (elevators, floors) {
function queueDestinationForElevator(elevator, floorNum) {
if (elevator.destinationQueue.length) {
if (isElevatorGoingUp(elevator)) {
if (floorNum < elevator.destinationQueue[0]) {
if (elevator.currentFloor() < floorNum) {
elevator.destinationQueue.splice(0, 0, floorNum);
} else {
elevator.destinationQueue.push(floorNum);
}
} else if (floorNum > elevator.destinationQueue[elevator.destinationQueue.length - 1]) {
elevator.destinationQueue.push(floorNum);
} else {
for (var i = 0; i < (elevator.destinationQueue.length - 1); i++) {
if ((floorNum >= elevator.destinationQueue[i]) && (floorNum <= elevator.destinationQueue[i + 1])) {
elevator.destinationQueue.splice(i + 1, 0, floorNum);
break;
}
}
}
} else {
if (floorNum > elevator.destinationQueue[0]) {
if (elevator.currentFloor() > floorNum) {
elevator.destinationQueue.splice(0, 0, floorNum);
} else {
elevator.destinationQueue.push(floorNum);
}
} else if (floorNum < elevator.destinationQueue[elevator.destinationQueue.length - 1]) {
elevator.destinationQueue.push(floorNum);
} else {
for (var i = 0; i < (elevator.destinationQueue.length - 1); i++) {
if ((floorNum <= elevator.destinationQueue[i]) && (floorNum >= elevator.destinationQueue[i + 1])) {
elevator.destinationQueue.splice(i + 1, 0, floorNum);
break;
}
}
}
}
elevator.checkDestinationQueue();
} else {
elevator.goToFloor(floorNum);
}
}
function isElevatorGoingUp(elevator) {
return !elevator.destinationQueue.length || (elevator.currentFloor() < elevator.destinationQueue[0]);
}
function isElevatorGoingDown(elevator) {
return !elevator.destinationQueue.length || (elevator.currentFloor() > elevator.destinationQueue[0]);
}
function isFloorPickupableForElevator(elevator, floorNum) {
return !elevator.destinationQueue.length
|| (isElevatorGoingUp(elevator) && (elevator.currentFloor() < floorNum))
|| (isElevatorGoingDown(elevator) && (elevator.currentFloor() > floorNum));
}
function scheduleElevatorForFloorButtonEvent(floor, isGoingUp) {
var candidate = null;
elevators.forEach(function (elevator) {
if ((elevator.loadFactor() < 1) || (elevator.destinationQueue[0] == floor.floorNum())) {
if (candidate) {
candidate.floorDiff = Math.abs(candidate.currentFloor() - floor.floorNum());
elevator.floorDiff = Math.abs(elevator.currentFloor() - floor.floorNum());
if (!elevator.destinationQueue.length) {
if (!candidate.destinationQueue.length) {
if ((elevator.floorDiff < candidate.floorDiff) || ((elevator.floorDiff == candidate.floorDiff) && (elevator.loadFactor() < candidate.loadFactor()))) {
candidate = elevator;
}
} else {
candidate = elevator;
}
} else {
if ((elevator.floorDiff < candidate.floorDiff) && (elevator.loadFactor() < candidate.loadFactor()) && ((isElevatorGoingUp(elevator) == isGoingUp) || (isElevatorGoingDown(elevator) != isGoingUp)) && isFloorPickupableForElevator(elevator, floor.floorNum())) {
candidate = elevator;
}
}
} else {
candidate = elevator;
}
}
});
if (candidate) {
queueDestinationForElevator(candidate, floor.floorNum());
} else {
elevators.sort(function (a, b) {
return (a.floorDiff < b.floorDiff) && (a.loadFactor() < b.loadFactor());
});
queueDestinationForElevator(elevators[0], floor.floorNum());
}
}
elevators.forEach(function (elevator) {
elevator.on('floor_button_pressed', function (floorNum) {
queueDestinationForElevator(elevator, floorNum);
});
elevator.on('stopped_at_floor', function (floorNum) {
elevator.destinationQueue.forEach(function (destination, index) {
if (destination == floorNum) {
elevator.destinationQueue.splice(index, 1);
}
});
});
});
floors.forEach(function (floor) {
floor.on('up_button_pressed', function () {
scheduleElevatorForFloorButtonEvent(floor, true);
});
floor.on('down_button_pressed', function () {
scheduleElevatorForFloorButtonEvent(floor, false);
});
});
},
update: function(dt, elevators, floors) {
// We normally don't need to do anything here
}
}
@axrwl
Copy link

axrwl commented Oct 19, 2016

Awesome
Could you provide one for every challenge.

@ens42
Copy link

ens42 commented May 17, 2017

Sometimes fails at challenge #5...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment