Javaでルーレットを作った．

# Javaでルーレットゲームを作成した話
## はじめに
SLP KBIT Advent Calendar 2018 12/5
大学の実験でJavaを用いてルーレットを作ったので，それを紹介する．[GitHub](https://github.com/guni1192/roulette_infoexpr2)．
本来は，別の[成果物](https://github.com/Hukanzen/Linux-Monitor)を紹介する予定だったが，あまりにも時間が無く，完成に漕ぎ着けれなかった．

## ルーレットとは
カジノにあるやつ．[Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%AB%E3%83%BC%E3%83%AC%E3%83%83%E3%83%88)．
アメリカ式とヨーロッパ式がある．
アメリカ式は，1~36の数字に追加して0/00が存在する．ヨーロッパ式は，0のみである．
今回は，プログラミングの都合上，偶数の方が都合がいいと考え，アメリカ式を採用した．

## 言語
Java>=9で動作を確認している．
何故，Javaを使った理由としては，実験で指定されたからである．重い．

## オリジナルルール
作成する上で簡略化するために，一部のルールを簡略化している．

* ディーラーが破産したら勝ち，自分が破産したら負けである．
* 掛け金がなくなるか，胴元の破産で終了．
* 線の上には掛けない．


## ゲームの流れ
1. プレイヤーが賭ける場所と金額を設定
1. 抽選
1. 支払い処理
1. 破産判定 if(破産) goto 6
1. goto 1.
1. 終了

## 独自設計
ルーレットには，SMALLやREDなど，特殊な場所がある．これは以下の値を用いることでint型で表現する．
そのうち，enumに置き換えたい．


|数字|値|
|----|----|
|0|0|
|...|...|
|36|36|
|37|00|
|38|SMALL|
|39|MIDDLE|
|40|LARGE|
|41|LOW|
|42|HIGH|
|43|PARILLINEN(偶数)|
|44|PARITON(奇数)|
|45|RED|
|46|BLACK|

## 動作中の様子
1. ベットテーブル
![picTable.png](https://qiita-image-store.s3.amazonaws.com/0/71328/a5822c9b-6057-c3ae-39f7-d7721ab51886.png)

1. ルーレットの円盤
![picBall.png](https://qiita-image-store.s3.amazonaws.com/0/71328/daa32458-5d88-be0d-cea4-3c3dd58e3a54.png)



## クラス設計

### Progress

* ゲームの全体進行を行う
* Mainメソッドはここ．

### InforMation
* ゲームの説明をする．
* ベットできる残り時間を表示する．

### AnyNumMoney
以下の変数がある．

* 初期化用変数
* 賭けた場所
* 賭金

また，Static変数として，賭けた場所とお金の回数を別々に保存する．
これを配列として，扱うことで，何処に幾ら賭けているのかを取り扱うことができ，次の値を配列の何番目に保存するのかが取得できる．
publicメソッドとして，resetがある．これは，全ての値を初期化する．


### Table
* ユーザが賭ける場所と金額を設定する．
* JButtonを多用

anyNumNomeyNormailizeメソッドにより，AnyNumMoney配列の正規化を行う．
これは，賭ける場所のみや，お金のみを保存していて，もう片方を保存していない要素は無駄であるため，取り消すためである．
publicメソッドには，以下のものがある．

1. void setLock(beelean)
ベットを行えなくなる．実際のカジノでは，時間制限によりベットができなくなる．それを実現する．

1. beelean getLock()
現在，ベットが行えるかを取得する．

1. AnyNumMoney[] getNumMoney()
現在，何処に幾ら賭けているかを保存した配列を返す．

### Number
* enum定義や，NumbersTableの値の取得メソッド

### NumbersTable
* ArrayListで，番号，SML，色を保存する．

1. public static SpecialNumbers getSpecialNumberByAddress(int)  
値を投げて，特殊な場所のenumを取る．


### Roulette
* 乱数生成をする．

1. int getIntRouletteValue()
intで取る．

1. String getStringRouletteValue()
Stringで取る．


### MyColor
Color型を返す．



### Ball
* 乱数によって決まった値まで，ボールを円盤状で流すアニメーション
* コンストラクタの引数で，止める数字を取る．

BallMainクラスをWindowとして呼び出す．
BallMainのWindowは，別スレッドで動作するため，Mainメソッドから直接呼び出すと，ルーレットが終わる前に，Mainメソッドの処理が進んでしまう．
これを防ぐために， `ckDoingBallMain()` メソッドを用いて，現在，アニメーションが途中なのか確認する．
終了したら，Windowを閉じて，Mainメソッドに処理を戻る．


Private クラスとして以下を用いる．つか，構造体をくれ．

#### dPoint
public として，double型のx,y変数を持つ．

#### iPoint
dPointと同様にint型のx,y変数を持つ．

#### Cast
dPoint中のx,yをそれぞれ四捨五入して，iPointにする．

#### NumOrder
円盤の配置を保存する．ルーレット円盤は， `0,1,2,...` ではなく `5,22,34,...` の規則性の低い順番で決まっている．それを保存するクラス．

1. int search(int)  
引数の値が何番目に存在するかを返すメソッド．例として， `search(5)` ならば， `0` が返る．

#### BallMain
* 円盤状でボールを回すクラス．
* ボールを回すアニメーション自体には，スレッドにより動作する．
* コンストラクタの引数に，止める値と縦横のサイズを取る．
* 止める値は，円盤状の何番目か， `NumOrder.search(int)` で求める．
* 黒魔術コードで絶妙に止まる．


1. beelean getThreadStatus()  
スレッドが現在動作しているかを，T/Fで返す．



### Payment
ユーザやディーラーに対して，金銭的な処理を行う．

1. void calcEach(Player, Player, int)
ユーザが賭けた場所を舐めて計算する．

1. void clac(Player, Player, int, AnyNumMoney)
ユーザが賭けた場所に対して，インサイドベット，アウトサイドベットの判定を行う．

### Wallet
Playerやディーラーの所持金を保存．

1. Wallet(int)
所持金を設定．

1. int getCache()
所持金を取得．

1. void Cache(int)
支払いを行う．所持金から引数額分引かれる．

1. boolean isInsolvency()
破産しているかをT/Fで返す．


### Player
Playerやディーラーについてのクラス．


### Dealer
Playerを継承してるだけ．

## ファイルリスト
```:ファイルリスト
.
├── ButtonIMG/  # そのうちボタンを置き換える用の画像ファイル
├── README.md   
└── roulette/
    ├── Makefile  # Build，実行用
    ├── bin/  # 生成される.classが自動で配置される
    └── src/  # ソースファイル
        ├── AnyNumMoney.java
        ├── Ball.java
        ├── Dealer.java
        ├── InforMation.java
        ├── MyColor.java
        ├── Number.java
        ├── NumbersTable.java
        ├── Payment.java
        ├── Player.java
        ├── Progress.java
        ├── Roulette.java
        ├── Table.java
        ├── Wallet.java
        └── WalletTest.java
```

## Makefile
`git clone` 後に， `cd roulette` でDirectoryを移動する．
その後，行いたい動作について，以下を実行する．

```bash:コンパイルと実行両方
$ make
```


```bash:コンパイル
$ make class
```


```bash:実行
$ make exe
```


```bash:Classファイルを消す
$ make clean
```


```bash:jarファイルの生成
$ make jar
```

## 今後の展望
* インターネット対戦の実装．
* テーブルやルーレット円盤のリアリティを高める．


## まとめ
作成したルーレットAppについて，紹介した．
実行中の画像とか，そのうち貼ります．
一応，プレイは可能なので，遊んで欲しい．
何かレビューをくれると，とても喜びます．