0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

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

Last updated at Posted at 2020-07-24

概要

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

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

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

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

に続いて。

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

今回はカード、役を扱うプレイヤーの実装に入っていきたいと思います。

プレイヤーの実装

今回もまずは要件を整理してみます。

  • 始め5枚のカードをもらう
    • 役を判定する
  • 任意の枚数、任意のカードを交換する
    • 再度、役を判定する
  • プレイヤーの勝敗を判定する
    • 実質、プレイヤーの持つ役を判定する

ファイルの作成

ruby_poker/player.rb
module RubyPoker
  class Player
    def initialize(cards:)
      @cards = cards
      @hand = Hand.new(cards: cards)
    end
  end
end

もらったカードで役を判定するまではこれで出来ました。

ruby_poker.rb
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

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) }
      @cards += new_cards
      @hand = Hand.new(cards: @cards)
    end

プレイヤーの勝敗判定

今回もComparableを使用します。
結局は役にて判定するので委譲するようにします。

delegateはactive_supportにてModuledelegateメソッドが拡張で用意されています。
ClassModuleのサブクラスなので同じくdelegateが使えます。

ruby_poker/player.rb
    delegate :<=>, to: :@hand

↑ダメでした。。
<=>のotherが、そのままdelegateだとhandに渡されてしまうため、自分のhandとotherのplayerを比較してしまうことになってしまいました。

ruby_poker/player.rb
    attr_reader :hand
    def <=>(other)
      @hand <=> other.hand
    end

おとなしく普通に実装しました。。

これで完了。楽ですねー

終わりに

今回は、勝敗などに関わる機能面での処理のみ実装しました。
ここから、ゲーム進行のことを考えるとコンソール出力回りを実装する必要もでますが、それは次の進行回りを検討するタイミングで追加するようにしていきたいと思います。

続き


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

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?