Help us understand the problem. What is going on with this article?

rubyでドローポーカーを作ってみる~実装編4(山札)~

概要

rubyでドローポーカーを作ってみる~準備編~

rubyでドローポーカーを作ってみる~test-unit準備編~

rubyでドローポーカーを作ってみる~実装編1(カード)~

rubyでドローポーカーを作ってみる~実装編2(役)~

rubyでドローポーカーを作ってみる~実装編3(プレイヤー)~
に続いて。

ソース: https://github.com/rytkmt/ruby_poker

山札の実装

はい、では今回も同じくまずは要件の整理からいきます。

  • はじめは13 x 4のカードを全て使用して山札を作成する
    • カードの並び順はばらばら
  • 手札交換を行って不要になったカードは回収する
  • 山札から任意の枚数をドローする
    • ドローする枚数が足りなくなった場合、手札交換にて不要になったカードをまぜてシャッフルしてそこから引く

という感じですかね。

プレイヤーの手札交換の修正

ここで気づいてしまいましたが、前回のプレイヤーの実装にて手札交換でただ手札のカードから削除するだけと実装してしまっていたため
捨てるカードを回収するように修正します・・

ruby_poker/player.rb
    def change(indexes:, new_cards:)
       raise(ArgumentError) unless indexes.size == new_cards.size
       raise(ArgumentError) unless indexes.all? { |i| (0..4).include?(i) }
-      indexes.sort.reverse_each { |i| @cards.delete_at(i) }
+      trushed = indexes.sort.reverse.each_with_object([]) { |i, trushed| trushed << @cards.delete_at(i) }
       @cards += new_cards
       @hand = Hand.new(cards: @cards)
+      trushed
     end

山札の作成

ruby_poker/deck.rb
module RubyPoker
  class Deck
    def initialize
      @cards = init_cards
      @trushed = []
    end
  private

    def init_cards
      RubyPoker::SUITS.each_with_object([]) do |suit, cards|
        cards.concat(
          RubyPoker::NUMBERS.map { |number| Card.new(suit: suit, number: number) }
        )
      end.shuffle
    end
  end
end

始め、each_with_object内で+=を使って実装したのですが、よくよく考えるとこれは+で結合したものを=で変数代入してるので同一の変数に結合した別オブジェクトを格納しているだけで、破壊的な変更を行っているわけではないのでうまくいかなかったです。

破壊的にcardsを変更するためにconcatを使います。

手札交換によるカードの回収

プレイヤーの#changeにて返ってきた不要カードを回収して保持しておくだけなので簡単です

ruby_poker/deck.rb
    def trush(cards:)
      @trushed += cards
    end

カードのドロー

  • 山札から任意の枚数をドローする
    • ドローする枚数が足りなくなった場合、手札交換にて不要になったカードをまぜてシャッフルしてそこから引く
ruby/ruby_poker/deck.rb
    def draw(count:)
      merge_trushed if @cards.size < count
      raise(ArgumentError, "No cards.") if @cards.size < count
      @cards.shift(count)
    end

  private

    def merge_trushed
      @cards += @trushed
      @cards.shuffle!
      @trushed = []
    end

足りなくなるってプレイ人数の設定がイケてないだけな気がするので、そこは起こらない前提でエラーを吐くようにしました。

終わりに

山札もシンプルでしたね。
これで次こそゲーム進行回りの実装に入れるかな?と思います。

完成も近づいてきました。4連休で終わらせてしまいたいですし最後までやってしまいます。

r12tkmt
vimとruby関連が多いかと思います :)
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away