## v0.2 working It's not really optimal, as elevator builds it's destination queue in plain format without thinking about it's current movement direction. ```js { init: function(elevators, floors) { const DIR_UP = 2; const DIR_DOWN = 1; const DIR_STOP = 0; const MAX_FLOOR = floors.length - 1; var elev_state = []; console.clear(); // Initialize elevator states if (elev_state == []) { for (var i = 0; i < elevators.length; i++) { elev_state.push(DIR_STOP); } } // HELPER functions // Command elevator to move to floor sendElevator = function(floor, dir) { // debug for (var i = 0; i < elevators.length; i++) { var elevator = elevators[i]; //console.log("Elevator " + elev + " pressed floors:"); //console.log(elevator.getPressedFloors()); } // At first trying to find closest empty elevator and send it if (!getFreeElevator(floor)) { // We didn't found free elevator var less_loaded = getLessLoaded()[0]; if (!less_loaded.destinationQueue.includes(floor)) { less_loaded.destinationQueue.push(floor); //less_loaded.destinationQueue = superSort(less_loaded); less_loaded.checkDestinationQueue(); // debug console.log("Added floor " + floor + " to less loaded elevator"); console.log("Elevator queue: "); console.log(less_loaded.destinationQueue); } } } // Get distance of elevator from floor getDistance = function(elevator, floor) { return Math.abs(elevator.currentFloor() - floor); } // Found free elevator closer to required floor and send it there getFreeElevator = function(floorRequired = 0) { // closest empty elevator var best = null; // get zero-loaded elevators var zero = []; for (var elev = 0; elev < elevators.length; elev++) { var elevator = elevators[elev]; if (elevator.loadFactor() == 0) { zero.push(elevator); } } // Found closer elevator from those who had 0 load for (var elev = 0; elev < zero.length; elev++) { var elevator = zero[elev]; if (best == null) { best = elevator; } if (getDistance(elevator, floorRequired) < getDistance(best, floorRequired)) { best = elevator; } } if (best != null) { // debug console.log("Empty elevator moving to floor " + floorRequired); // If we found one command to move to requested floor best.goToFloor(floorRequired); return true; } return false; } // Super sort superSort = function(elevator) { var queue = elevator.destinationQueue; var currentFloor = elevator.currentFloor; queue.sort(); for (var i = 0; i < queue.length; i++) { if (queue[i] > currentFloor) { var idx = i; break; } } var modQueue = queue.slice(idx); modQueue = modQueue.concat(queue.slice(0, idx)); return modQueue; } // Get less loaded elevator getLessLoaded = function() { return elevators.sort( (a,b) => (a.destinationQueue.length - b.destinationQueue.length) ); } // ELEVATOR events for (var elev = 0; elev < elevators.length; elev++) { var elevator = elevators[elev]; // Elevator is not doing anything elevator.on("idle", function() { // When idle move to 0 floor // elevator.goToFloor(0); }); // Passenger requested floor elevator.on("floor_button_pressed", function(floor) { // debug //console.log("Elevator " + elev + " pressed floors:"); //console.log(elevator.getPressedFloors()); //elevator.goToFloor(floor); if (!elevator.destinationQueue.includes(floor)) { elevator.destinationQueue.push(floor); elevator.checkDestinationQueue(); } }); // Stopped on a particulat floor elevator.on("stopped_at_floor", function(floorNum) { // debug // console.log("Elevator " + elev + " pressed floors:"); // console.log(elevator.getPressedFloors()); console.log("Elevator stopped at floor: " + floorNum); elev_state[elev] = DIR_STOP; // Change direction arrows lights var state_up, state_down = false; switch (floorNum) { case 0: state_up = true; state_down = false; break; case MAX_FLOOR: state_up = false; state_down = true; break; default: state_up = true; state_down = true; break; } elevator.goingUpIndicator(state_up); elevator.goingDownIndicator(state_down); }); // Passing floor elevator.on("passing_floor", function(floor, dir) { switch (dir) { case "up": elev_state[elev] = DIR_UP; break; case "down": elev_state[elev] = DIR_DOWN; break; } }); } // FLOOR events for (var fl = 0; fl < floors.length; fl++) { var floor = floors[fl]; // DOWN button pressed on a floor floor.on("down_button_pressed", function() { // debug console.log("Button DOWN pressed on a floor " + this.floorNum()); sendElevator(this.floorNum(), DIR_DOWN); }); // UP button pressed on a floor floor.on("up_button_pressed", function() { // debug console.log("Button UP pressed on a floor " + this.floorNum()); sendElevator(this.floorNum(), DIR_UP); }); } }, update: function(dt, elevators, floors) { // We normally don't need to do anything here } } ```