3 ms·
// works well enough: { currentFloor: 0, init: function(elevators, floors) { var elevator = elevators[0]; // Let's use the first elevator
by frevd 12y ago
// works well enough:
{
currentFloor: 0,
init: function(elevators, floors) {
var elevator = elevators[0]; // Let's use the first elevator
elevator.on("idle", function() {
// The elevator is idle, so let's go to all the floors (or did we forget one?)
var nextFloor;
do nextFloor = Math.round(Math.random() * 2); while (nextFloor == this.currentFloor);
elevator.goToFloor(this.currentFloor = nextFloor);
});
},
update: function(dt, elevators, floors) {
// We normally don't need to do anything here
},
vendor: 'Sirius Cybernetics Corporation'
}
- frevd 12y agoOkay, didn't read or look (currentFloor is already defined) and this won't work in this context. Here is another approach that brought me through till challenge #7: { init: function(elevators, floors) // hook up events { // these are the global wish lists that idle elevators choose from (key are floor numbers, values are number of people): var wishListUp = {}, wishListDown = {}; for (var i = 0, l = elevators.length; i < l; i++) { var elevator = elevators[i]; // API: goToFloor(n) [enqueues], stop() [clears queue], currentFloor(), // goingUpIndicator([set]), goingDownIndicator([set]), loadFactor() [0..1], // destinationQueue[], checkDestinationQueue() [after manual update] elevator.on("idle", function() // elevator destination queue finished { processWishList(); }); elevator.on("floor_button_pressed", function(floorNum) // passenger indicates where to go { if (this.destinationQueue.filter(function (d) { return d == floorNum; }).length == 0) // if not already enqueued this.goToFloor(floorNum); // enqueue // note: passengers coming first need to be delivered first (or at least at all) // however, the elevator will check by passing, whether one destination // can be approached before the others since it comes on the way. }); elevator.on("passing_floor", function(floorNum, direction/*"up"/"down"*/) // if not in destination queue { updateIndicators(this); // indicate next destination from here // we stop here if the queue contains this destination, // or if a passenger on the global wish list want to go in our direction. // we can only hope that people check where the elevator is going. if (this.destinationQueue.filter(function(d) { return d == floorNum; }).length > 0) { this.destinationQueue = this.destinationQueue.filter(function(d) { return d != floorNum; }); // remove from later this.destinationQueue.unshift(floorNum); // add as immediate next destination this.checkDestinationQueue(); // announce modification } else if (this.loadFactor() < 1.0) // if there is some space left { switch (getDirection(this)) { case 1: // going up if (wishListUp[floorNum]) // are people waiting to go up from here? { //if ((1.0 - this.loadFactor()) * 10.0 - wishListUp[floorNum] > 0) // assume capacity for 10 people with regular weight // delete wishListUp[floorNum]; // mark as visited this.destinationQueue.unshift(floorNum); // add as immediate next destination this.checkDestinationQueue(); // announce modification } break; case -1: // going down if (wishListDown[floorNum]) // are people waiting to go down from here? { //if ((1.0 - this.loadFactor()) * 10.0 - wishListDown[floorNum] > 0) // assume capacity for 10 people with regular weight // delete wishListDown[floorNum]; // mark as visited this.destinationQueue.unshift(floorNum); // add as immediate next destination this.checkDestinationQueue(); // announce modification } break; case 0: // final destination default: break; } } }); elevator.on("stopped_at_floor", function(floorNum) // one destination reached { processWishList(); updateIndicators(this); // next direction }); } for (var i = 0, l = floors.length; i < l; i++) { var floor = floors[i]; // API: floorNum() floor.on("up_button_pressed", function() // somebody wants to go up from a certain floor { // elevators are choosing their next best destination, // we just enqueue this into the global wish list queue: var f = this.floorNum(); if (wishListUp[f]) wishListUp[f]++; else wishListUp[f] = 1; processWishList(); }); floor.on("down_button_pressed", function() // somebody wants to go down from a certain floor { // elevators are choosing their next best destination, // we just enqueue this into the global wish list queue: var f = this.floorNum(); if (wishListDown[f]) wishListDown[f]++; else wishListDown[f] = 1; processWishList(); }); } function processWishList() // give idle elevators a new destination { for (var i = 0, l = elevators.length; i < l; i++) // idle { var elevator = elevators[i]; if (elevator.destinationQueue.length == 0) { var next = chooseFloor(elevator.currentFloor(), true); // find closest wish if (elevator.currentFloor() != next) elevator.goToFloor(next); } } } function getDirection(elevator) { if (elevator.destinationQueue.length == 0) return 0; // nowhere else if (elevator.currentFloor() < elevator.destinationQueue[0]) return 1; // up else return -1; // down } function chooseFloor(currentFloor, dequeue) { // choose next destination from the global wish lists for up and down, // depending on a) closest distance and b) number of waiting passengers: var wishList = {}; // joined up and down lists with passenger counts var floors = []; // array of distinct floor numbers for (var i in wishListUp) { wishList[i] = wishListUp[i]; floors.push(i); } for (var i in wishListDown) if (wishList[i]) wishList[i] += wishListDown[i]; else { wishList[i] = wishListDown[i]; floors.push(i); } floors.sort(function(a, b) { var res = Math.abs(currentFloor - a) - Math.abs(currentFloor - b); // by closeness asc if (res == 0) res = wishList[b] - wishList[a]; // by passengers waiting desc return res; }); if (floors.length == 0) return 0; // nothing to do, go back to base var next = floors[0]; if (dequeue) { if (wishListUp[next]) delete wishListUp[next]; if (wishListDown[next]) delete wishListDown[next]; } return next; } function updateIndicators(elevator) { return; // there seems to be a bug if announcing, people do not react .. switch (getDirection(elevator)) { case 1: // up if (!elevator.goingUpIndicator()) elevator.goingUpIndicator(true); if (elevator.goingDownIndicator()) elevator.goingDownIndicator(false); break; case -1: // down if (elevator.goingUpIndicator()) elevator.goingUpIndicator(false); if (!elevator.goingDownIndicator()) elevator.goingDownIndicator(true); break; case 0: // nowhere default: if (elevator.goingUpIndicator()) elevator.goingUpIndicator(false); if (elevator.goingDownIndicator()) elevator.goingDownIndicator(false); break; } } }, update: function(time, elevators, floors) // loop during operation, called each frame { }, vendor: 'frevd' }