I got the Coin Flip program to work! Note that there are a few methods in here that I have implemented but not used, this is fairly normal. So for instance when writing the Coin class, it seemed obvious to be able to turn a coin over, not just flip it, but I don't need that right now.
require 'optparse'
class Coin
attr_reader :face, :value
@@FaceRange = [0, 1]
@@ValidValues = [1, 2, 5, 10, 20, 50, 100, 200]
@@prng = Random.new # Pseudo-random Number Generator
# Default Face to an illegal value so that it will flip the coin
def initialize (value=10, face=-1) # CONSTRUCTOR
self.value = value
self.face = face
end
def face= (new_face) # Set a valid face
@face ||= 0 # default
if @@FaceRange.include? new_face
@face = new_face
else
self.flip
end
end
def value= (new_value) # Set a valid value
@value ||= 1 # default
@value = new_value if @@ValidValues.include? new_value
end
def set_face (new_face) # Set face to a chosen value
@face = new_face if [0, 1].include? new_face
end
def turn # Turn the coin over
@face = (@face + 1).modulo(2)
end
def flip # Flip the coin
@face = @@prng.rand(0..1)
end
def to_s # Over-ride the to_s method inherited from the Object class
"Value is #{@value} Face is #{@face}"
end
end
class CList
attr_reader :size
def initialize (size=10)
@size = size
@coins = []
(1..size).each do |i|
@coins.push(Coin.new)
end
end
def flip
@coins.each do |coin|
coin.flip
end
end
def countheads
heads = 0
@coins.each do |coin|
heads += 1 if coin.face == 1
end
heads
end
def to_s
@coins.each do |coin|
puts coin
end
"Total #{@coins.length}"
end
end
options = {}
OptionParser.new do |opts|
opts.banner = "Usage: clist.rb [options]"
opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
options[:verbose] = v
end
opts.on("-c", "--coins [CCOUNT]", "Number of coins to flip") do |c|
options[:count] = c.to_i
end
opts.on("-f", "--flips [FCOUNT]", "Number of flips") do |f|
options[:flips] = f.to_i
end
end.parse!
ccount = options[:count] # Number of coins
fcount = options[:flips] # Number of flips
puts "Flipping a row of #{ccount} coins #{fcount} times"
my_list = CList.new(ccount)
hoccurs = Array.new(ccount)
(0..hoccurs.length).each { |i| hoccurs[i] = 0 } # Zero Array
(1..fcount).each do
my_list.flip
hoccurs[my_list.countheads] += 1
end
(0..hoccurs.length-1).each do |i|
times="times"
times="time" if hoccurs[i] == 1
puts "Flipped #{i} heads #{hoccurs[i]} #{times}" if hoccurs[i] > 0
end
Here is how to run it:
If we want 10 coins and 40 flips:
$ ruby clist.rb -c 10 -f 40
Flipping a row of 10 coins 40 times
Flipped 2 heads 2 times
Flipped 3 heads 4 times
Flipped 4 heads 10 times
Flipped 5 heads 10 times
Flipped 6 heads 9 times
Flipped 7 heads 5 times
tjinkers@TJINKERS-LAP ~/ruby
$
But it's much more fun with bigger numbers than that
No comments:
Post a Comment