OSDN Git Service

Enhanced syntax of Floodgate time configuration file. Now it supports "set sacrifice...
authorDaigo Moriwaki <daigo@debian.org>
Sat, 7 Dec 2013 15:52:46 +0000 (00:52 +0900)
committerDaigo Moriwaki <daigo@debian.org>
Sat, 7 Dec 2013 15:52:46 +0000 (00:52 +0900)
It sets a sacrificed player for a specific Floodgate game.
ex. set sacrifice gps500+e293220e3f8a3e59f79f6b0efffaa931

changelog
shogi-server
shogi_server/league/floodgate.rb
shogi_server/pairing.rb
test/TC_floodgate_next_time_generator.rb

index 109f434..c253722 100644 (file)
--- 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 <player_id>"; it sets a
+           sacrificed player for a specific Floodgate game.
+           ex. set sacrifice gps500+e293220e3f8a3e59f79f6b0efffaa931
 
 2013-12-05  Daigo Moriwaki <daigo at debian dot org>
 
index c20dba8..33a2d70 100755 (executable)
@@ -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
 
index a93d30d..5d6ccaa 100644 (file)
@@ -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)}
index 6d62891..4c2583b 100644 (file)
@@ -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)
index c91cdfe..297d63b 100644 (file)
@@ -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