# thanks to Eric Davis for the base lottery code http://gist.github.com/164109
require 'ostruct'
class BugMashLottery
PRIZE_LIMIT = 1
attr_accessor :tickets
# http://wiki.railsbridge.org/projects/railsbridge/wiki/BugMash
def prizes
[
OpenStruct.new(:sponsor => "Mike Gunderloy", :prize => "Rails Rescue Handbook"),
OpenStruct.new(:sponsor => "Mike Gunderloy", :prize => "Rails Freelancing Handbook"),
OpenStruct.new(:sponsor => "Blue Box Group", :prize => "1 TB Time Capsule courtesy"),
OpenStruct.new(:sponsor => "Less Everything", :prize => "1 Annual Subscription to Less Accounting"),
OpenStruct.new(:sponsor => "Less Everything", :prize => "1 Annual Subscription to Less Time Spent"),
OpenStruct.new(:sponsor => "Peepcode Screencasts", :prize => "1 Credit"),
OpenStruct.new(:sponsor => "Peepcode Screencasts", :prize => "1 Credit"),
OpenStruct.new(:sponsor => "Little Stream Software", :prize => '1 set of books "Producing Open Source Software: How to Run a Successful Free Software Project" and "The Art of Community: Building the New Age of Participation'),
OpenStruct.new(:sponsor => "EngineYard", :prize => "1 Tee Shirt"),
OpenStruct.new(:sponsor => "EngineYard", :prize => "1 Tee Shirt"),
]
end
def bugmash_participants
{
'Elad Meidar' => 2950,
'John Trupiano' => 2375,
'sr.iniv.t' => 2125,
'Jay Pignata' => 2000,
'Matías Flores' => 1750,
'Elomar França' => 1550,
'John Pignata' => 1000,
'Luciano G Panaro' => 1000,
'Matias Flores' => 1000,
'Gaius Centus Novus' => 700,
'Blue Box Jesse' => 625,
'hsume2' => 450,
'Blue Box Stephen' => 450,
'Robert Rouse' => 375,
'Joe Van Dyk' => 375,
'Kieran P' => 325,
'dira' => 325,
'David Trasbo' => 300,
'Akira Matsuda' => 300,
'hsume2 (Henry)' => 275,
'Mike Enriquez' => 225,
'Lena Herrmann' => 175,
'John Guenin' => 175,
'Blue Box Chris' => 175,
'Daniel Hofstetter' => 175,
'Ken Richard' => 150,
'kolo' => 150,
'rbxbx' => 125,
'Lawrence Pit' => 125,
'Pat Allan' => 100,
'Chad Woolley' => 100,
'jroes' => 100,
'Jordan Brough' => 100,
'Erik Ostrom' => 75,
'andhapp' => 75,
'Ed Schmalzle' => 75,
'luciano.panaro' => 75,
'Elise Huard' => 75,
'rishav' => 75,
'MOROHASHI Kyosuke' => 75,
'Ben Woodcroft' => 50,
'Alex Kahn' => 50,
'Eloy Duran' => 50,
'Sam Ruby' => 50,
'John Woods' => 50,
'Nikolai Lugovoi' => 50,
'Claudio Poli' => 50,
'Josh Sharpe' => 25,
'Jakub Kuźma' => 25,
'Matt Jones' => 25,
'qmx' => 25,
'cohitre' => 25,
'Stephen Blackstone' => 25
}
end
def generate_tickets(participants)
tickets = []
participants.each do |participant, points|
number_of_tickets = (points.to_f / 100.0).ceil
(1..number_of_tickets).each do
tickets << participant
end
end
@tickets = tickets.sort_by {rand}
end
def pull_winners(participants=nil)
participants ||= bugmash_participants
generate_tickets(participants)
winners = []
prizes.each do |prize|
lucky_winner = @tickets.pop
while has_already_won_prize_from_sponsor?(lucky_winner, prize, winners)
put_ticket_back_in_lottery(lucky_winner)
lucky_winner = @tickets.pop
end
winners << OpenStruct.new(:participant => lucky_winner, :prize => prize)
remove_participant_from_lottery(lucky_winner) if has_reached_prize_limit?(lucky_winner, winners)
end
winners
end
def remove_participant_from_lottery(participant)
@tickets = @tickets.reject {|p| p == participant}
end
def has_reached_prize_limit?(participant, winners)
prize_count = winners.select {|winner| winner.participant == participant}
prize_count.size == PRIZE_LIMIT
end
def has_already_won_prize_from_sponsor?(participant, prize, winners)
winners.select {|winner| winner.participant == participant}.detect {|winner| winner.prize.sponsor == prize.sponsor}
end
def put_ticket_back_in_lottery(ticket)
@tickets.insert(rand(@tickets.size - 1), ticket)
end
def run_lottery
pull_winners.each do |winner|
puts "#{winner.participant} has won #{winner.prize.prize} from #{winner.prize.sponsor}"
end
end
end