Last active
August 29, 2015 14:15
-
-
Save djmitche/fdb454900ddca5ede9e8 to your computer and use it in GitHub Desktop.
Elevator Saga Solution
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) { | |
| var directions = new Array(); | |
| var stopped_at = new Array(); | |
| elevators.forEach(function(el, el_idx) { | |
| directions.push('up'); | |
| stopped_at.push(null); | |
| }); | |
| var setDirection = function(el_idx, direction) { | |
| if (directions[el_idx] != direction) { | |
| var el = elevators[el_idx]; | |
| el.goingUpIndicator((direction == 'up')); | |
| el.goingDownIndicator((direction == 'down')); | |
| directions[el_idx] = direction; | |
| } | |
| }; | |
| var setDestination = function(el_idx, floor_idx, preferred_direction) { | |
| var el = elevators[el_idx]; | |
| var cur_floor = el.currentFloor(); | |
| var direction = (floor_idx < cur_floor) ? 'down' : | |
| (floor_idx > cur_floor) ? 'up' : | |
| preferred_direction; | |
| setDirection(el_idx, direction); | |
| if (el.destinationQueue != [floor_idx]) { | |
| el.destinationQueue = [floor_idx]; | |
| el.checkDestinationQueue(); | |
| } | |
| }; | |
| // does this elevator need to stop at this floor in this direction? | |
| var shouldStopAt = function(el_idx, floor_idx, direction) { | |
| var el = elevators[el_idx]; | |
| // Don't try to stop on the floor we just stopped at. The | |
| // simulation doesn't allow us to move while the doors are still | |
| // open, so this has the effect of ensuring we don't "stall" at a | |
| // floor remaining passengers don't fit onto the elevator. | |
| if (floor_idx == stopped_at[el_idx]) { | |
| return false; | |
| } | |
| // Otherwise, stopping at the ground floor is always a good idea, | |
| // as it gets a lot more traffic than others | |
| if (floor_idx == 0 && direction == 'up') { | |
| return true; | |
| } | |
| // if the floor indicator is lit, we should stop | |
| var pressed_floors = el.getPressedFloors(); | |
| if (pressed_floors.some(function(f) { return f == floor_idx; })) { | |
| return true; | |
| } | |
| // if the button on that floor for that direction is lit, we should | |
| // stop if we're not overloaded | |
| var fl = floors[floor_idx]; | |
| var overloaded = (el.loadFactor() > 0.7); | |
| if (!overloaded && fl.buttonStates[direction] == 'activated') { | |
| return true; | |
| } | |
| return false; | |
| }; | |
| // get a complete trajectory of this elevator to its extreme, back to | |
| // its other extreme, and returning to where it is now. This is super | |
| // inefficient, but who cares? | |
| var trajectory = function(floor_idx, direction) { | |
| var traj = []; | |
| var i; | |
| // build the overall trajectory, starting at the bottom going up | |
| for (i = 0; i < floors.length; i++) { | |
| traj.push([i, 'up']); | |
| } | |
| for (i = floors.length-1; i >= 0; i--) { | |
| traj.push([i, 'down']); | |
| } | |
| // now rotate that trajectory until we get to the desired state | |
| while ((traj[0][0] != floor_idx) || (traj[0][1] != direction)) { | |
| traj.unshift(traj.pop()); | |
| } | |
| return traj; | |
| }; | |
| var nextFloor = function(el_idx, floor_idx, direction) { | |
| var el = elevators[el_idx]; | |
| var fl, dir, fldir; | |
| for (fldir of trajectory(el.currentFloor(), direction)) { | |
| fl = fldir[0]; | |
| dir = fldir[1]; | |
| if (shouldStopAt(el_idx, fl, dir)) { | |
| break; | |
| } | |
| } | |
| return [fl, dir]; | |
| }; | |
| var update = function() { | |
| elevators.forEach(function(el, el_idx) { | |
| var cur_floor = el.currentFloor(); | |
| var fldir = nextFloor(el_idx, cur_floor, directions[el_idx]); | |
| var next_floor = fldir[0], next_dir = fldir[1]; | |
| setDestination(el_idx, next_floor, next_dir); | |
| }); | |
| }; | |
| floors.forEach(function(floor) { | |
| floor.on('up_button_pressed', update); | |
| floor.on('down_button_pressed', update); | |
| }); | |
| elevators.forEach(function(el, el_idx) { | |
| el.on('stopped_at_floor', function() { | |
| stopped_at[el_idx] = el.currentFloor(); | |
| update(); | |
| }); | |
| el.on('passing_floor', function() { | |
| stopped_at[el_idx] = null; | |
| update(); | |
| }); | |
| el.on('idle', update); | |
| el.on('floor_button_pressed', update); | |
| }); | |
| }, | |
| update: function(dt, elevators, floors) {} | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment