3 ## Copyright (C) 2004 NABEYA Kenichi (aka nanami@2ch)
4 ## Copyright (C) 2007-2008 Daigo Moriwaki (daigo at debian dot org)
6 ## This program is free software; you can redistribute it and/or modify
7 ## it under the terms of the GNU General Public License as published by
8 ## the Free Software Foundation; either version 2 of the License, or
9 ## (at your option) any later version.
11 ## This program is distributed in the hope that it will be useful,
12 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ## GNU General Public License for more details.
16 ## You should have received a copy of the GNU General Public License
17 ## along with this program; if not, write to the Free Software
18 ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 module ShogiServer # for a namespace
24 # MonitorObserver observes GameResult to send messages to the monitors
28 def update(game_result)
29 game_result.game.each_monitor do |monitor_handler|
30 monitor_handler.write_safe(game_result.game.game_id, game_result.result_type)
35 # LoggingObserver appends a result of each game to a log file, which will
36 # be used to calculate rating scores of players.
40 @logfile = File.join($league.dir, "00LIST")
43 def update(game_result)
44 end_time_str = game_result.end_time.strftime("%Y/%m/%d %H:%M:%S")
45 black = game_result.black
46 white = game_result.white
47 black_name = black.rated? ? black.player_id : black.name
48 white_name = white.rated? ? white.player_id : white.name
50 game_result.log_summary_type,
51 game_result.black_result,
54 game_result.white_result,
55 game_result.game.logfile]
57 # Note that this is proccessed in the gian lock.
58 File.open(@logfile, "a") do |f|
59 f << msg.join("\t") << "\n"
63 $stderr.puts "Failed to write to the game result file: #{@logfile}" if $DEBUG
68 # Base abstract class for a game result.
69 # Imediate subclasses are GameResultWin and GameResultDraw.
82 # Command to send monitors such as '%TORYO' etc...
83 attr_reader :result_type
84 # Result types to write the main log file such as 'toryo' etc...
85 attr_reader :log_summary_type
86 # Time when the game ends
89 def initialize(game, p1, p2)
92 if p1.sente && !p2.sente
93 @black, @white = p1, p2
94 elsif !p1.sente && p2.sente
95 @black, @white = p2, p1
97 raise "Never reached!"
99 @players.each do |player|
100 player.status = "connected"
108 add_observer MonitorObserver.new
109 add_observer LoggingObserver.new
111 if League::Floodgate.game_name?(@game.game_name) &&
112 @game.sente.player_id && @game.gote.player_id
113 path = League::Floodgate.history_file_path(@game.game_name)
114 history = League::Floodgate::History.factory(path)
115 add_observer history if history
120 raise "Implement me!"
125 notify_observers(self)
133 log(@game.board.to_s.gsub(/^/, "\'").chomp)
137 return "Implemet me!"
141 return "Implemet me!"
146 log("'summary:%s:%s %s:%s %s" % [@log_summary_type,
147 @black.name, black_result,
148 @white.name, white_result])
152 class GameResultWin < GameResult
153 attr_reader :winner, :loser
155 def initialize(game, winner, loser)
157 @winner, @loser = winner, loser
158 @winner.last_game_win = true
159 @loser.last_game_win = false
163 return @black == @winner ? "win" : "lose"
167 return @black == @winner ? "lose" : "win"
171 class GameResultAbnormalWin < GameResultWin
172 def initialize(game, winner, loser)
174 @log_summary_type = "abnormal"
175 @result_type = "%TORYO"
179 @winner.write_safe("%TORYO\n#RESIGN\n#WIN\n")
180 @loser.write_safe( "%TORYO\n#RESIGN\n#LOSE\n")
187 class GameResultTimeoutWin < GameResultWin
188 def initialize(game, winner, loser)
190 @log_summary_type = "time up"
191 @result_type = "#TIME_UP"
195 @winner.write_safe("#TIME_UP\n#WIN\n")
196 @loser.write_safe( "#TIME_UP\n#LOSE\n")
203 # A player declares (successful) Kachi
204 class GameResultKachiWin < GameResultWin
205 def initialize(game, winner, loser)
207 @log_summary_type = "kachi"
208 @result_type = "%KACHI"
212 @winner.write_safe("%KACHI\n#JISHOGI\n#WIN\n")
213 @loser.write_safe( "%KACHI\n#JISHOGI\n#LOSE\n")
220 # A player declares wrong Kachi
221 class GameResultIllegalKachiWin < GameResultWin
222 def initialize(game, winner, loser)
224 @log_summary_type = "illegal kachi"
225 @result_type = "%KACHI"
229 @winner.write_safe("%KACHI\n#ILLEGAL_MOVE\n#WIN\n")
230 @loser.write_safe( "%KACHI\n#ILLEGAL_MOVE\n#LOSE\n")
237 class GameResultIllegalWin < GameResultWin
238 def initialize(game, winner, loser, cause)
239 super(game, winner, loser)
240 @log_summary_type = cause
241 @result_type = "#ILLEGAL_MOVE"
245 @winner.write_safe("#ILLEGAL_MOVE\n#WIN\n")
246 @loser.write_safe( "#ILLEGAL_MOVE\n#LOSE\n")
253 class GameResultIllegalMoveWin < GameResultIllegalWin
254 def initialize(game, winner, loser)
255 super(game, winner, loser, "illegal move")
259 class GameResultUchifuzumeWin < GameResultIllegalWin
260 def initialize(game, winner, loser)
261 super(game, winner, loser, "uchifuzume")
265 class GameResultOuteKaihiMoreWin < GameResultIllegalWin
266 def initialize(game, winner, loser)
267 super(game, winner, loser, "oute_kaihimore")
271 # This won't happen, though.
273 class GameResultOutoriWin < GameResultIllegalWin
274 def initialize(game, winner, loser)
275 super(game, winner, loser, "outori")
279 class GameResultToryoWin < GameResultWin
280 def initialize(game, winner, loser)
282 @log_summary_type = "toryo"
283 @result_type = "%TORYO"
287 @winner.write_safe("%TORYO\n#RESIGN\n#WIN\n")
288 @loser.write_safe( "%TORYO\n#RESIGN\n#LOSE\n")
295 class GameResultOuteSennichiteWin < GameResultWin
296 def initialize(game, winner, loser)
298 @log_summary_type = "oute_sennichite"
299 @result_type = "#OUTE_SENNICHITE"
303 @winner.write_safe("#OUTE_SENNICHITE\n#WIN\n")
304 @loser.write_safe( "#OUTE_SENNICHITE\n#LOSE\n")
313 class GameResultDraw < GameResult
314 def initialize(game, p1, p2)
316 p1.last_game_win = false
317 p2.last_game_win = false
329 class GameResultSennichiteDraw < GameResultDraw
330 def initialize(game, winner, loser)
332 @log_summary_type = "sennichite"
333 @result_type = "#SENNICHITE"
337 @players.each do |player|
338 player.write_safe("#SENNICHITE\n#DRAW\n")