summaryrefslogtreecommitdiff
path: root/app/models/tournament.rb
blob: b867716487ab86dce7744fa2cac2e694d4ed3cca (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
class Tournament < ActiveRecord::Base
	belongs_to :game
	has_many :tournament_stages
	has_many :brackets
	has_many :tournament_settings
	has_and_belongs_to_many :players, class_name: "User", association_foreign_key: "player_id", join_table: "players_tournaments"
	has_and_belongs_to_many :hosts,   class_name: "User", association_foreign_key: "host_id",   join_table: "hosts_tournaments"

	alias_attribute :stages, :tournament_stages

	before_save { self.status ||= 0 }

	# Settings #################################################################

	def settings
		@settings ||= Settings.new(self)
	end

	def settings=(setting)
		setting.each do |key, value|
			value = false if value == "0"
			settings[key] = value
		end
	end

	class Settings
		def initialize(tournament)
			@tournament = tournament
		end

		def [](setting_name)
			tournament_setting = @tournament.tournament_settings.find{|s|s.name==setting_name}
			if tournament_setting.nil?
				return nil
			else
				return tournament_setting.value
			end
		end

		def []=(setting_name, val)
			tournament_setting = @tournament.tournament_settings.find{|s|s.name==setting_name}
			if tournament_setting.nil?
				game_setting = @tournament.game.settings.find_by_name(setting_name)
				@tournament.tournament_settings.build(name: setting_name, value: val,
					vartype:       game_setting.vartype,
					type_opt:      game_setting.type_opt,
					description:   game_setting.description,
					display_order: game_setting.display_order)
			else
				tournament_setting.value = val
			end
		end

		def keys
			@tournament.tournament_settings.all.collect { |x| x.name }
		end

		def empty?() keys.empty? end
		def count() keys.count end
		def length() count end
		def size() count end

		def method_missing(name, *args)
			if name.to_s.ends_with?('=')
				self[name.to_s.sub(/=$/, '').to_s] = args.first
			else
				return self[name.to_s]
			end
		end
	end

	# Misc. ####################################################################

	def open?
		return true
	end

	# Joining/Leaving ##########################################################

	def joinable_by?(user)
		return (open? and user.can?(:join_tournament) and !players.include?(user))
	end

	def join(user)
		unless joinable_by?(user)
			return false
		end
		players.push(user)
	end

	def leave(user)
		if players.include?(user) && status == 0
			players.delete(user)
		end
	end

	# Configured methods #######################################################

	def scoring
		@scoring ||= "Scoring::#{self.scoring_method.camelcase}".constantize
	end

	# YISSSSSS

	def scoring_methods
		make_methods "scoring"
	end

	def sampling_methods
		make_methods("sampling").select do |name|
			"Sampling::#{name.camelcase}".constantize.works_with?(self.game)
		end
	end

	def scheduling_methods
		make_methods "scheduling"
	end

	def seeding_methods
		make_methods "seeding"
	end

	private
	def make_methods(dir)
		@@methods ||= {}
		if @@methods[dir].nil? or Rails.env.development?
			@@methods[dir] = Dir.glob("#{Rails.root}/lib/#{dir}/*.rb").map{|filename| File.basename(filename, ".rb") }
		end
		return @@methods[dir]
	end
end