概要
rubyでドローポーカーを作ってみる~準備編~
↓
rubyでドローポーカーを作ってみる~test-unit準備編~
↓
rubyでドローポーカーを作ってみる~実装編1(カード)~
↓
rubyでドローポーカーを作ってみる~実装編2(役)~
に続いて。
ソース: https://github.com/rytkmt/ruby_poker
今回はカード、役を扱うプレイヤーの実装に入っていきたいと思います。
プレイヤーの実装
今回もまずは要件を整理してみます。
- 始め5枚のカードをもらう
- 役を判定する
- 任意の枚数、任意のカードを交換する
- 再度、役を判定する
- プレイヤーの勝敗を判定する
- 実質、プレイヤーの持つ役を判定する
ファイルの作成
module RubyPoker
class Player
def initialize(cards:)
@cards = cards
@hand = Hand.new(cards: cards)
end
end
end
もらったカードで役を判定するまではこれで出来ました。
require "ruby_poker/version"
require "active_support/all"
-require "ruby_poker/card"
-require "ruby_poker/hand"
+Dir[__dir__ + "/ruby_poker/*.rb"].each { |p| require p }
module RubyPoker
requireも忘れずに行いますが、1ファイルずつ追加していくのもあほらしく感じたので全て読み込むように変更しました。
カードの交換
続いて、任意のカードの交換を実装します。
- いらないカードを捨てる
- 新しいカードをもらう
- 新しいカードにて、再度役を判定する
カードの交換は要素番号をもらい削除するようにしようと思います。
こんとき、要素番号で削除するため小さいものから削除してしまうと要素がそのぶんずれておかしなことになってしまいます。
なので、大きい番号から削除するようにしないといけないので注意して実装します。
検証)
x = %i[a b c d e]
# a & c & d => [b, e]
indexes = [0, 2, 3]
indexes.each { |i| x.delete_at(i); p x }
# => [:b, :c, :d, :e]
# => [:b, :c, :e]
# => [:b, :c, :e]
x = %i[a b c d e]
indexes.sort.reverse_each { |i| x.delete_at(i); p x }
# => [:a, :b, :c, :e]
# => [:a, :b, :e]
# => [:b, :e]
カードは山札からもらう必要があるため、捨てるカードの枚数だけ新しいカードをもらえばプレイヤーの責務の範囲は小さくなるかと思いました。
なので、そのように実装してみましょう(あとから変える可能性もありますが、、)k
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) }
@cards += new_cards
@hand = Hand.new(cards: @cards)
end
プレイヤーの勝敗判定
今回もComparable
を使用します。
結局は役にて判定するので委譲するようにします。
delegateはactive_support
にてModule
にdelegate
メソッドが拡張で用意されています。
Class
はModule
のサブクラスなので同じくdelegate
が使えます。
delegate :<=>, to: :@hand
↑ダメでした。。
<=>
のotherが、そのままdelegateだとhandに渡されてしまうため、自分のhandとotherのplayerを比較してしまうことになってしまいました。
attr_reader :hand
def <=>(other)
@hand <=> other.hand
end
おとなしく普通に実装しました。。
これで完了。楽ですねー
終わりに
今回は、勝敗などに関わる機能面での処理のみ実装しました。
ここから、ゲーム進行のことを考えるとコンソール出力回りを実装する必要もでますが、それは次の進行回りを検討するタイミングで追加するようにしていきたいと思います。