【JAVA】「くじで席替え+ファイル出力(CSV)」「フローチャート作成（plantuml）」

## 概要
「くじで席替え+ファイル出力(CSV)」する簡単なプログラムです。
フローチャートも作成しました。

||備考|
|----|---|
|人数|１８人|
|出席番号(ID)|0-17|
|前の席希望者(KIBOU)|n人(複数可)|
|くじ|１８枚|
|くじ番号(KUJI)|0-17|
|席番号(希望者)|0-n|
|席番号(その他)|n-18|
※席番号が小さい程前になるので、希望人数に合わせてくじ番号を限定する

### 座席表
|0|1|2|3|4|
|--|--|--|--|--|--|--|--|--|
|5|6|7|8|9|
|10|11|12|13|14|
|15|16|17|18|

## フローチャート（ベータ版）
※ plantumlのコードは、[おまけ](#おまけ)に記載しています

```plantuml
start
partition くじ引き(全員) {
    ' クラスの定義
    note left
        = 定義
        ====
        === クラス
        * 人数　　　　 : 18人
        * 出席番号　　 : 0~17
        * 前の席希望者 : n人(複数可)
        ----
        === くじ
        * くじ　　 : 18個
        * 順番　　 : 小→大
        * 席番号　 : 0~17(min~max)
        ** 希望者 : 0~(n-1)
        ** その他 : n~17
        * 使用状況
        ** 未使用[-] : false
        ** 使用済[×] : true
    end note

    repeat: 箱もらう;
      partition くじ引き(個人) {

        note left
            = 判断処理_A
            ====
            * 未使用
            * min >= くじ番号
            * くじ番号 < max
        end note

        repeat: くじを引く;
          backward :箱に戻す;
        repeat while (判断処理_A) is (No) not (Yes)
        : ・くじに「×」をつける \n ・箱に戻す;
        :紙に「出席番号」「くじ番号」を書く;
      }
      backward :次の人に渡す;
    repeat while (出席番号が18以下) is (No) not (Yes)
}
end

@enduml
```
## サンプル

|    |備考|
|----|---|
|前の席希望者  |3人|
|席番号(希望者)|0-2|
|席番号(その他)|3-18|

### コード
```java:Sekigae.java
import java.io.*;
import java.util.Arrays;

public class Sekigae {
    static int KUJI_MIN, KUJI_MAX, KUJI_NUM;

    static String FILE_NAME = "test.csv";
    static Integer[] KIBOU = { 5, 10, 15 };
    static int[][] DATA = new int[18][2];
    static boolean[] KUJI = new boolean[18];

    /***
     * くじ引きで席順を決める
     *
     * @param args
     */
    public static void main(String[] args) {
        try {
            // データ取得
            DATA = getData();

            // ファイルの設定
            FileWriter fw = new FileWriter(FILE_NAME);
            BufferedWriter bw = new BufferedWriter(fw);
            PrintWriter pw = new PrintWriter(bw);

            // ファイルに出力
            pw.println("ID,番号");
            for (int[] item : DATA) {
                pw.println(item[0] + "," + item[1]);
            }
            pw.close();

        } catch (IOException e) {
            System.out.println(e);
        } finally {
            System.out.println("処理終了");
        }

    }

    /***
     * くじ引き
     *
     * @return data くじ引きの結果
     */
    private static int[][] getData() {
        for (int i = 0; i < KUJI.length; i++) {
            // 希望者かどうか
            boolean isKibou = Arrays.asList(KIBOU).contains(i);

            // 席(min~max)
            KUJI_MIN = (isKibou) ? 0 : KIBOU.length;
            KUJI_MAX = (isKibou) ? KIBOU.length : 19;

            // 判定: 重複 OR 席(min~max)
            do {
                KUJI_NUM = (int) (Math.random() * 18);
            } while (KUJI[KUJI_NUM] || ((KUJI_NUM >= KUJI_MIN) == false) || ((KUJI_NUM < KUJI_MAX) == false));

            // 確定
            DATA[i][0] = i;
            DATA[i][1] = KUJI_NUM;
            KUJI[KUJI_NUM] = true;
        }
        return DATA;
    }
}

```


### 出力されたCSV
```csv:test.csv
ID,番号
0,3
1,14
2,15
3,9
4,6
5,0
6,17
7,13
8,12
9,5
10,1
11,10
12,8
13,4
14,11
15,2
16,7
17,16
```

## おまけ
### plantumlコード（ベータ版）
```:Sekigae.pu
@startuml くじ引きで席替え
title くじ引きで席替え
start
start
partition くじ引き(全員) {
    ' クラスの定義
    note left
        = 定義
        ====
        === クラス
        * 人数　　　　 : 18人
        * 出席番号　　 : 0~17
        * 前の席希望者 : n人(複数可)
        ----
        === くじ
        * くじ　　 : 18個
        * 順番　　 : 小→大
        * 席番号　 : 0~17(min~max)
        ** 希望者 : 0~(n-1)
        ** その他 : n~17
        * 使用状況
        ** 未使用[-] : false
        ** 使用済[×] : true
    end note

    repeat: 箱もらう;
      partition くじ引き(個人) {

        note left
            = 判断処理_A
            ====
            * 未使用
            * min >= くじ番号
            * くじ番号 < max
        end note

        repeat: くじを引く;
          backward :箱に戻す;
        repeat while (判断処理_A) is (No) not (Yes)
        : ・くじに「×」をつける \n ・箱に戻す;
        :紙に「出席番号」「くじ番号」を書く;
      }
      backward :次の人に渡す;
    repeat while (出席番号が18以下) is (No) not (Yes)
}
end
@enduml
```
### フローチャート図（レガシー版）

```plantuml
@startuml くじ引きで席替え
title くじ引きで席替え
(*)--> "箱もらう"
note left
        = 定義
        ====
        === クラス
        * 人数　　　　 : 18人
        * 出席番号　　 : 0~17
        * 前の席希望者 : n人(複数可)
        ----
        === くじ
        * くじ　　 : 18個
        * 順番　　 : 小→大
        * 席番号　 : 0~17(min~max)
        ** 希望者 : 0~(n-1)
        ** その他 : n~17
        * 使用状況
        ** 未使用[-] : false
        ** 使用済[×] : true
end note
"箱もらう" -right-> "くじを引く"
"くじを引く"-right-> "くじが未使用"
"くじが未使用" -->[no] "箱に戻す"
"箱に戻す" -->"くじを引く"
"くじが未使用" -right->[yes] "くじ番号 < max"
"くじに「×」をつけ、箱に戻す" --> "紙に「出席番号」「くじ番号」を書く"
"くじ番号 < max" -->[no] "箱に戻す"
"紙に「出席番号」「くじ番号」を書く" --> "出席番号 < 18"
"くじ番号 < max" -right->[yes] "min >= くじ番号"
"min >= くじ番号" ->[no] "箱に戻す"
"min >= くじ番号" -->[yes] "くじに「×」をつけ、箱に戻す"
"次の人に渡す" --> "箱もらう"
"出席番号 < 18" --> [no] "次の人に渡す"
"出席番号 < 18" -->  [yes] (*)
@enduml
```
### plantumlコード（レガシー版）
```
@startuml くじ引きで席替え
title くじ引きで席替え
(*)--> "箱もらう"
note left
        = 定義
        ====
        === クラス
        * 人数　　　　 : 18人
        * 出席番号　　 : 0~17
        * 前の席希望者 : n人(複数可)
        ----
        === くじ
        * くじ　　 : 18個
        * 順番　　 : 小→大
        * 席番号　 : 0~17(min~max)
        ** 希望者 : 0~(n-1)
        ** その他 : n~17
        * 使用状況
        ** 未使用[-] : false
        ** 使用済[×] : true
end note
"箱もらう" -right-> "くじを引く"
"くじを引く"-right-> "くじが未使用"
"くじが未使用" -->[no] "箱に戻す"
"箱に戻す" -->"くじを引く"
"くじが未使用" -right->[yes] "くじ番号 < max"
"くじに「×」をつけ、箱に戻す" --> "紙に「出席番号」「くじ番号」を書く"
"くじ番号 < max" -->[no] "箱に戻す"
"紙に「出席番号」「くじ番号」を書く" --> "出席番号 < 18"
"くじ番号 < max" -right->[yes] "min >= くじ番号"
"min >= くじ番号" ->[no] "箱に戻す"
"min >= くじ番号" -->[yes] "くじに「×」をつけ、箱に戻す"
"次の人に渡す" --> "箱もらう"
"出席番号 < 18" --> [no] "次の人に渡す"
"出席番号 < 18" -->  [yes] (*)
@enduml
```