# thanks to Eric Davis for the base lottery code http://gist.github.com/164109
require 'ostruct'
class BugMashLottery
PRIZE_LIMIT = 2
attr_accessor :tickets
# http://wiki.railsbridge.org/projects/railsbridge/wiki/BugMash
def prizes
[
OpenStruct.new(:sponsor => "Jeff Cohen", :prize => "$100-off coupon code for any public Purple Workshops workshop"),
OpenStruct.new(:sponsor => "Mike Mangino", :prize => "Developing Facebook Platform Applications with Rails"),
OpenStruct.new(:sponsor => "Mike Gunderloy", :prize => "Rails Rescue Handbook"),
OpenStruct.new(:sponsor => "Mike Gunderloy", :prize => "Rails Freelancing Handbook"),
OpenStruct.new(:sponsor => "Noel Rappin", :prize => "Copy #1: Rails Test Prescriptions"),
OpenStruct.new(:sponsor => "Noel Rappin", :prize => "Copy #2: Rails Test Prescriptions"),
OpenStruct.new(:sponsor => "Jeremy McAnally", :prize => "Signed copy of Ruby in Practice"),
OpenStruct.new(:sponsor => "Luke Crawford", :prize => "$100 credit at Prgmr (VPS hosting)"),
OpenStruct.new(:sponsor => "ENTP", :prize => "Copy #1: 1yr Lighthouse (bronze)"),
OpenStruct.new(:sponsor => "ENTP", :prize => "Copy #2: 1yr Lighthouse (bronze)"),
OpenStruct.new(:sponsor => "ENTP", :prize => "Copy #3: 1yr Lighthouse (bronze)"),
OpenStruct.new(:sponsor => "ENTP", :prize => "Copy #1: 1yr Tender Support (plus)"),
OpenStruct.new(:sponsor => "ENTP", :prize => "Copy #2: 1yr Tender Support (plus)"),
OpenStruct.new(:sponsor => "ENTP", :prize => "Copy #3: 1yr Tender Support (plus)"),
OpenStruct.new(:sponsor => "ActionRails", :prize => "1 month (4 hours) of Developer Hotline support"),
OpenStruct.new(:sponsor => "RimuHosting", :prize => "Copy #1: $200 VPS hosting credits"),
OpenStruct.new(:sponsor => "RimuHosting", :prize => "Copy #2: $200 VPS hosting credits"),
OpenStruct.new(:sponsor => "RimuHosting", :prize => "Copy #3: $200 VPS hosting credits"),
OpenStruct.new(:sponsor => "Exceptional", :prize => "1-year Mini plan in the prize pool"),
OpenStruct.new(:sponsor => "Devver", :prize => "Copy #1: Beta invite"),
OpenStruct.new(:sponsor => "Devver", :prize => "Copy #2: Beta invite"),
OpenStruct.new(:sponsor => "Devver", :prize => "Copy #3: Beta invite"),
OpenStruct.new(:sponsor => "Slicehost", :prize => "$100 hosting credit"),
OpenStruct.new(:sponsor => "GitHub", :prize => "Copy #1: one-year Medium account"),
OpenStruct.new(:sponsor => "GitHub", :prize => "Copy #2: one-year Medium account"),
OpenStruct.new(:sponsor => "GitHub", :prize => "Copy #3: one-year Medium account"),
OpenStruct.new(:sponsor => "Uservoice", :prize => "Two months of gold service"),
OpenStruct.new(:sponsor => "Sterling Rose Design", :prize => "Ten hours of free design work on any project")
]
end
def bugmash_participants
{
'David Reese' => 50,
'jonnii' => 50,
'Yugui (Yuki Sonoda)' => 50,
'blatyo (at gmail)' => 25,
'Michael Siebert' => 1050,
'Adrien Pestel' => 50,
'Larry Sprock' => 50,
'Rizwan Reza' => 9100,
'Brendan Schwartz' => 1000,
'anupom syam' => 25,
'Wesley Moxam' => 100,
'Dan Pickett' => 1575,
'Ryan Bigg' => 175,
'stevestmartin' => 3450,
'Matt Duncan' => 5350,
'Josh Sharpe' => 1175,
'railsbob' => 2400,
'wmoxam' => 1000,
'Derander' => 1825,
'pjammer' => 300,
'qmx' => 75,
'Nikolay Petrachkov ' => 1725,
'Kieran P' => 525,
'Cristi Balan' => 2150,
'dira' => 400,
'Nick Quaranto' => 2250,
'gsterndale' => 575,
'David Trasbo' => 650,
'Bas Van Klinkenberg' => 1000,
'Josh Nichols' => 6400,
'Niklas Holmgren' => 1000,
'jamesw' => 50,
'John Trupiano' => 225,
'Adam Keys' => 225,
'Leandro Heuert' => 50,
'Edd Morgan' => 75,
'Sam Goldstein' => 25,
'jzw' => 1000,
'Dan Croak' => 4075,
'chucknelson' => 25,
'Rajesh' => 325,
'Gabe da Silveira' => 4050,
'Alexey Poimtsev' => 50,
'Hugo Peixoto' => 7200,
'Rebecca Frankel' => 225,
'Arthur Zapparoli' => 2475,
'Simon Jefford' => 325,
'AmundS' => 25,
'John Pignata' => 200,
'Daniel Rice' => 50,
'Dmitry Ratnikov' => 1125,
'Tristan Dunn' => 4875,
'Rob' => 1000,
'Jon Wood' => 1000,
'bastilian' => 1000,
'Marc-Andre Lafortune' => 1000,
'Peer Allan' => 175,
'Jatinder Singh' => 2575,
'Ed Ruder' => 125,
'RomKo' => 75,
'Rich Bradley' => 1000,
'Geoff Jacobsen' => 100,
'Elise Huard' => 1550,
'Christian Seiler' => 50,
'Felipe Talavera' => 1275,
'Matt Conway' => 1000,
'Marshall Huss' => 1025,
'ThePhred' => 100,
'Casper' => 50,
'Nathan Humbert' => 25,
'Roy Nicholson' => 1000,
'David Burger' => 1000,
'Erik' => 50,
'feldercarb' => 50,
'Adam Bair' => 225,
'Jordan Brough' => 1000,
'Vladimir Meremyanin' => 1000,
'Grzegorz Forysinski' => 1000,
'Max Lapshin' => 1000,
'jeem' => 1000,
'Erik Ostrom' => 1225,
'Prem Sichanugrist' => 1000,
'barunio' => 50,
'Morgan Schweers' => 1000,
'Jaime Bellmyer' => 1000,
'Leonardo Borges' => 1000,
'Daniel Sheppard' => 1000,
'Jay Pignata' => 1000,
'Fabien Jakimowicz' => 1000,
'Jeff Dean' => 1000,
'Steve H' => 50,
'Tim Peters' => 1000,
'Kamal Fariz Mahyuddin' => 1000,
'codeape' => 1000,
'Casey Rosenthal' => 175
}
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