Skip to content

Instantly share code, notes, and snippets.

@adamnew123456
Last active June 8, 2016 16:12
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 adamnew123456/3363055402253d2915e7b1faa21bc8d6 to your computer and use it in GitHub Desktop.
Save adamnew123456/3363055402253d2915e7b1faa21bc8d6 to your computer and use it in GitHub Desktop.
Elevator Saga - Current Attempt
{
// NOTE: Only expect this to work on FF, Chrome or Edge.
// There are several arrow functions sprinkled around,
// and caniuse suggests that these are the only browsers
// that can handle them natively
init: function(elevators, floors) {
// The backlog is (an approximation of) the number of people currently waiting at
// the given floor.
//
// Why an approximation? Well, there are places in the code where a floor's backlog
// is set to 0, but shouldn't be. Ocasionally, this will leave people hanging, and
// require some tuning for the 'let no-one wait more than X' missions.
var backlog = [];
floors.forEach((_, i) => { backlog[i] = 0 });
var minList = lst => Math.min.apply(null, lst);
var maxList = lst => Math.max.apply(null, lst);
// Some challenges will have a lot of people start on a given floor, so
// it can pay to tune this a little bit
var DEFAULT_FLOOR = 0;
// Moves to the busiest floor, or the default floor if no floor has waiters
function goToBusiestFloor(elevator) {
var maxBacklog = maxList(backlog);
// Go to the middle floor, if there aren't any waiting, so that the
// travel time to the next floor will be lowest (on average)
if (maxBacklog == 0) {
elevator.goToFloor(DEFAULT_FLOOR);
} else {
var maxFloor = backlog.indexOf(maxBacklog);
elevator.goToFloor(maxFloor);
backlog[maxFloor] = 0;
}
}
function initElevator(elevator, elevatorNum) {
// Once the elevator is this perecent full, it will not stop
// to pick up new passengers
var PASS_FACTOR = 0.95;
var direction = 'down';
// Changes the direction of the elevator. If new_dir is *not* given,
// then this swaps the direction - otherwise, the new directio is
// new_dir
function changeDirection(new_dir) {
other_dir = {
'up': 'down',
'down': 'up',
};
if (new_dir == 'up' || direction == 'down') {
direction = 'up';
} else if (new_dir == 'down' || direction == 'up') {
direction = 'down';
}
}
changeDirection();
// This finds the next floor to go to, considering the current direction (this will avoid
// reversing course if at all possible), the floors whose buttons are pressed, and the
// floors that are busy and on the way from here to the destionation floor
function pickNextPressedFloor(destinations, busy) {
switch (direction) {
case 'up':
// Find the minimum floor that's currently above us
var aboveUs = destinations.filter(dest => dest > elevator.currentFloor());
var busyAboveUs;
if (elevator.loadFactor() > PASS_FACTOR) {
// It doesn't matter how many people are waiting above us, if we
// can't pick them up
busyAboveUs = [];
} else {
busyAboveUs = busy.filter(floor => floor > elevator.currentFloor());
}
var available = aboveUs.concat(busyAboveUs);
if (available.length == 0) {
// Go down, and find the next place to go
changeDirection();
return pickNextPressedFloor(destinations, busy);
} else {
elevator.goToFloor(minList(available));
if (elevator.loadFactor() < PASS_FACTOR) {
backlog[minList(available)] = 0;
}
}
break;
case 'down':
// Find the maximium floor that's currently below
var belowUs = destinations.filter(dest => dest < elevator.currentFloor());
var busyBelowUs;
if (elevator.loadFactor() > PASS_FACTOR) {
busyBelowUs = [];
} else {
busyBelowUs = busy.filter(floor => floor < elevator.currentFloor());
}
var available = belowUs.concat(busyBelowUs);
if (available.length == 0) {
// Go up, and find the next place to go
changeDirection();
return pickNextPressedFloor(destinations, busy);
} else {
elevator.goToFloor(maxList(available));
if (elevator.loadFactor() < PASS_FACTOR) {
backlog[maxList(available)] = 0;
}
}
break;
}
}
elevator.on("idle", function() {
var destinations = elevator.getPressedFloors();
if (destinations.length == 0) {
// No passengers - go find the most densely packed floor and
// get to work
goToBusiestFloor(elevator);
} else {
// We're picking out the index of any floor with >0 waiters
var busy = (backlog
.map((waiting, i) => waiting > 0 ? i: -1)
.filter(i => i != -1));
pickNextPressedFloor(destinations, busy);
}
})
elevator.on("stopped_at_floor", function(floorNum) {
backlog[floorNum] = 0;
})
}
function initFloor(floor, floorNum) {
floor.on("up_button_pressed", function() {
backlog[floorNum]++;
})
floor.on("down_button_pressed", function() {
backlog[floorNum]++;
})
}
for (var i = 0; i < elevators.length; i++) {
initElevator(elevators[i], i);
}
for (var i = 0; i < floors.length; i++) {
initFloor(floors[i], i);
}
},
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