4 ms·
Okay, 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 challeng
by frevd 12y ago
Okay, 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'
}