X-Git-Url: http://git.sourceforge.jp/view?p=shogi-server%2Fshogi-server.git;a=blobdiff_plain;f=shogi_server%2Fpairing.rb;h=cc2ea62ef4f14800ec9f4f2516f2126b20e140ff;hp=6d62891dc773ecba7a393d48b44ead7569a59153;hb=3b47d9406bdf976c82fe426581327d765111ed50;hpb=f8dc7d8ab76bf939f4dee30b401cbb2ec1f19ff9 diff --git a/shogi_server/pairing.rb b/shogi_server/pairing.rb index 6d62891..cc2ea62 100644 --- a/shogi_server/pairing.rb +++ b/shogi_server/pairing.rb @@ -24,59 +24,67 @@ module ShogiServer class Pairing class << self - def default_factory - return least_diff_pairing + def default_factory(options) + return least_diff_pairing(options) end - def sort_by_rate_with_randomness + def sort_by_rate_with_randomness(options) return [LogPlayers.new, - ExcludeSacrificeGps500.new, + ExcludeSacrifice.new(options[:sacrifice]), MakeEven.new, SortByRateWithRandomness.new(1200, 2400), StartGameWithoutHumans.new] end - def random_pairing + def random_pairing(options) return [LogPlayers.new, - ExcludeSacrificeGps500.new, + ExcludeSacrifice.new(options[:sacrifice]), MakeEven.new, Randomize.new, StartGameWithoutHumans.new] end - def swiss_pairing + def swiss_pairing(options) return [LogPlayers.new, - ExcludeSacrificeGps500.new, + ExcludeSacrifice.new(options[:sacrifice]), MakeEven.new, Swiss.new, StartGameWithoutHumans.new] end - def least_diff_pairing + def least_diff_pairing(options) return [LogPlayers.new, - ExcludeSacrificeGps500.new, + ExcludeSacrifice.new(options[:sacrifice]), MakeEven.new, LeastDiff.new, StartGameWithoutHumans.new] end - def floodgate_zyunisen + def floodgate_zyunisen(options) return [LogPlayers.new, ExcludeUnratedPlayers.new, - ExcludeSacrificeGps500.new, + ExcludeSacrifice.new(options[:sacrifice]), MakeEven.new, LeastDiff.new, StartGameWithoutHumans.new] end - def match(players, logics) + def match(players, logics, options) logics.inject(players) do |result, item| + item.set_options(options) item.match(result) result end end end # class << self + def initialize + @options = {} + end + + def set_options(options) + @options.merge!(options) + end # Make matches among players. # @param players an array of players, which should be updated destructively @@ -129,7 +137,7 @@ module ShogiServer 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 = Board.new(@options) board.initial Game.new(p1.game_name, p1, p2, board) end @@ -144,7 +152,7 @@ module ShogiServer def match(players) super if players.size < 2 - log_warning("Floodgate: There should be more than one player (%d)." % [players.size]) + log_message("Floodgate: There are less than two players: %d" % [players.size]) return end if players.size.odd? @@ -167,7 +175,7 @@ module ShogiServer super log_players(players) if players.size < 2 - log_warning("Floodgate: There should be more than one player (%d)." % [players.size]) + log_message("Floodgate: There are less than two players: %d" % [players.size]) return elsif players.size == 2 start_game_shuffle(players) @@ -354,7 +362,7 @@ module ShogiServer # @sacrifice a player id to be eliminated def initialize(sacrifice) super() - @sacrifice = sacrifice + @sacrifice = sacrifice || "gps500+e293220e3f8a3e59f79f6b0efffaa931" end def match(players) @@ -494,11 +502,34 @@ module ShogiServer if p1.is_human? && p2.is_human? ret += 800 end + + # 2.3 a match with likely kin players + if (p1.player_id[0..6] == p2.player_id[0..6]) + ret += 800 + elsif (p1.player_id[0..3] == p2.player_id[0..3]) + ret += 400 + end end ret end + # Total combinations of possible games among n players + # nC2 * (n-2)C2 * ... * 2C2 / (n/2)! + def total_posibilities(n) + n -= 1 if n.odd? + return 1 if n <= 2 + + ret = 1 + i = n + while i >= 2 do + ret *= ::ShogiServer::nCk(i,2) + i -= 2 + end + ret /= ::ShogiServer::factorial(n/2) + return ret + end + def match(players) super if players.size < 3 @@ -509,12 +540,16 @@ module ShogiServer # Reset estimated rate players.each {|p| p.estimated_rate = 0} - # 10 trials matches = [] scores = [] path = ShogiServer::League::Floodgate.history_file_path(players.first.game_name) history = ShogiServer::League::Floodgate::History.factory(path) - 10.times do + + # Increase trials, depending on a number of players + trials = [300, total_posibilities(players.size)/3].min + trials = [10, trials].max + log_message("Floodgate: %d trials" % [trials]) + trials.times do m = random_match(players) matches << m scores << calculate_diff_with_penalty(m, history) @@ -535,7 +570,7 @@ module ShogiServer min_score = s end end - log_message("Floodgate: the least score %d (%d per player) [%s]" % [min_score, min_score/players.size, scores.join(" ")]) + log_message("Floodgate: the least score %d (%d per game) [%s]" % [min_score, min_score/players.size*2, scores.join(" ")]) players.replace(matches[min_index]) end