Created
May 16, 2018 12:54
-
-
Save gombosg/aadcfb4b2539c2ecb4788e8d1e7f32bf to your computer and use it in GitHub Desktop.
My take on Elevator saga, completes until challenges 1-12 so far.
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) { | |
// ---------------------------- | |
// 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