diff --git a/level2.md b/level2.md new file mode 100644 index 0000000..66f3cc1 --- /dev/null +++ b/level2.md @@ -0,0 +1,195 @@ +### v0.1 + +```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]; + 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); + }); + + // 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 + } +} +``` \ No newline at end of file