ドロー・ポーカーの Ruby プログラム
以下は、Ruby によるドロー・ポーカーのプログラムの一例です。
#!/usr/bin/env ruby
BEGIN {
}
END {
}
class Stack
#定数
#なし
#クラス変数
#なし
#クラスメソッド
#なし
#インスタンスメソッド
def initialize(ndeck)
#インスタンス変数
@stack = Array.new#カードの山
deck = Array.new#1 組 52 枚のカード
0.upto(Card::IMAX - 1) do |i|
deck.push(i)
end
0.upto(ndeck - 1) do
deck.each do |x|
@stack.push(x)
end
end
end
#カードを混ぜる
def shuffle()
if (RUBY_VERSION >= '1.8.7')
@stack.shuffle!
else
@stack = @stack.sort_by{rand}
end
end
def next()
return(@stack.shift)
end
def size()
return(@stack.size)
end
#アクセスメソッド(アクセサ)
#なし
end
class Card
#定数
IMAX = 52#1 組 52 枚のカード
SUITS = [ #カードの印
'S',#spade
'H',#heart
'D',#diamond
'C' #club
]
#クラス変数
#なし
#クラスメソッド
def self.suit(card)
return((card % IMAX) / 13)
end
def self.number(card)
return((card % IMAX) % 13)
end
#インスタンスメソッド
#なし
#アクセスメソッド(アクセサ)
#なし
end
class Game#トランプゲーム
#定数
NDECK = 1
#クラス変数
#なし
#クラスメソッド
#トランプゲームを行う
def self.run(stack)
#カードを混ぜる
stack.shuffle()
end
#カードを画面に表示する
def self.display(player, pre = '', post = '', from = 0, to = player.size - 1)
STDERR.print pre
from.upto(to) do |i|
STDERR.printf "%s%02d", Card::SUITS[Card.suit(player[i])], Card.number(player[i]) + 1
STDERR.print ", " if (i != to)
end
STDERR.print post, "\n"
end
#インスタンスメソッド
#なし
#アクセスメソッド(アクセサ)
#なし
end
class Poker < Game#ポーカーはトランプゲームのサブクラス
#定数
HANDS = [#役の種類
'No Pair',
'One Pair',
'Two Pair',
'Three of a Kind',
'Straight',
'Flush',
'Full House',
'Four of a Kind',
'Straight Flush',
'Royal Straight Flush'
]
#クラス変数
#なし
#クラスメソッド
#役を確認する
def self.check(player)
npair = 0 #ペアの数
s = Array.new(Card::SUITS.size, 0)#印毎の枚数
n = Array.new(13, 0)#数字毎の枚数
flag = Hash.new #確認フラグ
player.each do |x|
#番号をカードに換算し、印と数字の枚数を追加する
s[Card.suit (x)] += 1
n[Card.number(x)] += 1
end
#フラッシュ系
flag['flush'] = flush?(player, s)#フラッシュの確認フラグ
#ストレート系
0.upto(9) do |i|#ストレートの低位の数字は 1 から 10 まで
if (straight?(player, i, n))
if (flag['flush'])
if (i == 9)
return(9)#ロイヤル・ストレート・フラッシュ
else
return(8)#ストレート・フラッシュ
end
else
return(4)#ストレート
end
break
end
end
return(5) if (flag['flush'])#フラッシュ
#ペア系
flag['three'] = false#スリーカードの確認フラグ
0.upto(12) do |i|
if (n[i] == 4)
return(7)#フォーカード
elsif (n[i] == 3)
flag['three'] = true
elsif (n[i] == 2)
npair += 1
end
end
if (flag['three'])
if (npair == 1)
return(6)#フルハウス
else
return(3)#スリーカード
end
else
if (npair == 2)
return(2)#ツーペア
elsif (npair == 1)
return(1)#ワンペア
end
end
return(0)#ノーペア
end
def self.flush?(player, s)
0.upto(s.size - 1) do |i|
return(true) if (s[i] == player.size)
end
return(false)
end
def self.straight?(player, i, n)
0.upto(player.size - 1) do |j|
return(false) if (n[(i + j) % 13] != 1)#13 は 1 と連なる
end
return(true)
end
#インスタンスメソッド
#なし
#アクセスメソッド(アクセサ)
#なし
end
class Draw < Poker#ドロー・ポーカーはポーカーのサブクラス
#定数
NDECK = 1#実際のカジノでは、6 デックを 1 スタックとすることが多い
#(ブラックジャックの場合)
M = 5#手札の枚数
N = 5#交換可能な枚数
#クラス変数
#なし
#クラスメソッド
#ドロー・ポーカーを行う
def self.run()
stack = Stack.new(NDECK)#カードの山
player = Array.new #プレーヤーの手札
super(stack)
#カードを配る
0.upto(M - 1) do
player.push(stack.next())
end
#カードを画面に表示する
display(player)
#カードを交換する
change(player, stack)
#カードを画面に表示する
display(player)
#役を確認する
STDERR.printf "%s\n", HANDS[check(player)]
end
#カードを交換する
def self.change(player, stack)
nflag = 0 #真の flag の数
flag = Array.new(player.size, false)#カードの交換フラグ
#交換するカードを決定する
loop do
STDERR.print "Please select the card(s) you want to change (1 - 5). "
STDERR.print "To finish, input 0.\n"
i = gets.chomp
if (i =~ /^[1-M]$/)
if (flag[i.to_i - 1])
next
else
flag[i.to_i - 1] = true
end
nflag += 1
break if (nflag == N)
# elsif (i =~ /^0$/)
elsif (i == '0')#正規表現より処理が早い
break
else
STDERR.print "Input Error!\n"
end
end
#カードを交換する
0.upto(player.size - 1) do |i|
player[i] = stack.next() if (flag[i])
end
end
#インスタンスメソッド
#なし
#アクセスメソッド(アクセサ)
#なし
end
#関数的メソッド
#なし
#トップレベル
#定数
#なし
#グローバル変数
#なし
#ローカル変数
#なし
Draw.run()
exit(0)#正常終了
各クラスや各メソッドについて、以下に説明します。
- トランプ・ポーカー
- トランプ・ブラックジャック
- ギャンブルから株式為替まで役立つ資金管理
- 株式投資や為替取引のリスクマネジメント
- カード被害が預金者保護法で補償された体験
- アニメで英会話/台詞逆輸入
- 右脳と左脳を鍛える開発トレーニング