Files
game-scoring-scripts/murder-haggle/score.rb
T
2010-10-03 18:59:24 -07:00

125 lines
3.3 KiB
Ruby
Executable File

#!/usr/bin/env ruby
class MurderHaggleHand
def initialize(player, bullets, fingerprints, tips, suspects, witnesses, first_entry=false, girl_entered=false)
# build a hand
@player = player
@original_hand = {
'bullets' => bullets,
'fingerprints' => fingerprints,
'tips' => tips,
'suspects' => suspects,
'witnesses' => witnesses,
}
@first_entry = first_entry
@girl_entered = girl_entered
end
def score
# seed the same so we always get the same results!
srand(32472)
# track the total score
hand_total = 0
card_multipliers = { "bullets" => [], "fingerprints" => [], "tips" => [], "suspects" => [], "witnesses" => [] }
puts "======================================================"
puts "#{@player} turned in #{@original_hand.inspect}."
# copy the hand so we can mess with it
hand = @original_hand.dup
# no more than 13 cards allowed
hand_size = hand.values.inject(0) { |sum,n| sum+n }
discarded = 0
(hand_size-13).times do
hand_array = hand.collect { |k,v| [k]*v }.flatten
i = rand(hand_array.size)
puts "Hand too big... discarding 1 #{hand_array[i]}."
hand[hand_array[i]] = hand[hand_array[i]] - 1;
discarded += 1
end
puts "New hand is #{hand.inspect}." if discarded > 0
# base scores
base_scores = { "bullets" => 1, "fingerprints" => 2, "tips" => 3, "suspects" => 4, "witnesses" => 5 }
# not allowed more suspects than witnesses
if hand["suspects"] > hand["witnesses"]
diff = hand["suspects"] - hand["witnesses"]
puts "Discarding #{diff} suspects."
hand["suspects"] = hand["witnesses"]
end
# +10 points for first envelope turned in
if @first_entry
puts "+10 points for being the first entry."
hand_total += 10
end
# +10 points for envelope turned in by girls
if @girl_entered
puts "+10 points for being turned in by a girl."
hand_total += 10
end
# 8 or more tips is 25 points
if hand["tips"] >= 8
puts "+25 points for having 8 or more tips."
hand_total += 25
end
# each set of 4 suspects and 1 witness score 10 points
x = [ hand["suspects"]/4, hand["witnesses"] ].min
if x > 0
puts "+#{x*10} points for #{x} set(s) of 4 suspects/1 witness"
hand_total += x*10
end
# each set of 3 fingerprints doubles one tip
(hand["fingerprints"]/3).times do
card_multipliers["tips"] << 2
puts "Detected a set of 3 fingerprints, 1 tip will be doubled."
end
# each set of 2 suspects quadruples the value of one bullet casing
(hand["suspects"]/2).times do
card_multipliers["bullets"] << 4
puts "Detected a set of 2 suspects, 1 bullet will be quadrupled."
end
# now sum up score
hand.each do |k,v|
v.times do
multiplier = card_multipliers[k].shift || 1
base = base_scores[k]
points = base * multiplier
mult_string = multiplier > 1 ? " multiplied by #{multiplier}." : "."
puts "+#{points} points for 1 #{k} card#{mult_string}"
hand_total += points
end
end
# pyramid
sorted_counts = hand.values.sort.select { |x| x > 0 }
if sorted_counts == [1,2,3,4]
hand_total *= 2
puts "You have a pyramid, hand value will double."
end
# input total
puts "Total for #{@player}: #{hand_total}"
puts "======================================================"
print " "
end
end
MurderHaggleHand.new("Steve",5,5,5,5,5).score
MurderHaggleHand.new("Steve",0,3,2,1,4,true,true).score