Skip to content

Instantly share code, notes, and snippets.

@curzonj
Last active November 24, 2019 03:21
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 curzonj/b449f7b1ebdf024f597c352cbdac70a3 to your computer and use it in GitHub Desktop.
Save curzonj/b449f7b1ebdf024f597c352cbdac70a3 to your computer and use it in GitHub Desktop.
{
init: function(elevators, floors) {
var elevator = elevators[0]; // Let's use the first elevator
function addFloorRequest(requestedDirection, floorNumber) {
if (elevator.destinationQueue.indexOf(floorNumber) > -1) return;
if (elevator.destinationQueue.length === 0) {
elevator.goToFloor(floorNumber);
return;
}
elevator.destinationQueue.push(floorNumber);
var currentFloor = elevator.currentFloor();
var direction = elevator.destinationDirection();
if (direction === "stopped") {
direction = elevator.destinationQueue[0] > currentFloor ? "up" : "down";
}
var first = elevator.destinationQueue.filter(function(dqfn) {
return direction === "up" ? dqfn > currentFloor : dqfn < currentFloor;
}).sort();
var after = elevator.destinationQueue.filter(function(dqfn) {
return first.indexOf(dqfn) === -1;
}).sort();
if (direction === "up") {
after.reverse();
} else {
first.reverse();
}
elevator.destinationQueue = [ first, after ].flat();
elevator.checkDestinationQueue();
}
floors.forEach(function (floor) {
floor.on("up_button_pressed", function() {
addFloorRequest("up", floor.floorNum())
})
floor.on("down_button_pressed", function() {
addFloorRequest("down", floor.floorNum())
})
})
elevator.on("floor_button_pressed ", function(floorNumber) {
addFloorRequest(undefined, floorNumber);
});
},
update: function(dt, elevators, floors) {
// We normally don't need to do anything here
}
}
{
init: function(elevators, floors) {
elevators.forEach(function (e) {
e.goingUpIndicator(true);
e.goingDownIndicator(false);
e.on("floor_button_pressed ", function(floorNumber) {
addFloorRequest(e, floorNumber);
});
e.on("stopped_at_floor", function(floorNumber) {
const direction = currentDirection(e);
e.goingUpIndicator(direction === "up" || direction === "stopped")
e.goingDownIndicator(direction === "down" || direction === "stopped")
})
});
function currentDirection(elevator) {
let direction = elevator.destinationDirection();
if (direction === "stopped" && elevator.destinationQueue.length > 0) {
direction = elevator.destinationQueue[0] > elevator.currentFloor() ? "up" : "down";
}
return direction;
}
function distance(elevator, floorNumber) {
return Math.abs(elevator.currentFloor() - floorNumber);
}
function filterLoadFactor(n) {
return function(e) {
return e.loadFactor() <= n;
}
}
function selectClosestFromList(floorNumber, list) {
if (list.length === 0) return;
return list.reduce(function(acc, e) {
if (distance(e, floorNumber) < distance(acc, floorNumber)) {
return e;
} else {
return acc;
}
});
}
function selectClosestSameDirection(loadFactor, requestedDirection, floorNumber) {
selectClosestFromList(floorNumber, elevators.
filter(filterLoadFactor(loadFactor)).
filter(function(e) {
const direction = currentDirection(e);
const currentFloor = e.currentFloor();
if (requestedDirection !== direction) return false;
if (direction === "up" && floorNumber > currentFloor) return true;
if (direction === "down" && floorNumber < currentFloor) return true;
return false;
}))
}
function selectClosestEmpty(floorNumber) {
selectClosestFromList(floorNumber, elevators.
filter(function(e) { return e.destinationQueue.length === 0; }));
}
function selectSoonestAvailable(loadFactor) {
return elevators.
filter(filterLoadFactor(loadFactor)).
reduce(function(acc, e) {
if (acc === undefined || e === undefined) return acc;
if (e.destinationQueue.length < acc.destinationQueue.length) {
return e;
} else {
return acc;
}
})
}
function selectBestElevator(requestedDirection, floorNumber) {
const ret =
selectClosestEmpty(floorNumber) ||
selectClosestSameDirection(0.8, requestedDirection, floorNumber) ||
selectSoonestAvailable(0.4) ||
selectSoonestAvailable(0.8) ||
selectClosestSameDirection(1, requestedDirection, floorNumber) ||
selectSoonestAvailable(1);
if (ret === undefined) {
console.dir({ requestedDirection, floorNumber, warning: "undefined best elevator" })
}
return ret;
}
function addFloorRequest(elevator, floorNumber) {
if (elevator.destinationQueue.indexOf(floorNumber) > -1) return;
if (elevator.destinationQueue.length === 0) {
elevator.goToFloor(floorNumber);
return;
}
elevator.destinationQueue.push(floorNumber);
const currentFloor = elevator.currentFloor();
const direction = currentDirection(elevator);
const first = elevator.destinationQueue.filter(function(dqfn) {
return direction === "up" ? dqfn > currentFloor : dqfn < currentFloor;
}).sort();
const after = elevator.destinationQueue.filter(function(dqfn) {
return first.indexOf(dqfn) === -1;
}).sort();
if (direction === "up") {
after.reverse();
} else {
first.reverse();
}
elevator.destinationQueue = [ first, after ].flat();
elevator.checkDestinationQueue();
elevator.goingUpIndicator(direction === "up")
elevator.goingDownIndicator(direction === "down")
}
floors.forEach(function (floor) {
floor.on("up_button_pressed", function() {
addFloorRequest(selectBestElevator("up", floor.floorNum()), floor.floorNum())
})
floor.on("down_button_pressed", function() {
addFloorRequest(selectBestElevator("down", floor.floorNum()), floor.floorNum())
})
})
},
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