ExcludeSacrificeGps500.new,
MakeEven.new,
SortByRateWithRandomness.new(1200, 2400),
- StartGame.new]
+ StartGameWithoutHumans.new]
end
def random_pairing
ExcludeSacrificeGps500.new,
MakeEven.new,
Randomize.new,
- StartGame.new]
+ StartGameWithoutHumans.new]
end
def swiss_pairing
ExcludeSacrificeGps500.new,
MakeEven.new,
Swiss.new(history),
- StartGame.new]
+ StartGameWithoutHumans.new]
end
def match(players)
end
end
- class StartGame < Pairing
+ class AbstractStartGame < Pairing
+ def start_game(p1, p2)
+ log_message("Floodgate: Starting a game: BLACK %s vs WHITE %s" % [p1.name, p2.name])
+ p1.sente = true
+ p2.sente = false
+ board = Board.new
+ board.initial
+ Game.new(p1.game_name, p1, p2, board)
+ end
+
+ def start_game_shuffle(pair)
+ pair.shuffle!
+ start_game(pair.first, pair.last)
+ end
+ end
+
+ class StartGame < AbstractStartGame
def match(players)
super
if players.size < 2
log_players(players)
while (players.size >= 2) do
pair = players.shift(2)
- pair.shuffle!
- start_game(pair.first, pair.last)
+ start_game_shuffle(pair)
end
end
+ end
- def start_game(p1, p2)
- log_message("Floodgate: Starting a game: BLACK %s vs WHITE %s" % [p1.name, p2.name])
- p1.sente = true
- p2.sente = false
- board = Board.new
- board.initial
- Game.new(p1.game_name, p1, p2, board)
+ # This tries to avoid a human-human match
+ #
+ class StartGameWithoutHumans < AbstractStartGame
+ def match(players)
+ super
+ log_players(players)
+ if players.size < 2
+ log_warning("Floodgate: There should be more than one player (%d)." % [players.size])
+ return
+ elsif players.size == 2
+ start_game_shuffle(players)
+ return
+ end
+
+ loop do
+ humans = get_human_indexes(players)
+ log_message("Floodgate: There are (still) %d humans." % [humans.size])
+ break if humans.size < 2
+
+ pairing_possible = false
+ for i in 0..(humans.size-2) # -2
+ next if humans[i].odd?
+ if humans[i]+1 == humans[i+1]
+ pairing_possible = i
+ break
+ end
+ end
+ unless pairing_possible
+ log_message("Floodgate: No possible human-human match found")
+ break
+ end
+
+ current_index = pairing_possible
+ j = (current_index == 0 ? current_index : current_index-1)
+ while j < players.size
+ break if players[j].is_computer?
+ j += 1
+ end
+
+ pairing_indexes = []
+ if j == players.size
+ # no computer player found
+ pairing_indexes << current_index << current_index+1
+ else
+ # a comupter player found
+ pairing_indexes << current_index << j
+ end
+
+ pair = []
+ pair << players.delete_at(pairing_indexes.max)
+ pair << players.delete_at(pairing_indexes.min)
+ start_game_shuffle(pair)
+ end # loop
+
+ while (players.size >= 2) do
+ pair = players.shift(2)
+ start_game_shuffle(pair)
+ end
+ end
+
+ private
+
+ def get_human_indexes(players)
+ ret = []
+ for i in 0..(players.size-1)
+ ret << i if players[i].is_human?
+ end
+ return ret
end
end
end
end
-class TestStartGame < Test::Unit::TestCase
- def setup
- @pairing= ShogiServer::StartGame.new
- $called = 0
- def @pairing.start_game(p1,p2)
- $called += 1
- end
- @a = ShogiServer::BasicPlayer.new
- @a.name = "a"
- @a.win = 1
- @a.loss = 2
- @a.rate = 0
- @b = ShogiServer::BasicPlayer.new
- @b.name = "b"
- @b.win = 10
- @b.loss = 20
- @b.rate = 1500
- @c = ShogiServer::BasicPlayer.new
- @c.name = "c"
- @c.win = 100
- @c.loss = 200
- @c.rate = 1000
- @d = ShogiServer::BasicPlayer.new
- @d.name = "d"
- @d.win = 1000
- @d.loss = 2000
- @d.rate = 2000
- end
-
- def test_match_two_players
- players = [@a,@b]
- @pairing.match(players)
- assert_equal(1, $called)
- end
-
- def test_match_one_player
- players = [@a]
- @pairing.match(players)
- assert_equal(0, $called)
- end
-
- def test_match_zero_player
- players = []
- @pairing.match(players)
- assert_equal(0, $called)
- end
-
- def test_match_three_players
- players = [@a,@b,@c]
- @pairing.match(players)
- assert_equal(1, $called)
- end
-
- def test_match_four_players
- players = [@a,@b,@c,@d]
- @pairing.match(players)
- assert_equal(2, $called)
- end
-end
-
class TestDeleteMostPlayingPlayer < Test::Unit::TestCase
def setup
@pairing= ShogiServer::DeleteMostPlayingPlayer.new
--- /dev/null
+$:.unshift File.join(File.dirname(__FILE__), "..")
+require 'test/unit'
+require 'shogi_server'
+require 'shogi_server/player'
+require 'shogi_server/pairing'
+
+class MockLogger
+ def debug(str)
+ end
+ def info(str)
+ #puts str
+ end
+ def warn(str)
+ end
+ def error(str)
+ end
+end
+
+$logger = MockLogger.new
+def log_message(msg)
+ $logger.info(msg)
+end
+
+def log_warning(msg)
+ $logger.warn(msg)
+end
+
+def same_pair?(a, b)
+ unless a.size == 2 && b.size == 2
+ return false
+ end
+
+ return true if [a.first, a.last] == b || [a.last, a.first] == b
+end
+
+class TestStartGame < Test::Unit::TestCase
+ def setup
+ @pairing= ShogiServer::StartGame.new
+ $called = 0
+ def @pairing.start_game(p1,p2)
+ $called += 1
+ end
+ @a = ShogiServer::BasicPlayer.new
+ @a.name = "a"
+ @a.win = 1
+ @a.loss = 2
+ @a.rate = 0
+ @b = ShogiServer::BasicPlayer.new
+ @b.name = "b"
+ @b.win = 10
+ @b.loss = 20
+ @b.rate = 1500
+ @c = ShogiServer::BasicPlayer.new
+ @c.name = "c"
+ @c.win = 100
+ @c.loss = 200
+ @c.rate = 1000
+ @d = ShogiServer::BasicPlayer.new
+ @d.name = "d"
+ @d.win = 1000
+ @d.loss = 2000
+ @d.rate = 2000
+ end
+
+ def test_match_two_players
+ players = [@a,@b]
+ @pairing.match(players)
+ assert_equal(1, $called)
+ end
+
+ def test_match_one_player
+ players = [@a]
+ @pairing.match(players)
+ assert_equal(0, $called)
+ end
+
+ def test_match_zero_player
+ players = []
+ @pairing.match(players)
+ assert_equal(0, $called)
+ end
+
+ def test_match_three_players
+ players = [@a,@b,@c]
+ @pairing.match(players)
+ assert_equal(1, $called)
+ end
+
+ def test_match_four_players
+ players = [@a,@b,@c,@d]
+ @pairing.match(players)
+ assert_equal(2, $called)
+ end
+end
+
+class TestStartGameWithoutHumans < Test::Unit::TestCase
+ def setup
+ @pairing= ShogiServer::StartGameWithoutHumans.new
+ $paired = []
+ $called = 0
+ def @pairing.start_game(p1,p2)
+ $called += 1
+ $paired << [p1,p2]
+ end
+ @a = ShogiServer::BasicPlayer.new
+ @a.name = "a"
+ @a.win = 1
+ @a.loss = 2
+ @a.rate = 0
+ @b = ShogiServer::BasicPlayer.new
+ @b.name = "b"
+ @b.win = 10
+ @b.loss = 20
+ @b.rate = 1500
+ @c = ShogiServer::BasicPlayer.new
+ @c.name = "c"
+ @c.win = 100
+ @c.loss = 200
+ @c.rate = 1000
+ @d = ShogiServer::BasicPlayer.new
+ @d.name = "d"
+ @d.win = 1000
+ @d.loss = 2000
+ @d.rate = 2000
+ end
+
+ def test_match_one_player
+ players = [@a]
+ @pairing.match(players)
+ assert_equal(0, $called)
+ end
+
+ def test_match_one_player_human
+ @a.name += "_human"
+ players = [@a]
+ @pairing.match(players)
+ assert_equal(0, $called)
+ end
+
+ def test_match_two_players
+ players = [@a,@b]
+ @pairing.match(players)
+ assert_equal(1, $called)
+ end
+
+ def test_match_two_players_humans
+ @a.name += "_human"
+ @b.name += "_human"
+ players = [@a,@b]
+ @pairing.match(players)
+ assert_equal(1, $called)
+ end
+
+ def test_match_zero_player
+ players = []
+ @pairing.match(players)
+ assert_equal(0, $called)
+ end
+
+ def test_match_three_players
+ players = [@a,@b,@c]
+ @pairing.match(players)
+ assert_equal(1, $called)
+ end
+
+ def test_match_three_players_a_human
+ @a.name += "_human"
+ players = [@a,@b,@c]
+ @pairing.match(players)
+ assert_equal(1, $called)
+ assert_equal(1, players.size)
+ assert_equal(@c, players[0])
+ end
+
+ def test_match_three_players_b_human
+ @b.name += "_human"
+ players = [@a,@b,@c]
+ @pairing.match(players)
+ assert_equal(1, $called)
+ assert_equal(1, players.size)
+ assert_equal(@c, players[0])
+ end
+
+ def test_match_three_players_c_human
+ @c.name += "_human"
+ players = [@a,@b,@c]
+ @pairing.match(players)
+ assert_equal(1, $called)
+ assert_equal(1, players.size)
+ assert_equal(@c, players[0])
+ end
+
+ def test_match_three_players_ab_human
+ @a.name += "_human"
+ @b.name += "_human"
+ players = [@a,@b,@c]
+ @pairing.match(players)
+ assert_equal(1, $called)
+ assert_equal(1, players.size)
+ assert_equal(@b, players[0])
+ end
+
+ def test_match_three_players_bc_human
+ @b.name += "_human"
+ @c.name += "_human"
+ players = [@a,@b,@c]
+ @pairing.match(players)
+ assert_equal(1, $called)
+ assert_equal(1, players.size)
+ assert_equal(@c, players[0])
+ end
+
+ def test_match_four_players
+ players = [@a,@b,@c,@d]
+ @pairing.match(players)
+ assert_equal(2, $called)
+ end
+
+ def test_match_four_players_ab_human
+ @a.name += "_human"
+ @b.name += "_human"
+ players = [@a,@b,@c,@d]
+ @pairing.match(players)
+ assert_equal(2, $paired.size)
+ assert(same_pair?([@a,@c], $paired[0]))
+ assert(same_pair?([@b,@d], $paired[1]))
+ end
+
+ def test_match_four_players_bc_human
+ @b.name += "_human"
+ @c.name += "_human"
+ players = [@a,@b,@c,@d]
+ @pairing.match(players)
+ assert_equal(2, $paired.size)
+ assert(same_pair?([@a,@b], $paired[0]))
+ assert(same_pair?([@c,@d], $paired[1]))
+ end
+
+ def test_match_four_players_abc_human
+ @a.name += "_human"
+ @b.name += "_human"
+ @c.name += "_human"
+ players = [@a,@b,@c,@d]
+ @pairing.match(players)
+ assert_equal(2, $paired.size)
+ assert(same_pair?([@a,@d], $paired[0]))
+ assert(same_pair?([@b,@c], $paired[1]))
+ end
+
+ def test_match_four_players_bcd_human
+ @b.name += "_human"
+ @c.name += "_human"
+ @d.name += "_human"
+ players = [@a,@b,@c,@d]
+ @pairing.match(players)
+ assert_equal(2, $paired.size)
+ assert(same_pair?([@a,@b], $paired[0]))
+ assert(same_pair?([@c,@d], $paired[1]))
+ end
+
+ def test_match_four_players_abcd_human
+ @a.name += "_human"
+ @b.name += "_human"
+ @c.name += "_human"
+ @d.name += "_human"
+ players = [@a,@b,@c,@d]
+ @pairing.match(players)
+ assert_equal(2, $paired.size)
+ assert(same_pair?([@a,@b], $paired[0]))
+ assert(same_pair?([@c,@d], $paired[1]))
+ end
+end
+
+