3 ## Copyright (C) 2004 NABEYA Kenichi (aka nanami@2ch)
4 ## Copyright (C) 2007-2008 Daigo Moriwaki (daigo at debian dot org)
6 ## This program is free software; you can redistribute it and/or modify
7 ## it under the terms of the GNU General Public License as published by
8 ## the Free Software Foundation; either version 2 of the License, or
9 ## (at your option) any later version.
11 ## This program is distributed in the hope that it will be useful,
12 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ## GNU General Public License for more details.
16 ## You should have received a copy of the GNU General Public License
17 ## along with this program; if not, write to the Free Software
18 ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 require 'shogi_server/util'
28 return sort_by_rate_with_randomness
31 def sort_by_rate_with_randomness
32 return [LogPlayers.new,
33 ExcludeSacrificeGps500.new,
35 SortByRateWithRandomness.new(1200, 2400),
40 return [LogPlayers.new,
41 ExcludeSacrificeGps500.new,
48 logics = default_factory
49 logics.inject(players) do |result, item|
61 def include_newbie?(players)
62 return players.find{|a| a.rate == 0} == nil ? false : true
65 def less_than_one?(players)
67 log_warning("Floodgate: There should be at least one player.")
74 def log_players(players)
75 str_array = players.map do |one|
83 log_message("Floodgate: [Players] None is here.")
85 log_message("Floodgate: [Players] %s." % [str_array.join(", ")])
91 class LogPlayers < Pairing
97 class StartGame < Pairing
101 log_warning("Floodgate: There should be more than one player: %d" % [players.size])
105 log_warning("Floodgate: There are odd players: %d. %s will not be matched." %
106 [players.size, players.last.name])
110 while (players.size >= 2) do
111 pair = players.shift(2)
113 start_game(pair.first, pair.last)
117 def start_game(p1, p2)
118 log_message("Floodgate: BLACK %s; WHITE %s" % [p1.name, p2.name])
121 Game.new(p1.game_name, p1, p2)
125 class Randomize < Pairing
128 log_message("Floodgate: Randomize... before")
131 log_message("Floodgate: Randomized after")
136 class SortByRate < Pairing
139 log_message("Floodgate: Ordered by rate")
140 players.sort! {|a,b| a.rate <=> b.rate} # decendent order
145 class SortByRateWithRandomness < Pairing
146 def initialize(rand1, rand2)
148 @rand1, @rand2 = rand1, rand2
154 players.each{|a| cur_rate[a] = a.rate ? a.rate + rand(@rand1) : rand(@rand2)}
155 players.sort!{|a,b| cur_rate[a] <=> cur_rate[b]}
156 log_players(players) do |one|
157 "%s %d (randomness %d)" % [one.name, one.rate, cur_rate[one] - one.rate]
162 class DeletePlayerAtRandom < Pairing
165 return if less_than_one?(players)
167 log_message("Floodgate: Deleted %s at random" % [one.name])
173 class DeletePlayerAtRandomExcept < Pairing
174 def initialize(except)
181 log_message("Floodgate: Deleting a player at rondom except %s" % [@except.name])
182 players.delete(@except)
183 DeletePlayerAtRandom.new.match(players)
184 players.push(@except)
188 class DeleteMostPlayingPlayer < Pairing
191 one = players.max_by {|a| a.win + a.loss}
192 log_message("Floodgate: Deleted the most playing player: %s (%d)" % [one.name, one.win + one.loss])
198 class DeleteLeastRatePlayer < Pairing
201 one = players.min_by {|a| a.rate}
202 log_message("Floodgate: Deleted the least rate player %s (%d)" % [one.name, one.rate])
208 class ExcludeSacrifice < Pairing
209 attr_reader :sacrifice
211 # @sacrifice a player id to be eliminated
212 def initialize(sacrifice)
214 @sacrifice = sacrifice
221 players.find{|a| a.player_id == @sacrifice}
222 log_message("Floodgate: Deleting the sacrifice %s" % [@sacrifice])
223 players.delete_if{|a| a.player_id == @sacrifice}
227 end # class ExcludeSacrifice
229 class ExcludeSacrificeGps500 < ExcludeSacrifice
231 super("gps500+e293220e3f8a3e59f79f6b0efffaa931")
235 class MakeEven < Pairing
238 return if players.size.even?
239 log_message("Floodgate: there are odd players: %d. Deleting one..." %
241 DeletePlayerAtRandom.new.match(players)