7 return SwissPairing.new
8 #return ExcludeSacrifice.new(SwissPairing.new)
9 #return RandomPairing.new
10 #return ExcludeSacrifice.new(RandomPairing.new)
16 log_message("Floodgate[%s]: too few players [%d]" %
17 [self.class, players.size])
19 log_message("Floodgate[%s]: found %d players. Pairing them..." %
20 [self.class, players.size])
24 def start_game(p1, p2)
27 Game.new(p1.game_name, p1, p2)
30 def include_newbie?(players)
31 return players.find{|a| a.rate == 0} == nil ? false : true
34 def delete_player_at_random(players)
35 return players.delete_at(rand(players.size))
38 def delete_player_at_random_except(players, a_player)
39 candidates = players - [a_player]
40 return delete_player_at_random(candidates)
43 def delete_most_playing_player(players)
44 # TODO ??? undefined method `<=>' for nil:NilClass
45 max_player = players.max {|a,b| a.win + a.loss <=> b.win + b.loss}
46 return players.delete(max_player)
49 def delete_least_rate_player(players)
50 min_player = players.min {|a,b| a.rate <=> b.rate}
51 return players.delete(min_player)
54 def pairing_and_start_game(players)
55 return if players.size < 2
56 if players.size % 2 == 1
57 log_warning("#Players should be even: %d" % [players.size])
60 sorted = players.sort{ rand < 0.5 ? 1 : -1 }
62 pairs = [[sorted.shift]]
63 while !sorted.empty? do
64 if pairs.last.size < 2
65 pairs.last << sorted.shift
67 pairs << [sorted.shift]
71 start_game(pair.first, pair.last)
76 class RandomPairing < Pairing
79 return if players.size < 2
81 if players.size % 2 == 1
82 delete_player_at_random(players)
84 pairing_and_start_game(players)
88 class SwissPairing < Pairing
91 return if players.size < 2
93 win_players = players.find_all {|a| a.last_game_win?}
94 remains = players - win_players
95 if win_players.size >= 2
96 if win_players.size % 2 == 1
97 if include_newbie?(win_players)
98 remains << delete_player_at_random(win_players)
100 remains << delete_least_rate_player(win_players)
103 pairing_and_start_game(win_players)
105 remains.concat(win_players)
107 return if remains.size < 2
108 if remains.size % 2 == 1
109 delete_player_at_random(remains)
110 # delete_most_playing_player(remains)
112 pairing_and_start_game(remains)
116 class ExcludeSacrifice
117 attr_accessor :sacrifice
119 def initialize(pairing)
121 @sacrifice = "gps500+e293220e3f8a3e59f79f6b0efffaa931"
126 players.size % 2 == 1 &&
127 players.find{|a| a.id == @sacrifice}
128 log_message("Floodgate: first, exclude %s" % [@sacrifice])
129 players.delete_if{|a| a.id == @sacrifice}
131 @pairing.match(players)
134 # Delegate to @pairing
135 def method_missing(message, *arg)
136 @pairing.send(message, *arg)
138 end # class ExcludeSacrifice