Elevator Saga 2 プログラミングできることを把握する

# エレベータで知れること

APIドキュメントを見ながら試行錯誤を始めると、当たり前に知れそうなことが知れないとわかります。
特に`GUIだと把握できる重要な情報が分からない`です。
- 各フロアに何人待機しているか分からない
- エレベータに何人乗っているか分からない = 何人乗れるか分からない(ただし、load factorという重量値は取れます)
という点です。このため、`待機人数の多いフロアに優先的にエレベータを出す`、といったことが不可能であるとわかります。

# 何ができるかを整理する
APIドキュメントから何ができるかを整理します。

## イベント
### エレベータ
| Name | 備考 |
|:---------------|------------|
| idle | することがない時のイベント。 | 
| floor_button_pressed | フロアボタンが押された時のイベント。 |
| passing_floor | フロアを通過する直前に発火するイベント。 up, downの情報が得られる。 |
| stopped_at_floor | フロアに到着した際に発火するイベント。| 
`idle`は標準の階数を指定するのに使えそうです。
`floor_button_pressed`は利用が必須です。
`stopped_at_floor`は表示灯を変更するのに使えそうです。
`passing_floor`はほかで十分そう。

### フロア
| Name | 備考 |
|:--------|------------|
| up_button_pressed | 上ボタンが押された時のイベント | 
| down_button_pressed | 下ボタンが押された時のイベント |  
Floorにはこの2つしかイベントがないのですが、あまりこれを区別する意味はないように思えます。

## 関数
### エレベータ
| Name | 備考 |
|:---------------|------------|
| goToFloor | 
### フロア
| Name | 備考 |
|:---------------|------------|
| floorNum | このフロア自身の階数 |


# いくつかの考察
## elavator.goToFloor()
それぞれ、以下のWrapper相当の動作となります。

```Javascript
// goToFloor(x)
e.destinationQueue(floor)
e.checkDestinationQueue()
// goToFloor(x, true)
e.destinationQueue.unshift(floor)
e.checkDestinationQueue()
```

## elavator.destinationDirection()
これも利用する意味はなく、以下のWrapper相当です。

```JavaScript
e.destinationQueue = []ならstop
e.destinationQueue = e.currentFloor() ならstop
e.destinationQueue[0] < e.currentFloor() なら "down"
e.destinationQueue[0] < e.currentFloor() なら "up"
```

# elavator.maxPassengerCount()
loadFactorを使わないと現在の乗車人数は分かりませんが、これを使うことでloadfactorを参照して止まるかどうかの判断に使える。

```Javascript
if(e.maxPassengerCount == 4 and e.loadFactor() > 0.9)
 > 4人乗りで9割乗っていたらもう乗れないが、
else if(e.maxPassengerCount == 100 and e.loadFactor() > 0.9)
 > もし、100人乗りで9割ならまだ乗れそう
```

# elavator.passing_floor()
色々と使えそうなのですが、"このイベントはdestination フロアには発火しません"というのがネックです。

# 基礎的ないくつかのアイデア

## 表示灯について
上に行くとき上の表示灯を、下に行くとき下の表示灯を表示しようとして、以下のように（抜粋)してもうまくいかない。

```JavaScript
        function goingUp(e){e.goingUpIndicator(true); e.goingDownIndicator(false); }
        function goingDown(e){e.goingUpIndicator(false); e.goingDownIndicator(true); }
    init: function(elevators, floors) {
            elevator.destinationQueue.push(0);
            goingUp(elevator);
            elevator.destinationQueue.push(1);
            elevator.destinationQueue.push(2);
            goingDown(elevator);
            elevator.checkDestinationQueue();
            elevator.goToFloor(1);
```
なぜなら、idle時に上が実行され、goingUpだけが残るからである。
このため、例えば、stopped_at_floorトリガを使って以下のように実装する必要がある。
ここでは、Lv1で表示灯を表示しながら移動するようにした。

```JavaScript
{

    init: function(elevators, floors) {
        var elevator = elevators[0]; // Let's use the first elevator
        function goingUp(e){e.goingUpIndicator(true); e.goingDownIndicator(false); }
        function goingDown(e){e.goingUpIndicator(false); e.goingDownIndicator(true); }
        // Whenever the elevator is idle (has no more queued destinations) ...
        elevator.on("stopped_at_floor", function(floorNum) {
            if(elevator.destinationQueue.length == 0){
                goingUp(elevator);
            } else if(elevator.destinationQueue[0] < elevator.currentFloor() ) {
                goingDown(elevator);

            } else {
                goingUp(elevator);
            }
        });
        
        elevator.on("idle", function() {
            // let's go to all the floors (or did we forget one?)
            elevator.destinationQueue.push(1);
            elevator.destinationQueue.push(2);
            elevator.destinationQueue.push(1);
            elevator.destinationQueue.push(0);
            elevator.checkDestinationQueue();
            console.log("a");
        });
    },
    update: function(dt, elevators, floors) {
        // We normally don't need to do anything here
    }
}
```

# 気が付いたこと