#!/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(quiet=true) # 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 "======================================================" unless quiet puts "#{@player} turned in #{@original_hand.inspect}." unless quiet # copy the hand so we can mess with it hand = @original_hand.dup # not allowed more suspects than witnesses if hand["suspects"] > hand["witnesses"] diff = hand["suspects"] - hand["witnesses"] puts "Discarding #{diff} suspects." unless quiet hand["suspects"] = hand["witnesses"] end # 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]}." unless quiet hand[hand_array[i]] = hand[hand_array[i]] - 1; discarded += 1 end puts "New hand is #{hand.inspect}." if discarded > 0 unless quiet # base scores base_scores = { "bullets" => 1, "fingerprints" => 2, "tips" => 3, "suspects" => 4, "witnesses" => 5 } # +10 points for first envelope turned in if @first_entry puts "+10 points for being the first entry." unless quiet 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." unless quiet hand_total += 10 end # 8 or more tips is 25 points if hand["tips"] >= 8 puts "+25 points for having 8 or more tips." unless quiet hand_total += 25 end # each set of 3 suspects and 1 witness score 10 points x = [ hand["suspects"]/3, hand["witnesses"] ].min if x > 0 puts "+#{x*10} points for #{x} set(s) of 3 suspects/1 witness" unless quiet 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, one tip will be doubled." unless quiet 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, one bullet will be quadrupled." unless quiet 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}" unless quiet 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." unless quiet end # input total puts "Total for #{@player}: #{hand_total}" unless quiet puts "======================================================" unless quiet puts " " unless quiet hand_total end end #best = 0 #14.times do |f| # 14.times do |t| # 14.times do |w| # 14.times do |s| # 14.times do |b| # hand = MurderHaggleHand.new("Test",b,f,t,s,w,true,true) # score = hand.score # if score > best # hand.score(false) # best = score # end # end # end # end # end #end # (player, bullets, fingerprints, tips, suspects, witnesses, first_entry=false, girl_entered=false) hands = [ MurderHaggleHand.new("Abe",2,0,0,2,1,false,false), MurderHaggleHand.new("Casey",0,3,5,0,0,false,false), MurderHaggleHand.new("Craig",1,2,0,3,4,false,false), MurderHaggleHand.new("Dundee",2,2,2,3,3,false,false), MurderHaggleHand.new("Eddy",6,3,2,2,0,false,true), MurderHaggleHand.new("Francois",2,2,2,1,1,false,true), MurderHaggleHand.new("Jon",9,1,0,0,0,false,false), MurderHaggleHand.new("Josh",0,3,2,4,1,false,false), MurderHaggleHand.new("Lonna",0,1,2,3,4,true,true), MurderHaggleHand.new("Mary Tess",0,2,1,3,4,false,true), MurderHaggleHand.new("Mike",1,0,0,0,0,false,false), MurderHaggleHand.new("Nate",0,3,1,3,3,false,false), MurderHaggleHand.new("PJ",0,3,8,0,2,false,false), MurderHaggleHand.new("Shae",0,2,3,4,4,false,true), ] hands.sort { |a,b| b.score <=> a.score }.each do |h| h.score(false) end