rubyでブラック・ジャックできるんです！！

今日は[こちらの記事]("https://qiita.com/hirossyi73/items/cf8648c31898216312e5")を参考にしてトランプのブラック・ジャックを作ってみました。

<b>仕様</b>
・初期カードは52枚。引く際にカードの重複は無いようにする
・プレイヤーとディーラーの2人対戦。プレイヤーは実行者、ディーラーは自動的に実行・
・実行開始時、プレイヤーとディーラーはそれぞれ、カードを2枚引く。引いたカードは画面に表示する。ただし、ディーラーの2枚目のカードは分からないようにする
・その後、先にプレイヤーがカードを引く。プレイヤーが21を超えていたらバースト、その時点でゲーム終了
・プレイヤーは、カードを引くたびに、次のカードを引くか選択できる
・プレイヤーが引き終えたら、その後ディーラーは、自分の手札が17以上になるまで引き続ける
・プレイヤーとディーラーが引き終えたら勝負。より21に近い方の勝ち
・JとQとKは10として扱う
・Aはとりあえず「1」としてだけ扱う。「11」にはしない
・ダブルダウンなし、スプリットなし、サレンダーなし、その他特殊そうなルールなし

<b>コード</b>

```view.rb
require './black_jack/player'
require './black_jack/card'
require './black_jack/controller'

p '今からブラックジャックを始めます'
p 'ディーラーとプレイヤーに2枚ずつカードを配ります。'

@dealer = create_player
@player = create_player

p "ディーラーの#{@dealer.hand_index(0)}"
p "あなたの#{@player.hand_index(0)}"
p "あなたの#{@player.hand_index(1)}"

2.upto(15) do |i|
  p 'カードを引きますか？(y/n)'
  input = gets.chomp

  if input == 'y'
    @player.draw
    p "あなたの引いたカードは#{@player.hand[i][0]}の#{@player.hand[i][1]}です"
  else
    break
  end

  if @player.card_sum > 21
    p '合計が21を超えました！！！'
    p 'プレイヤーの負けです！！！'
    exit
  end
end

p 'では、次にディーラーが引いていきたいと思います。'

while @dealer.card_sum < 17
  @dealer.draw
end

p '両者引き終わりました。'
p '勝者は....'

p @player.battle(@dealer)

p 'プレイヤーのカード'
p @player.card_index

p 'ディーラーのカード'
p @dealer.card_index
```

```login.rb
require './black_jack/player'
require './black_jack/card'

def create_player
  @player = Player.new
  @player.draw
  @player.draw
  @player
end
```

```card.rb
class Card
  MARK = ['spade', 'heart', 'diamond', 'club'].freeze
  NUMBER = [
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13
  ].freeze

  attr_reader :mark, :number

  def initialize(mark,number)
    @mark = mark
    @number = number
  end
end
```

```player.rb
class Player
  attr_reader :hand

  # 引いたカードを入れる配列
  def initialize
    @hand = []
  end

  # カードを引く処理。既に持っているカードを引いたらやり直し
  def draw
    @hand.uniq!
    card = Card.new(Card::MARK.sample, Card::NUMBER.sample)
    @hand << [card.mark, card.number]
    unless @hand.count == @hand.uniq.count
      draw
    end
    @hand
  end

  # 手札の内容
  def hand_index(i)
    "#{i + 1}枚目は#{self.hand[i][0]}の#{self.hand[i][1]}です"
  end

  # プレイヤーのカードの合計がディーラーのカードの合計と比較する
  def battle(other)
    result = (card_sum - 21).abs <=> (other.card_sum - 21).abs
    if result == -1
      'プレイヤーです!!!'
    elsif result == 0
      '引き分けです!!!'
    else
      'ディーラーです!!!'
    end
  end

  # カードの合計を出す。
  def card_sum
    sum = 0
    @hand.each do |num|
      if num[1] > 10
        sum += 10
      else
        sum += num[1]
      end
    end
    sum
  end

  # 手札の一覧を返す
  def card_index
    hand.map { |num| "#{num[0]}の#{num[1]}" }.sort.join(',')
  end
end
```

<b>完成動画</b>
実際にやってみると以下のような動画になります（リンクですいません）。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">トランプのブラック・ジャックを作った！！！<br>ルール合っているか分からないけど！！！ <a href="https://t.co/UAl8mQfCmv">pic.twitter.com/UAl8mQfCmv</a></p>&mdash; あるくまくん (@kesuike713) <a href="https://twitter.com/kesuike713/status/1132507249656516610?ref_src=twsrc%5Etfw">2019年5月26日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<b>まとめ</b>
今回は処理と出力で別のファイルにすることを特に意識しました。
実際に出力されるのはview.rbに、処理はその他のファイルに書きました。
ただ、create_playerメソッドの為だけにlogic.rbを作る必要はなかったかな〜と反省中です。
本当はplayerのインスタンスが作成された時点でdrawメソッドを2回実行させたかったけど、どうすればいいか分かりませんでした汗
後、view.rbに少しだけ処理が残ってしまいました。
こちらも今後リファクタリング 必須ですね。

ブラック・ジャックは[こちらの記事]("https://qiita.com/hirossyi73/items/cf8648c31898216312e5")にも書いてある通り、基本的な文法が理解出来ていれば出来るので、ぜひやってみてください！！！！