Rubyでチンチロゲームを作る 　第1回　全体の仕様決定と役判定まで

#1.はじめに
　Rubyって楽しいですね。独特の言い回しはあるけれど、ささっと書けるのが素敵です。今回は自分がどこまでRubyを理解しているのかを知るために、なにかつくってみることにしました。チンチロゲームです。

#2.  チンチロとは？
　サイコロをつかった賭博ゲームです。サイコロ3つを振り、出た目で役が決まります。親を交代しながら、掛け金が移動していきます。私はカイジでこのゲームを知りました。

　チンチロゲームを作ろうと思ったのは、適当な難易度だと思ったからです。カードゲームのようにマークや残数を考えなくていいし、手札を表示させる必要もありません。

　※ピンゾロサイやシゴロサイは出ません。

#3. 全体の仕様決定
##3-1. ルール
　ルール/役はカイジの地下チンチロを適用します。勝敗は自分で適当に
http://ketto.com/zw/tintiro_rule.shtml

##3-2. ゲームの流れ
　1. 親決め
　2. 掛け金決定
　3. サイコロを振り役を決める（親が最初、子も振る）
　4. 役に応じて掛け金の移動
　5. 掛け金が0になったら負け　もしくは親を二巡して掛け金が多い人が勝ち

## 3-3.実装に必要な処理
　□ サイコロを振る/役の決定
　□ 掛け金の移動
　□ 勝利/敗北判定
　□ 親の決定
　□ 親の移動
　□ メイン画面・メッセージ出力

　これで全体的なものがなんとなく見えてきました。
#4.  役の決定までをつくる
　今回の記事では「サイコロを振る/役の決定」の機能をつくってみます。なにかしらの関数が必要になるでしょう。`roll_dice()`関数とします。引数はなし、戻り値はサイコロの出目と役です。ハッシュ形式で
`{eye: eye_on_the_dices, hand: dice_hand}`
とできればいいですね。書きます。

```ruby
def roll_dice()
    eye_on_the_dices = [rand(1..6),rand(1..6) ,rand(1..6)]
    eye_on_the_dices.sort!
    if eye_on_the_dices === [1,1,1] then
        dice_hand = 'ピンゾロ'
    elsif eye_on_the_dices === [1,2,3] then
        dice_hand = 'ヒフミ'
    elsif eye_on_the_dices === [4,5,6] then
        dice_hand = 'シゴロ'
    elsif eye_on_the_dices.uniq.size == 1 then
        dice_hand = 'ゾロ目'
    elsif eye_on_the_dices.uniq.size == 2 then
        # ????
    else 
        dice_hand = '目なし'
    end
    
    {eye: eye_on_the_dices, hand: dice_hand}
end
```

　Rubyは関数の戻り値に`return`を使わないのが一般的らしいです。ちょっとびっくり。

　はじめのeye_on_the_dicesには1~6のサイコロの出た目を入れます。次にsortをすることで配列の中を昇順の並びにします。こうすることで、[1,3,5]と[3,5,1]が同じものとして扱われます。

　次に出た目の判定です。ピンゾロ、ヒフミ、シゴロ、ゾロ目は単純です。しかし、通常の目の判定がちょっと難しかったです。「３つのサイコロのうち2つが同じ目」となるからです。しかものこりの1個のサイコロの目で役の強さが変わるのでそれも取得する必要があります。

　すこし悩んだ結果、こうなりました。

```ruby
#...略
     elsif eye_on_the_dices.uniq.size == 2 then
        
        group_eye_dices = eye_on_the_dices.group_by{|value|value} 
        #ハッシュ形式で整形する　 ex. group_eye ={2=>[2,2], 5=>[5]}

        uniq_array = group_eye_dices.select{|key,value| value.size == 1}
        #重複していない要素のみを取り出す ex. uniq_array ={5=>[5]}
        
        uniq_value = uniq_array.values.flatten.first
        #取り出した要素を抽出 ex. uniq_array ={5=>[5]}

        dice_hand = '通常の目(' + uniq_value.to_s + ')'
    else 
#...略
```

`group_by`や`select`で値を整形します。できました。


## 5.テスト
　はじめてですが、テストコードというのを書いてみます。チェリー本に書いてあった、minitestを使います。サイコロ３つの全パターン（216通り）をそれぞれ`assert equal`で判定させました。もっとよいやりかたがあるかもしれません。だれか教えてください。

```ruby
require 'minitest/autorun'
require './lib/dice_roll'
class DiceTest < Minitest::Test
  def test_dice
      # 1
      assert_equal 'ピンゾロ', roll_dice([1,1,1])
      assert_equal '通常の目(2)', roll_dice([1,1,2])
      assert_equal '通常の目(3)', roll_dice([1,1,3])
      assert_equal '通常の目(4)', roll_dice([1,1,4])
      assert_equal '通常の目(5)', roll_dice([1,1,5])
      assert_equal '通常の目(6)', roll_dice([1,1,6])
      assert_equal '通常の目(2)', roll_dice([1,2,1])
      assert_equal '通常の目(1)', roll_dice([1,2,2])
      assert_equal 'ヒフミ', roll_dice([1,2,3])
      assert_equal '目なし', roll_dice([1,2,4])
      assert_equal '目なし', roll_dice([1,2,5])
     #めっちゃ略....
  end
end
```

テストのため関数に引数/戻り値を設定しなおしました。この方法があっているのか疑問ですが....

テストは無事に通りました。よかったです。

## 6. 次回予告
　次はプレイヤーをclassで定義し、役によって掛け金が移動するようにします。

　今回のコードはこちらのリポジトリに追記していきます。

https://github.com/kyokucho1989/ruby-game