module Rlottery class Lottery attr_accessor :rule_set def initialize(args) [:participants, :slots].each do |attr| raise(ArgumentError, "Must supply #{attr}") unless args.has_key?(attr) end self.participants = args[:participants] self.slots = args[:slots] rule_set_klass = args[:rule_set] rule_set_klass ||= Rlottery::RuleSet::BaseRuleSet @rule_set = rule_set_klass.new( :participants => self.participants, :slots => self.slots ) end def run! @rule_set.run! end def participants @participants_list ||= {} end def slots @slots_list ||= {} end def rule_set @rule_set end def persist(filename) File.open(filename, 'w+') do |file| YAML.dump( self, file ) end end def self.load(filename) YAML.load_file filename end def ==(other) my_slots = self.slots.values other_slots = other.slots.values slots_are_equal = slots_equality?(my_slots, other_slots) return false unless slots_are_equal my_participants = self.participants.values other_participants = self.slots.values participants_are_equal = participants_equality?(my_slots, other_slots) return false unless participants_are_equal return true end protected def participants=(participants_list) @participants_list ||= {} list_init(Participant, participants_list, @participants_list) end def slots=(slots_list) @slots_list ||= {} list_init(Slot, slots_list, @slots_list) end def list_init(item_class, list, store_in) unless list.respond_to?(:each) raise ArgumentError, "Must supply a list for #{item_class} init." end list.each do |i| if i.kind_of?(String) || i.kind_of?(Symbol) item = item_class.new(:identifier => i) else raise ArgumentError, "Unknown kind of #{item_class}: #{i}." end store_in[item.identifier] = item end end private def slots_equality?(mine, theirs) generic_entity_equality?(mine, theirs) end def participants_equality?(mine, theirs) generic_entity_equality?(mine, theirs) end def generic_entity_equality?(mine, theirs) return false unless sizes_equal?(mine, theirs) return false unless keys_equal?(mine, theirs) mine.each do |i| my_item = i their_item = theirs.detect{ |t| t.identifier == i.identifier } return false unless their_item my_assignment_ids = i.assignments.map{ |a| a.identifier } their_assignment_ids = their_item.assignments.map{ |a| a.identifier } return false unless (my_assignment_ids - their_assignment_ids == []) end true end def sizes_equal?(mine, theirs) mine.size == theirs.size ? true : false end def keys_equal?(mine, theirs) my_entity_keys = mine.map{ |e| e.identifier } their_entity_keys = theirs.map{ |e| e.identifier } return false unless (my_entity_keys - their_entity_keys == []) return true end end end