class << self
def default_factory
- return sort_by_rate_with_randomness
+ return swiss_pairing
end
def sort_by_rate_with_randomness
StartGame.new]
end
+ def swiss_pairing
+ history = ShogiServer::League::Floodgate::History.factory
+ return [LogPlayers.new,
+ ExcludeSacrificeGps500.new,
+ MakeEven.new,
+ Swiss.new(history),
+ StartGame.new]
+ end
+
def match(players)
logics = default_factory
logics.inject(players) do |result, item|
@rand1, @rand2 = rand1, rand2
end
- def match(players)
- super
+ def match(players, desc=false)
+ super(players)
cur_rate = Hash.new
players.each{|a| cur_rate[a] = a.rate ? a.rate + rand(@rand1) : rand(@rand2)}
players.sort!{|a,b| cur_rate[a] <=> cur_rate[b]}
+ players.reverse! if desc
log_players(players) do |one|
- "%s %d (randomness %d)" % [one.name, one.rate, cur_rate[one] - one.rate]
+ "%s %d (+ randomness %d)" % [one.name, one.rate, cur_rate[one] - one.rate]
+ end
+ end
+ end
+
+ class Swiss < Pairing
+ def initialize(history)
+ super()
+ @history = history
+ end
+
+ def match(players)
+ super
+ winners = players.find_all {|pl| @history.last_win?(pl.player_id)}
+ rest = players - winners
+
+ log_message("Floodgate: %d winners" % [winners.size])
+ sbrwr_winners = SortByRateWithRandomness.new(800, 2500)
+ sbrwr_winners.match(winners, true)
+ log_players(winners)
+
+ log_message("Floodgate: and the rest: %d" % [rest.size])
+ sbrwr_losers = SortByRateWithRandomness.new(200, 400)
+ sbrwr_losers.match(rest, true)
+ log_players(rest)
+
+ players.clear
+ [winners, rest].each do |group|
+ group.each {|pl| players << pl}
end
end
end
end
end
+class TestSwissPairing < Test::Unit::TestCase
+ def setup
+ srand(10)
+ @a = ShogiServer::BasicPlayer.new
+ @a.player_id = "a"
+ @a.rate = 0
+ @b = ShogiServer::BasicPlayer.new
+ @b.player_id = "b"
+ @b.rate = 1000
+ @c = ShogiServer::BasicPlayer.new
+ @c.player_id = "c"
+ @c.rate = 1500
+ @d = ShogiServer::BasicPlayer.new
+ @d.player_id = "d"
+ @d.rate = 2000
+
+ @players = [@a, @b, @c, @d]
+
+ @file = Pathname.new(File.join(File.dirname(__FILE__), "floodgate_history.yaml"))
+ @history = ShogiServer::League::Floodgate::History.new @file
+
+ @swiss = ShogiServer::Swiss.new @history
+ end
+
+ def teardown
+ @file.delete if @file.exist?
+ end
+
+ def test_all_win
+ def @history.last_win?(player_id)
+ true
+ end
+ @swiss.match @players
+ assert_equal([@d, @c, @b, @a], @players)
+ end
+
+ def test_all_lose
+ def @history.last_win?(player_id)
+ false
+ end
+ @swiss.match @players
+ assert_equal([@d, @c, @b, @a], @players)
+ end
+
+ def test_one_win
+ def @history.last_win?(player_id)
+ if player_id == "a"
+ true
+ else
+ false
+ end
+ end
+ @swiss.match @players
+ assert_equal([@a, @d, @c, @b], @players)
+ end
+
+ def test_two_win
+ def @history.last_win?(player_id)
+ if player_id == "a" || player_id == "d"
+ true
+ else
+ false
+ end
+ end
+ @swiss.match @players
+ assert_equal([@d, @a, @c, @b], @players)
+ end
+end
class TestFloodgateHistory < Test::Unit::TestCase
def setup