ヒットアンドブローのスクリプトができた
でもひどいコードかも。。
ヒットアンドブローは、コンピュータの用意した数字の並びを当てるゲーム。
コンピュータは、こちらが考えた数字の並びと自分のものを比較して、
次の2つのヒントをくれる。
- HIT: 数字も場所も合っているものの数
- BLOW: 数字は合っているが場所は合っていないものの数
例えば、コンピュータの用意した数字の並びが4278で、
プレイヤーが考えた数字が4321だったときは、HIT:1 BLOW:1となる。
全部をHITにできれば勝ち。
また、今回は同じ数字を使ってもいいようにしてみた。
(そのせいで手こずった・・・。)
=begin ヒットアンドブロー <概要> コンピュータの用意した数字の並びと同じ数字の並びをつくれば勝ち HIT: 数字も場所も合っている BLOW: 数字は合っているが場所は合っていない <usage> > ruby hit-and-blow.rb [size] [size]でいくつの数字の並びなのかを指定できる(デフォルトは4) =end # 複数の数字の管理をする class Numbers def initialize(size = 4) @size = size.to_i @numbers = Array.new # コンピュータの用意する数字の並び @size.times{ @numbers << rand(10) } end # カードの表示 def disp puts "com> #{@numbers}" end # コンピュータの用意した数字の並びとプレイヤーの数字の並びを比較する def compare(ply) # コンピュータとプレイヤーの用意した各数字の間にリンクを考える # 対応する数字同士はリンクする links = Array.new @size.times{ link = Hash.new link['to'] = nil link['type'] = nil links << link } @size.times{|c| @size.times{|p| # toがpで、typeがhitのLinkが存在する場合はply[p]をパス next if links.detect{|l| l['to'] == p and l['type'] == 'hit'} if @numbers[c] == ply[p].to_i links[c]['to'] = p if c == p if l = links.detect{|l| l['to'] == p and l['type'] == 'blow'} l['to'] = l['type'] = nil end links[c]['type'] = 'hit' break # 'hit'が分かったら、そのcom[c]の処理は終了 else links[c]['type'] = 'blow' end end } } hit = blow = 0 links.each{|l| hit += 1 if l['type'] == 'hit' blow += 1 if l['type'] == 'blow' } puts " HIT:#{hit} BLOW:#{blow}" if hit == @size puts "Congratution!!" exit end end end size = ARGV.shift || 4 com = Numbers.new(size) puts "#{size}つのランダムな数字の並びを当ててください。" loop{ print "ply> " line = gets line.chomp! exit if /^e/ =~ line com.disp if /^d/ =~ line com = Numbers.new if /^r/ =~ line unless /^\d{#{size}}$/ =~ line puts "#{size}つの数字を指定してください。" next end ply = line.split(//) # プレイヤーの用意する数字の並び # 比較のために配列にする必要がある com.compare(ply) }
今回、僕は自分で思っているよりもプログラムが書けないことに気づいた。
もっと色々自分で考えて書いてみないとダメだと思った。
だからもっと色々自分で考えて書いてみようと思う。