Skip to content

Instantly share code, notes, and snippets.

@gombosg
Created May 16, 2018 12:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gombosg/aadcfb4b2539c2ecb4788e8d1e7f32bf to your computer and use it in GitHub Desktop.
Save gombosg/aadcfb4b2539c2ecb4788e8d1e7f32bf to your computer and use it in GitHub Desktop.
My take on Elevator saga, completes until challenges 1-12 so far.
{
init: function(elevators, floors) {
// ----------------------------
// INIT
// ----------------------------
let myFloors = [];
initFloors();
// ----------------------------
// ELEVATOR CALLBACKS
// ----------------------------
for (var elevator of elevators) {
elevator.on("floor_button_pressed", function (floorNum) {
setIndicator(floorNum, this);
startElevator(this, floorNum);
});
elevator.on("stopped_at_floor", function (floorNum) {
cleanDestQueue(this);
// Remove this floor from destination queue
removeFromDestQueue(floorNum, this);
if (!this.destinationQueue.length) {
// Idle elevator
this.goingUpIndicator(true);
this.goingDownIndicator(true);
} else {
// Set indicator for next destination
setIndicator(this.destinationQueue[0], this);
}
this.goingUpIndicator() && resetFloor(floorNum, "up");
this.goingDownIndicator() && resetFloor(floorNum, "down");
});
elevator.on("passing_floor", function (floorNum, direction) {
if ((direction === "up" && myFloors[floorNum].up && hasFreeSpaceFor(this, 2)) ||
(direction === "down" && myFloors[floorNum].down && hasFreeSpaceFor(this, 2)) ||
this.destinationQueue.includes(floorNum)) {
removeFromDestQueue(floorNum, this);
startElevator(this, floorNum, true);
}
});
elevator.on("idle", function () {
console.log("Idle...");
// useLogic(this, lowestNotBookedFloor);
// useLogic(this, closestNotBookedFloor);
useLogic(this, longestWaitingFloor);
});
}
// ----------------------------
// CHALLENGE-SPECIFIC
// ----------------------------
// FOR CHALLENGE 10
// elevators[0].on("idle", function() {
// console.log("Idle...");
// useLogic(this, closestNotBookedFloor);
// });
// elevators[1].on("idle", function() {
// console.log("Idle...");
// useLogic(this, longestWaitingFloor);
// });
// CHALLENGE 12
// elevators[0].on("idle", function () {
// console.log("Idle...");
// useLogic(this, lowestNotBookedFloor);
// });
// elevators[1].on("idle", function () {
// console.log("Idle...");
// useLogic(this, highestNotBookedFloor);
// });
// ----------------------------
// LOGIC
// ----------------------------
function useLogic(elevator, fcn) {
let currentFloor = elevator.currentFloor();
fcn(currentFloor) !== null && startElevator(elevator, fcn(currentFloor));
}
function lowestNotBookedFloor() {
let ind = myFloors.findIndex((_,floorNum) => calledNotBooked(floorNum));
console.log("Lowest not booked: ", ind);
return ind === -1 ? null : ind;
}
function highestNotBookedFloor() {
let ind = myFloors.reverse().findIndex((_,floorNum) => calledNotBooked(floorNum));
console.log("Lowest not booked: ", ind);
return ind === -1 ? null : myFloors.length - 1 - ind;
}
function closestNotBookedFloor(currentFloor) {
let limit = (arr, val) => {
val = Math.min(val, arr.length - 1);
val = Math.max(val, 0);
return val;
}
let r = 1;
while (r < floors.length) {
let result;
let plusFloorNum = limit(floors, currentFloor + r);
let minusFloorNum = limit(floors, currentFloor - r);
if (calledNotBooked(plusFloorNum))
result = plusFloorNum;
if (calledNotBooked(minusFloorNum))
result = minusFloorNum;
if (result) {
console.log("Closest not booked: ", result);
return result;
}
r++;
}
console.log("Closest not booked not found");
return null;
}
function longestWaitingFloor() {
let now = new Date();
let waiting = myFloors.map(val => (val.up && val.down && Math.min(val.up, val.down)) || val.up || val.down || Infinity);
let min = Math.min(...waiting);
let idx = min === Infinity ?
null :
waiting.findIndex(val => val == Math.min(...waiting));
console.log("Longest waiting: ", idx);
return idx === -1 ? null : idx;
}
// ----------------------------
// FLOOR CALLBACKS
// ----------------------------
for (var floor of floors) {
floor.on("up_button_pressed", function () {
myFloors[this.floorNum()].up = Date.now();
console.log("up", this.floorNum(), myFloors)
callIdleElevator(this.floorNum());
});
floor.on("down_button_pressed", function () {
myFloors[this.floorNum()].down = Date.now();
console.log("down", this.floorNum(), myFloors)
callIdleElevator(this.floorNum());
});
}
// ----------------------------
// HELPER FUNCTIONS
// ----------------------------
function isBooked(floorNum) {
return myFloors[floorNum].bookedUp || myFloors[floorNum].bookedDown;
}
function calledNotBooked(floorNum) {
return (myFloors[floorNum].up || myFloors[floorNum].down) && !isBooked(floorNum);
}
function initFloors() {
for (let floorNum in floors) {
myFloors[floorNum] = {};
resetFloor(floorNum, "up");
resetFloor(floorNum, "down");
}
}
function resetFloor(floorNum, direction) {
if (direction === "up") {
Object.assign(myFloors[floorNum], {
up: null,
bookedUp: false,
});
} else if (direction === "down") {
Object.assign(myFloors[floorNum], {
down: null,
bookedDown: false
});
}
}
function hasFreeSpaceFor(elevator, passNum) {
return elevator.loadFactor() <= (1 - passNum / elevator.maxPassengerCount());
}
function startElevator(elevator, floorNum, priority = false) {
console.log("Start: ", floorNum);
if (!elevator.destinationQueue.includes(floorNum)) {
if (myFloors[floorNum].up && elevator.goingUpIndicator()) myFloors[floorNum].bookedUp = true;
if (myFloors[floorNum].down && elevator.goingDownIndicator()) myFloors[floorNum].bookedDown = true;
elevator.goToFloor(floorNum, priority);
}
}
function callIdleElevator(floorNum) {
for (var idx in elevators) {
let elevator = elevators[idx];
// if (elevator.destinationDirection() === "stopped" && !floors[floorNum].booked()) {
console.log("Dest queue: ", elevator.destinationQueue);
if (!elevator.destinationQueue.length && !isBooked(floorNum)) {
console.log("Call idle to floor: ", floorNum, "elevator: ", idx);
startElevator(elevator, floorNum);
// Only call 1 elevator!
return;
// useLogic(elevator, longestWaitingFloor);
}
}
}
function cleanDestQueue(elevator) {
elevator.destinationQueue = elevator.destinationQueue.filter(item => (myFloors[item].up || myFloors[item].down || elevator.getPressedFloors().includes(item)));
}
function removeFromDestQueue(floor, elevator) {
elevator.destinationQueue = elevator.destinationQueue.filter(x => x != floor);
}
function setIndicator(floorNum, elevator) {
var up = (floorNum > elevator.currentFloor());
elevator.goingUpIndicator(up);
elevator.goingDownIndicator(!up);
}
},
update: function(dt, elevators, floors) {
// NOT USED (yet)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment