## $Id$
## Copyright (C) 2004 NABEYA Kenichi (aka nanami@2ch)
-## Copyright (C) 2007-2008 Daigo Moriwaki (daigo at debian dot org)
+## Copyright (C) 2007-2012 Daigo Moriwaki (daigo at debian dot org)
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
#
class MonitorObserver
def update(game_result)
- game_result.game.each_monitor do |monitor|
- monitor.write_safe("##[MONITOR][%s] %s\n" % [game_result.game.game_id, game_result.result_type])
+ game_result.game.each_monitor do |monitor_handler|
+ monitor_handler.write_safe(game_result.game.game_id, game_result.result_type)
end
end
end
-# Base class for a game result
+# LoggingObserver appends a result of each game to a log file, which will
+# be used to calculate rating scores of players.
+#
+class LoggingObserver
+ def initialize
+ @logfile = File.join($league.dir, "00LIST")
+ end
+
+ def update(game_result)
+ end_time_str = game_result.end_time.strftime("%Y/%m/%d %H:%M:%S")
+ black = game_result.black
+ white = game_result.white
+ black_name = black.rated? ? black.player_id : black.name
+ white_name = white.rated? ? white.player_id : white.name
+ msg = [end_time_str,
+ game_result.log_summary_type,
+ game_result.black_result,
+ black_name,
+ white_name,
+ game_result.white_result,
+ game_result.game.logfile]
+ begin
+ # Note that this is proccessed in the gian lock.
+ File.open(@logfile, "a") do |f|
+ f << msg.join("\t") << "\n"
+ end
+ rescue => e
+ # ignore
+ $stderr.puts "Failed to write to the game result file: #{@logfile}" if $DEBUG
+ end
+ end
+end
+
+# Base abstract class for a game result.
+# Imediate subclasses are GameResultWin and GameResultDraw.
#
class GameResult
include Observable
attr_reader :white
# Command to send monitors such as '%TORYO' etc...
attr_reader :result_type
+ # Result types to write the main log file such as 'toryo' etc...
+ attr_reader :log_summary_type
+ # Time when the game ends
+ attr_reader :end_time
def initialize(game, p1, p2)
@game = game
player.status = "connected"
end
@result_type = ""
-
+ @end_time = Time.now
regist_observers
end
def regist_observers
add_observer MonitorObserver.new
+ add_observer LoggingObserver.new
if League::Floodgate.game_name?(@game.game_name) &&
- @game.sente.player_id &&
- @game.gote.player_id &&
- $options["floodgate-history"]
- add_observer League::Floodgate::History.factory
+ @game.sente.player_id && @game.gote.player_id
+ path = League::Floodgate.history_file_path(@game.game_name)
+ history = League::Floodgate::History.factory(path)
+ add_observer history if history
end
-
end
def process
log(@game.board.to_s.gsub(/^/, "\'").chomp)
end
+ def black_result
+ return "Implemet me!"
+ end
+
+ def white_result
+ return "Implemet me!"
+ end
+
+ def log_summary
+ log_board
+ log("'summary:%s:%s %s:%s %s" % [@log_summary_type,
+ @black.name, black_result,
+ @white.name, white_result])
+ end
end
class GameResultWin < GameResult
@loser.last_game_win = false
end
- def log_summary(type)
- log_board
-
- black_result = white_result = ""
- if @black == @winner
- black_result = "win"
- white_result = "lose"
- else
- black_result = "lose"
- white_result = "win"
- end
- log("'summary:%s:%s %s:%s %s" % [type,
- @black.name, black_result,
- @white.name, white_result])
+ def black_result
+ return @black == @winner ? "win" : "lose"
+ end
+ def white_result
+ return @black == @winner ? "lose" : "win"
end
end
class GameResultAbnormalWin < GameResultWin
+ def initialize(game, winner, loser)
+ super
+ @log_summary_type = "abnormal"
+ @result_type = "%TORYO"
+ end
+
def process
@winner.write_safe("%TORYO\n#RESIGN\n#WIN\n")
@loser.write_safe( "%TORYO\n#RESIGN\n#LOSE\n")
- log("%TORYO")
- log_summary("abnormal")
- @result_type = "%TORYO"
+ log(@result_type)
+ log_summary
notify
end
end
class GameResultTimeoutWin < GameResultWin
+ def initialize(game, winner, loser)
+ super
+ @log_summary_type = "time up"
+ @result_type = "#TIME_UP"
+ end
+
def process
@winner.write_safe("#TIME_UP\n#WIN\n")
@loser.write_safe( "#TIME_UP\n#LOSE\n")
- log_summary("time up")
- @result_type = "#TIME_UP"
+ # no log
+ log_summary
notify
end
end
# A player declares (successful) Kachi
class GameResultKachiWin < GameResultWin
+ def initialize(game, winner, loser)
+ super
+ @log_summary_type = "kachi"
+ @result_type = "%KACHI"
+ end
+
def process
@winner.write_safe("%KACHI\n#JISHOGI\n#WIN\n")
@loser.write_safe( "%KACHI\n#JISHOGI\n#LOSE\n")
- log("%KACHI")
- log_summary("kachi")
- @result_type = "%KACHI"
+ log(@result_type)
+ log_summary
notify
end
end
# A player declares wrong Kachi
class GameResultIllegalKachiWin < GameResultWin
+ def initialize(game, winner, loser)
+ super
+ @log_summary_type = "illegal kachi"
+ @result_type = "%KACHI"
+ end
+
def process
@winner.write_safe("%KACHI\n#ILLEGAL_MOVE\n#WIN\n")
@loser.write_safe( "%KACHI\n#ILLEGAL_MOVE\n#LOSE\n")
- log("%KACHI")
- log_summary("illegal kachi")
- @result_type = "%KACHI"
+ log(@result_type)
+ log_summary
notify
end
end
class GameResultIllegalWin < GameResultWin
def initialize(game, winner, loser, cause)
super(game, winner, loser)
- @cause = cause
+ @log_summary_type = cause
+ @result_type = "#ILLEGAL_MOVE"
end
def process
@winner.write_safe("#ILLEGAL_MOVE\n#WIN\n")
@loser.write_safe( "#ILLEGAL_MOVE\n#LOSE\n")
- log_summary(@cause)
- @result_type = "#ILLEGAL_MOVE"
+ # no log
+ log_summary
notify
end
end
end
end
-class GameResultOutoriWin < GameResultWin
+# This won't happen, though.
+#
+class GameResultOutoriWin < GameResultIllegalWin
def initialize(game, winner, loser)
- super(game, winner, loser)
+ super(game, winner, loser, "outori")
end
end
class GameResultToryoWin < GameResultWin
+ def initialize(game, winner, loser)
+ super
+ @log_summary_type = "toryo"
+ @result_type = "%TORYO"
+ end
+
def process
@winner.write_safe("%TORYO\n#RESIGN\n#WIN\n")
@loser.write_safe( "%TORYO\n#RESIGN\n#LOSE\n")
- log("%TORYO")
- log_summary("toryo")
- @result_type = "%TORYO"
+ log(@result_type)
+ log_summary
notify
end
end
class GameResultOuteSennichiteWin < GameResultWin
+ def initialize(game, winner, loser)
+ super
+ @log_summary_type = "oute_sennichite"
+ @result_type = "#OUTE_SENNICHITE"
+ end
+
def process
@winner.write_safe("#OUTE_SENNICHITE\n#WIN\n")
@loser.write_safe( "#OUTE_SENNICHITE\n#LOSE\n")
- log_summary("oute_sennichite")
- @result_type = "#OUTE_SENNICHITE"
+ # no log
+ log_summary
notify
end
end
+# Draw
+#
class GameResultDraw < GameResult
def initialize(game, p1, p2)
super
p2.last_game_win = false
end
- def log_summary(type)
- log_board
- log("'summary:%s:%s draw:%s draw" % [type, @black.name, @white.name])
+ def black_result
+ return "draw"
+ end
+
+ def white_result
+ return "draw"
end
end
class GameResultSennichiteDraw < GameResultDraw
+ def initialize(game, winner, loser)
+ super
+ @log_summary_type = "sennichite"
+ @result_type = "#SENNICHITE"
+ end
+
def process
@players.each do |player|
player.write_safe("#SENNICHITE\n#DRAW\n")
end
- log_summary("sennichite")
- @result_type = "#SENNICHITE"
+ # no log
+ log_summary
notify
end
end
end # ShogiServer
-