通し番号方式に変えたブラックジャックプログラム

変更点を赤下線で示した。

#!/usr/koeki/bin/ruby

def createCardsArray()
  card=Array.new		# 空の配列を作る
  0.upto(51) do |x|		# ジョーカー不要なので51まで
    card << x
  end
  card				# 最後に card配列 を呼び主に返す
end

def shuffle(a)
  srand
  0.upto(a.length-1) do |i|
    j = rand(a.length-1)    # 交換相手をランダムに選ぶ
    w = a[i]
    a[i] = a[j]
    a[j] = w
  end
  a
end

def getSuite(n)		# 通し番号からスートに変える
  s = n/13
  ["ハート", "スペード", "ダイヤ", "クラブ"][s]
end

def dispCard(card)
  num = card%13 + 1		# 通し番号から数に変える
  cardN = case num
	  when 1
	    "A"
	  when 11
	    "J"
	  when 12
	    "Q"
	  when 13
	    "K"
	  else
	    num
	  end
  printf("%s の %s\n", getSuite(card), cardN)
end


def point(arr)
  ace = 0		# "A"の枚数
  sum = 0		# 合計点
  for card in arr	# arr配列全ての要素に対して繰り返す
    n = (card%13)+1	# 13で割った余りに1足したものが数
    case n		# nの値によって場合分け
    when 1		# "A"ならば…
      ace += 1		# 枚数カウンタを1増やしておく
      sum += 11		# まずは11点として加算
    when 10, 11, 12, 13
      sum += 10		# 絵札と10は10点
    else		# それ以外(つまり2〜9)はそのものを整数にして足す
      sum += n
    end # when終わり
  end # for終わり
  while sum > 21 && ace > 0 # 21より大きく、かつ、aceが1以上なら
    sum -= 10		# 10を引く
    ace -= 1		# aceを1つ使ったので減らす
  end
  sum
end

# カードを作ってシャッフルしたものを cards配列に格納
cards=shuffle(createCardsArray)

# カードを数える変数。-1で初期化
cardNo=-1

# コンピュータの持ちカードを格納する配列
com=[]
com << cards[cardNo+=1]
com << cards[cardNo+=1]

# プレイヤーの持ちカードを格納する配列
player=[]
player << cards[cardNo+=1]
player << cards[cardNo+=1]

# 最初の手持を表示する
puts "わたしの手:"
# コンピュータの1枚目を表示
puts "  [ ??? ]"
# コンピュータの2枚目を表示
dispCard(com[1])	# 2枚目は com[1] に入っている
# プレイヤー側
puts "あなたの手:"
dispCard(player[0])
dispCard(player[1])

# プレイヤーが満足するまで引かせる
while true
  STDERR.print "もう一枚引きますか?(yかnで) "
  answer = gets
  if /^y/i =~ answer
    player << cards[cardNo+=1]
    puts "もう一枚引きます。引いたカードはこれです。"
    dispCard(player[-1])
  else
    break		# while true を抜ける
  end
end

# コンピュータが16以下なら引き続ける
while point(com) <= 16
  puts "わたしはもう一枚引きます"
  com << cards[cardNo+=1]
end

# いよいよ勝負
puts "勝負!"
puts "わたしの手:"
for c in com		# コンピュータの手持カード全て繰り返す
  dispCard(c)
end
puts "あなたの手:"
player.each do |c|	# プレイヤーの手持カード全て繰り返す
  dispCard(c)
end

# 得点を比べる
cp, pp = point(com), point(player)
printf("わたし %d : %d あなた\n", cp, pp)

if cp >= 22		# 22以上なら0点ということにしてしまう
  cp = 0		# (コンピュータ)
end

if pp >= 22		# 22以上なら0点ということにしてしまう
  pp = 0		# (プレイヤー)
end

if pp > cp		# コンピュータより点が高ければ
  puts "あなたの勝ちです。参りました!"
else			# そうでなければ(引き分け含む)
  puts "わたしの勝ちです。べろべろばあ〜"
end


目次