From f35a166044ad84d7f53aed7aa5675312ce38862a Mon Sep 17 00:00:00 2001 From: Daigo Moriwaki Date: Sun, 8 Dec 2013 00:52:46 +0900 Subject: [PATCH] Enhanced syntax of Floodgate time configuration file. Now it supports "set sacrifice " It sets a sacrificed player for a specific Floodgate game. ex. set sacrifice gps500+e293220e3f8a3e59f79f6b0efffaa931 --- changelog | 4 ++++ shogi-server | 14 ++++++++++++++ shogi_server/league/floodgate.rb | 21 +++++++++++++++++++-- shogi_server/pairing.rb | 26 +++++++++++++------------- test/TC_floodgate_next_time_generator.rb | 31 +++++++++++++++++++++++++++++++ 5 files changed, 81 insertions(+), 15 deletions(-) diff --git a/changelog b/changelog index 109f434..c253722 100644 --- a/changelog +++ b/changelog @@ -3,6 +3,10 @@ * [shogi-server] - shogi_server/pairing.rb, player.rb: Simplify estimated rate of unrated players (less memory). + - Enhanced syntax of Floodgate time configuration file. + Now it supports "set sacrifice "; it sets a + sacrificed player for a specific Floodgate game. + ex. set sacrifice gps500+e293220e3f8a3e59f79f6b0efffaa931 2013-12-05 Daigo Moriwaki diff --git a/shogi-server b/shogi-server index c20dba8..33a2d70 100755 --- a/shogi-server +++ b/shogi-server @@ -138,6 +138,20 @@ FLOODGATE SCHEDULE CONFIGURATIONS Sat 22:00 Sun 13:00 + PAREMETER SETTING + + In addition, this configuration file allows to set parameters + for the specific Floodaget group. A list of parameters is the + following: + + * pairing_factory: + Specifies a factory function name generating a pairing + method which will be used in a specific Floodgate game. + ex. set pairing_factory floodgate_zyunisen + * sacrifice: + Specifies a sacrificed player. + ex. set sacrifice gps500+e293220e3f8a3e59f79f6b0efffaa931 + LICENSE GPL versoin 2 or later diff --git a/shogi_server/league/floodgate.rb b/shogi_server/league/floodgate.rb index a93d30d..5d6ccaa 100644 --- a/shogi_server/league/floodgate.rb +++ b/shogi_server/league/floodgate.rb @@ -28,12 +28,15 @@ class League attr_reader :next_time attr_reader :league, :game_name attr_reader :pairing_factory + attr_reader :options def initialize(league, hash={}) @league = league @next_time = hash[:next_time] || nil @game_name = hash[:game_name] || "floodgate-900-0" @pairing_factory = "default_factory" # will be updated by NextTimeGenerator + # Options will be updated by NextTimeGenerator + @options = {:sacrifice => "gps500+e293220e3f8a3e59f79f6b0efffaa931"} charge if @next_time.nil? end @@ -44,6 +47,7 @@ class League def charge ntg = NextTimeGenerator.factory(@game_name) @pairing_factory = ntg.pairing_factory + @options[:sacrifice] = ntg.sacrifice if ntg @next_time = ntg.call(Time.now) else @@ -58,7 +62,7 @@ class League game_name?(pl.game_name) && pl.sente == nil end - logics = Pairing.send(@pairing_factory) + logics = Pairing.send(@pairing_factory, @options) Pairing.match(players, logics) end @@ -88,11 +92,13 @@ class League class AbstructNextTimeGenerator attr_reader :pairing_factory + attr_reader :sacrifice # Constructor. # def initialize @pairing_factory = "default_factory" + @sacrifice = "gps500+e293220e3f8a3e59f79f6b0efffaa931" end end @@ -119,7 +125,10 @@ class League # * pairing_factory: # Specifies a factory function name generating a pairing # method which will be used in a specific Floodgate game. - # ex. floodgate_zyunisen + # ex. set pairing_factory floodgate_zyunisen + # * sacrifice: + # Specifies a sacrificed player. + # ex. set sacrifice gps500+e293220e3f8a3e59f79f6b0efffaa931 # class NextTimeGeneratorConfig < AbstructNextTimeGenerator @@ -142,6 +151,8 @@ class League case line when %r!^\s*set\s+pairing_factory\s+(\w+)! @pairing_factory = $1 + when %r!^\s*set\s+sacrifice\s+(.*)! + @sacrifice = $1 when %r!^\s*(\w+)\s+(\d{1,2}):(\d{1,2})! dow, hour, minute = $1, $2.to_i, $3.to_i dow_index = ::ShogiServer::parse_dow(dow) @@ -151,6 +162,12 @@ class League time = DateTime::commercial(now.cwyear, now.cweek, dow_index, hour, minute) rescue next time += 7 if time <= now candidates << time + when %r!^\s*#! + # Skip comment line + when %r!^\s*$! + # Skip empty line + else + log_warning("Floodgate: Unsupported syntax in a next time generator config file: %s" % [line]) end end candidates.map! {|dt| ::ShogiServer::datetime2time(dt)} diff --git a/shogi_server/pairing.rb b/shogi_server/pairing.rb index 6d62891..4c2583b 100644 --- a/shogi_server/pairing.rb +++ b/shogi_server/pairing.rb @@ -24,46 +24,46 @@ 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] @@ -354,7 +354,7 @@ module ShogiServer # @sacrifice a player id to be eliminated def initialize(sacrifice) super() - @sacrifice = sacrifice + @sacrifice = sacrifice || "gps500+e293220e3f8a3e59f79f6b0efffaa931" end def match(players) diff --git a/test/TC_floodgate_next_time_generator.rb b/test/TC_floodgate_next_time_generator.rb index c91cdfe..297d63b 100644 --- a/test/TC_floodgate_next_time_generator.rb +++ b/test/TC_floodgate_next_time_generator.rb @@ -3,6 +3,7 @@ require 'test/unit' require 'shogi_server' require 'shogi_server/league/floodgate' require 'fileutils' +require 'test/mock_log_message' $topdir = File.expand_path File.dirname(__FILE__) @@ -142,6 +143,20 @@ class TestNextTimeGeneratorConfig < Test::Unit::TestCase def setup end + def test_comment + now = DateTime.new(2010, 6, 10, 21, 59, 59) # Thu + lines = %w(#\ comment1 Thu\ 22:00 #\ comment2) + ntc = ShogiServer::League::Floodgate::NextTimeGeneratorConfig.new lines + assert_equal Time.parse("10-06-2010 22:00"), ntc.call(now) + end + + def test_empty_line + now = DateTime.new(2010, 6, 10, 21, 59, 59) # Thu + lines = %w(\ Thu\ 22:00 \ hoge) + ntc = ShogiServer::League::Floodgate::NextTimeGeneratorConfig.new lines + assert_equal Time.parse("10-06-2010 22:00"), ntc.call(now) + end + def test_read now = DateTime.new(2010, 6, 10, 21, 20, 15) # Thu assert_equal DateTime.parse("10-06-2010 21:20:15"), now @@ -218,4 +233,20 @@ class TestNextTimeGeneratorConfig < Test::Unit::TestCase assert_equal Time.parse("10-06-2010 22:00"), ntc.call(now) assert_equal("least_diff_pairing", ntc.pairing_factory) end + + def test_default_sacrifice + now = DateTime.new(2010, 6, 10, 21, 59, 59) # Thu + lines = %w(Thu\ 22:00) + ntc = ShogiServer::League::Floodgate::NextTimeGeneratorConfig.new lines + assert_equal Time.parse("10-06-2010 22:00"), ntc.call(now) + assert_equal("gps500+e293220e3f8a3e59f79f6b0efffaa931", ntc.sacrifice) + end + + def test_read_sacrifice + now = DateTime.new(2010, 6, 10, 21, 59, 59) # Thu + lines = %w(set\ sacrifice\ yowai_gps+95908f6c18338f5340371f71523fc5e3 Thu\ 22:00) + ntc = ShogiServer::League::Floodgate::NextTimeGeneratorConfig.new lines + assert_equal Time.parse("10-06-2010 22:00"), ntc.call(now) + assert_equal("yowai_gps+95908f6c18338f5340371f71523fc5e3", ntc.sacrifice) + end end -- 2.11.0