summaryrefslogtreecommitdiff
path: root/app/models/tournament.rb
blob: bf44cdfbeff5adb7a063d83c0d6207216fa3cf32 (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
class Tournament < ActiveRecord::Base
	belongs_to :game
	has_many :matches
	has_many :settings_raw, class_name: "TournamentSetting"
	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"

	def matches_ordered
		h = {}
		i = 1
		matches.order(:id).each do |m|
			h[i] = m
			i += 1
		end
		return h
	end

	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
		@vartypes = {
			:true_false => 0,
			:integer => 1,
			:string => 2,
			:select => 3,
			:range => 4
		}

		def initialize(tournament)
			@tournament = tournament
		end

		def [](setting)
			p = @tournament.settings_raw.find_by_name(setting)
			if p.nil?
				return nil
			else
				return p.value
			end
		end

		def []=(setting, val)
			p = @tournament.settings_raw.find_by_name(setting)
			if p.nil?
				TournamentSetting.create( tournament_id: @tournament.id, vartype: get_type(val), name: setting, value: val )
			else
				p.value = val
			end
		end

		def get_type(val)
			case val
				when "true", "false"
					vartypes[:true_false]
				when /\d+-\d/ =~ val
					vartypes[:range]
				when /\d+/ =~ val
					vartypes[:integer]
				when /,/ =~ val
					vartypes[:select]
				else
					vartypes[:string]
			end
		end

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

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

	def open?
		return true
	end

	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

	def setup
		num_teams = (self.players.count/self.min_players_per_team).floor
		num_matches = num_teams - 1
		for i in 1..num_matches
			self.matches.create(name: "Match #{i}", status: 0, submitted_peer_evaluations: 0)
		end
		match_num = num_matches-1
		team_num = 0
		#for each grouping of min_players_per_team
		players.each_slice(min_players_per_team) do |players|

			#if the match is full, move to the next match, otherwise move to the next team
			if (team_num == min_teams_per_match)
				match_num -= 1
				team_num = 0
			else
				team_num += 1
			end
			#create a new team in the current match
			self.matches[match_num].teams.push(Team.create(users: players))
		end
	end
end