Last active
January 22, 2019 11:49
-
-
Save apostololeg/45a9ae27c3a4c1f248acb144bc3eb014 to your computer and use it in GitHub Desktop.
Elevator
This file contains 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
const DIRECTION_DOWN = -1; | |
const DIRECTION_NONE = 0; | |
const DIRECTION_UP = 1; | |
function HardwareElevator() {} | |
HardwareElevator.prototype = { | |
moveUp: function() { console.log("up") }, | |
moveDown: function() { console.log("down") }, | |
stopAndOpenDoors: function() { console.log("stop and open") }, | |
getCurrentFloor: function() {}, | |
getCurrentDirection: function() {} | |
}; | |
function Elevator() { | |
this.hw = new HardwareElevator(); | |
this.hw.on("doorsClosed", _bind(this.onDoorsClosed, this)); | |
this.hw.on("beforeFloor", _bind(this.onBeforeFloor, this)); | |
this.hw.on("floorButtonPressed", _bind(this.onFloorButtonPressed, this)); | |
this.hw.on("cabinButtonPressed", _bind(this.onCabinButtonPressed, this)); | |
this.queue = { | |
1: [], | |
-1: [] | |
}; | |
} | |
Elevator.prototype = { | |
// your changes starting from here | |
addToQueue(floor, direction) { | |
const currentFloor = this.getCurrentFloor(); | |
const queue = this.queue[direction]; | |
if (currentFloor === floor) { | |
// open door on same floor | |
this.stopAndOpenDoors(); | |
return; | |
} | |
if (queue.indexOf(floor) !== -1) { | |
return; | |
} | |
queue.push(floor).sort(); | |
if (direction === DIRECTION_DOWN) { | |
queue.reverse(); | |
} | |
this.queue[direction] = queue; | |
}, | |
// навправление активной очереди (не направление движения!) | |
getDirection() { | |
let currentDirection = this.getCurrentDirection(); | |
let anotherDirection = this.getAnotherDirection(currentDirection); | |
if (currentDirecction !== DIRECTION_NONE) { | |
const upQueue = this.queue[DIRECTION_UP]; | |
const downQueue = this.queue[DIRECTION_DOWN]; | |
if (upQueue.length && upQueue[0]) { | |
currentDirection = DIRECTION_UP; | |
anotherDirection = DIRECTION_DOWN; | |
} esle if (downQueue.length && downQueue[0]) { | |
currentDirection = DIRECTION_DOWN; | |
anotherDirection = DIRECTION_UP; | |
} | |
} | |
if (this.queue[currentDirection][0]) { | |
return currentDirection; | |
} | |
if (this.queue[anotherDirection][0]) { | |
return anotherDirection; | |
} | |
return null; | |
}, | |
// куда нужно двигаться | |
getMoveDirection() { | |
const currFloor = this.getCurrentFloor(); | |
const direction = this.getDirection(); | |
const anotherDirection = this.getAnotherDirection(direction); | |
const nextFloorByDir = this.getNextFloorByDirection(direction); | |
const nextFloorAnother = this.getNextFloorByDirection(anotherDirection); | |
const nextFloorInDir = this.queue[direction][0]; | |
const nextFloorInAnother = this.queue[anotherDirection][0]; | |
const nextFloor = nextFloorByDir | |
|| nextFloorAnother | |
|| nextFloorInAnother | |
|| nextFloorInDir; | |
if (!nextFloor || nextFloor === currFloor) return null; | |
return nextFloor > currFloor ? DIRECTION_UP : DIRECTION_DOWN; | |
} | |
getAnotherDirection(direction) { | |
return [DIRECTION_UP, DIRECTION_DOWN].filter(d => d !== direction)[0]; | |
}, | |
getNextFloorByDirection(direction) { | |
const currFloor = this.getCurrentFloor(); | |
const currDirection = this.getDirection(); | |
return this.queue[direction].filter(n => { | |
return currDirection === DIRECTION_UP | |
? n > currFloor | |
: n < currFloor; | |
})[0]; | |
} | |
moveNext() { | |
const direction = this.getMoveDirection(); | |
if (direction === DIRECTION_DOWN) { | |
this.moveDown(); | |
} | |
if (direction === DIRECTION_UP) { | |
this.moveUp(); | |
} | |
}, | |
onDoorsClosed: function() { | |
this.moveNext(); | |
}, | |
onBeforeFloor: function() { | |
const currentDirection = this.getCurrentDirection(); | |
const currentFloor = this.getCurrentFloor(); | |
const nextFloor = this.queue[currentDirection][0]; | |
if (!nextFloor) { | |
return; | |
} | |
if (nextFloor === currentFloor + currentDirection) { | |
this.stopAndOpenDoors(); | |
this.queue[currentDirection].shift(); | |
} | |
}, | |
onFloorButtonPressed: function(floor, direction) { | |
this.addToQueue(floor, direction); | |
}, | |
onCabinButtonPressed: function(floor) { | |
const currentFloor = this.getCurrentFloor(); | |
if (floor === currentFloor) { | |
return; | |
} | |
const direction = floor > currentFloor ? DIRECTION_UP : DIRECTION_DOWN; | |
this.addToQueue(floor, direction); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment