#
attr_reader :next_time
attr_reader :league, :game_name
+ attr_reader :options
def initialize(league, hash={})
@league = league
- @next_time = hash[:next_time] || nil
- @game_name = hash[:game_name] || "floodgate-900-0"
+ @next_time = hash[:next_time] || nil
+ @game_name = hash[:game_name] || "floodgate-900-0"
+ # Options will be updated by NextTimeGenerator and then passed to a
+ # pairing factory.
+ @options = {}
+ @options[:pairing_factory] = hash[:pairing_factory] || "default_factory"
+ @options[:sacrifice] = hash[:sacrifice] || "gps500+e293220e3f8a3e59f79f6b0efffaa931"
charge if @next_time.nil?
end
return Regexp.new(@game_name).match(str) ? true : false
end
+ def pairing_factory
+ return @options[:pairing_factory]
+ end
+
+ def sacrifice
+ return @options[:sacrifice]
+ end
+
def charge
ntg = NextTimeGenerator.factory(@game_name)
if ntg
@next_time = ntg.call(Time.now)
+ @options[:pairing_factory] = ntg.pairing_factory
+ @options[:sacrifice] = ntg.sacrifice
else
@next_time = nil
end
end
def match_game
+ log_message("Starting Floodgate games...: %s, %s" % [@game_name, @options])
players = @league.find_all_players do |pl|
pl.status == "game_waiting" &&
game_name?(pl.game_name) &&
pl.sente == nil
end
- Pairing.match(players)
+ logics = Pairing.send(@options[:pairing_factory], @options)
+ Pairing.match(players, logics)
end
#
end
end
+ class AbstructNextTimeGenerator
+
+ attr_reader :pairing_factory
+ attr_reader :sacrifice
+
+ # Constructor.
+ #
+ def initialize
+ @pairing_factory = "default_factory"
+ @sacrifice = "gps500+e293220e3f8a3e59f79f6b0efffaa931"
+ end
+ end
+
# Schedule the next time from configuration files.
#
# Line format:
# # This is a comment line
+ # set <parameter_name> <value>
# DoW Time
# ...
# where
# Sat 22:00
# Sun 13:00
#
- class NextTimeGeneratorConfig
+ # Set parameters:
+ #
+ # * 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
+ #
+ class NextTimeGeneratorConfig < AbstructNextTimeGenerator
# Constructor.
# Read configuration contents.
#
def initialize(lines)
+ super()
@lines = lines
end
# now.cweek 1-53
# now.cwday 1(Monday)-7
@lines.each do |line|
- if %r!^\s*(\w+)\s+(\d{1,2}):(\d{1,2})! =~ line
+ case line
+ when %r!^\s*set\s+pairing_factory\s+(\w+)!
+ @pairing_factory = $1.chomp
+ when %r!^\s*set\s+sacrifice\s+(.*)!
+ @sacrifice = $1.chomp
+ 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)
next if dow_index.nil?
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)}
# Schedule the next time for floodgate-900-0: each 30 minutes
#
- class NextTimeGenerator_Floodgate_900_0
+ class NextTimeGenerator_Floodgate_900_0 < AbstructNextTimeGenerator
+
+ # Constructor.
+ #
+ def initialize
+ super
+ end
+
def call(now)
if now.min < 30
return Time.mktime(now.year, now.month, now.day, now.hour, 30)
# Schedule the next time for floodgate-3600-0: each 2 hours (odd hour)
#
- class NextTimeGenerator_Floodgate_3600_0
+ class NextTimeGenerator_Floodgate_3600_0 < AbstructNextTimeGenerator
+
+ # Constructor.
+ #
+ def initialize
+ super
+ end
+
def call(now)
return Time.mktime(now.year, now.month, now.day, now.hour) + ((now.hour%2)+1)*3600
end
# Schedule the next time for debug: each 30 seconds.
#
- class NextTimeGenerator_Debug
+ class NextTimeGenerator_Debug < AbstructNextTimeGenerator
+
+ # Constructor.
+ #
+ def initialize
+ super
+ end
+
def call(now)
if now.sec < 30
return Time.mktime(now.year, now.month, now.day, now.hour, now.min, 30)