Big/Smallゲーム再考
id:hrkt0115311 さん原作のBig/Smallゲームのソースを昨日考えさえていただいたが、自分で1から書いたらどう書くだろう?と想ってリファクタリングしてみた。
条件は以下の通りとした。
- 山札は53枚でジョーカーが1枚
- 山札から2枚引いて判定するので同じカードは出てこない
- ジョーカーは最強のカード
- スートの種類は強さの判定には影響が無く、数字のみが意味を持つ
- 数字の強さは、エースが最も強く、後はK,Q,J,10,9...の順に数字が大きいほど強い
- 勝敗のメッセージは単純化する
追記:カードの強さ判定で、2つの山札からカードを引いた場合に両方にジョーカーがあり得る事を考慮してなかったので、判定ロジックを修正
追記2(2008.05.27):カード強さの判定で順番に依存する部分がスマートでなかったので少し修正
#山札処理系クラス class Deck def initialize @card = (0...53).map {|i|i} end def draw #カード残りが無いならnil return nil if @card.empty? #カード抽出 tar = rand(@card.size) card = Card.new(@card[tar]) @card.delete_at(tar) return card; end #カードクラス class Card attr_reader :card def initialize (no) @suit_name = %w!ハート クラブ クローバー スペード! @num_name = %w!エース 2 3 4 5 6 7 8 9 10 J Q K! @card = no end #自分がJokerならtrueを返す def joker? (@card == 52) ? true : false end #自分のカード名称を返す def name self.joker?() ? "ジョーカー" : "%sの%s" % [@suit_name[@card/13],@num_name[@card%13]] end def >(tar_card) if tar_card.joker? return false elsif self.joker? return true elsif (self.card % 13 ) == 0 and (tar_card.card % 13 != 0) return true elsif (self.card % 13 ) != 0 and (tar_card.card % 13 == 0) return false end return (self.card % 13 > tar_card.card % 13) ? true : false end def <(tar_card) self > tar_card ? false : true end def ==(tar_card) #同じ番号なら同じカード(2デッキ以上を想定) if self.card == tar_card.card return true #両方ともジョーカーだったら同じカード(山札にジョーカーが2枚以上になった場合を想定) elsif self.joker? and tar_card.joker? return true #片方だけがジョーカーならちがうカード elsif (true == self.joker? and false == tar_card.joker? ) or (false == self.joker? and true == tar_card.joker?) return false; end return (self.card % 13 == tar_card.card % 13) ? true : false end end end #カードを最初に引いておく deck = Deck.new first_card = deck.draw second_card = deck.draw #ゲーム開始のメッセージ表示 puts <<MESSAGE ひとつ、運試しをしませんか? これから2枚のカードを引きます 最初のカードが大きければあなたの負け、逆ならあなたの勝ちです。 それでははじめましょう。 MESSAGE #メッセージ表示後の停止 sleep 2 #最初のカードを表示 if first_card.joker? puts "残念ジョーカーです。あなたの負けです。" puts "でも、ジョーカーをいきなり引当るなんて、" puts "逆に、ついてるかもしれませんね!" puts "どうぞよい一日を!!" exit else puts "%sです。" % first_card.name puts "次のカードを引きます。" puts "このカードより大きければあなたの勝ちです。" end #初期表示したので停止 sleep 2 #2枚目表示 puts "%sです。" % second_card.name #判定表示 if second_card == first_card puts "引き分けです。今日もよい一日を!" elsif second_card > first_card puts "あなたの勝ちです。今日もよい一日を!" else puts "あなたの負けです。お疲れさまでした。今日もよい一日を!" end