#!/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