OSDN Git Service

Added a new feature, LoggingObserver, which logs a result of each game.
authorbeatles <beatles@b8c68f68-1e22-0410-b08e-880e1f8202b4>
Sun, 15 Nov 2009 13:24:44 +0000 (13:24 +0000)
committerbeatles <beatles@b8c68f68-1e22-0410-b08e-880e1f8202b4>
Sun, 15 Nov 2009 13:24:44 +0000 (13:24 +0000)
changelog
shogi_server/game.rb
shogi_server/game_result.rb
test/TC_game_result.rb

index 3ef2cd9..fe7794b 100644 (file)
--- a/changelog
+++ b/changelog
@@ -1,11 +1,27 @@
+2009-11-10 Daigo Moriwaki <daigo at debian dot org>
+
+       * [shogi-server]
+         - The server logs a result of each game to a file named '00LIST',
+           which will be used to generate players.yaml. If the file does
+           not exist, the server will create one automatically.
+           Instruction to use the game result list file:
+           1. Make a list of game results from exisiting CSA files with
+              mk_game_results
+              % ./mk_game_results dir_of_csa_files > 00LIST
+           2. Run the server. It appends a result of each game to
+              '00LIST' when the game finishes.
+           3. From the list of game results, calcurate rating scores of
+              players.
+              % ./mk_rate 00LIST > players.yaml
+
 2009-11-08 Daigo Moriwaki <daigo at debian dot org>
 
        * [mk_rate]
          - Split a pre-process collecting game results from csa files into
            a new command, mk_game_results. Now, Generating players.yaml
            requires two steps as follows:
 2009-11-08 Daigo Moriwaki <daigo at debian dot org>
 
        * [mk_rate]
          - Split a pre-process collecting game results from csa files into
            a new command, mk_game_results. Now, Generating players.yaml
            requires two steps as follows:
-             % ./mk_game_results dir_of_csa_files > 00list
-             % ./mk_rate 00list > players.yaml
+             % ./mk_game_results dir_of_csa_files > 00LIST
+             % ./mk_rate 00LIST > players.yaml
              or
              % ./mk_game_results dir_of_csa_files | ./mk_rate > players.yaml 
            (Closes: #19454)
              or
              % ./mk_game_results dir_of_csa_files | ./mk_rate > players.yaml 
            (Closes: #19454)
index 4aeaf3a..532c552 100644 (file)
@@ -138,15 +138,20 @@ class Game
     end
     
     if (@current_player == killer)
     end
     
     if (@current_player == killer)
-      result = GameResultAbnormalWin.new(self, @next_player, @current_player)
-      result.process
+      @result = GameResultAbnormalWin.new(self, @next_player, @current_player)
+      @result.process
       finish
     end
   end
 
   def finish
     log_message(sprintf("game finished %s", @game_id))
       finish
     end
   end
 
   def finish
     log_message(sprintf("game finished %s", @game_id))
-    @fh.printf("'$END_TIME:%s\n", Time::new.strftime("%Y/%m/%d %H:%M:%S"))    
+
+    # In a case where a player in agree_waiting or start_waiting status is
+    # rejected, a GameResult object is not yet instanciated.
+    # See test/TC_before_agree.rb.
+    end_time = @result ? @result.end_time : Time.now
+    @fh.printf("'$END_TIME:%s\n", end_time.strftime("%Y/%m/%d %H:%M:%S"))    
     @fh.close
 
     @sente.game = nil
     @fh.close
 
     @sente.game = nil
@@ -218,39 +223,39 @@ class Game
       end
     end
 
       end
     end
 
-    result = nil
+    @result = nil
     if (@next_player.status != "game") # rival is logout or disconnected
     if (@next_player.status != "game") # rival is logout or disconnected
-      result = GameResultAbnormalWin.new(self, @current_player, @next_player)
+      @result = GameResultAbnormalWin.new(self, @current_player, @next_player)
     elsif (status == :timeout)
       # current_player losed
     elsif (status == :timeout)
       # current_player losed
-      result = GameResultTimeoutWin.new(self, @next_player, @current_player)
+      @result = GameResultTimeoutWin.new(self, @next_player, @current_player)
     elsif (move_status == :illegal)
     elsif (move_status == :illegal)
-      result = GameResultIllegalMoveWin.new(self, @next_player, @current_player)
+      @result = GameResultIllegalMoveWin.new(self, @next_player, @current_player)
     elsif (move_status == :kachi_win)
     elsif (move_status == :kachi_win)
-      result = GameResultKachiWin.new(self, @current_player, @next_player)
+      @result = GameResultKachiWin.new(self, @current_player, @next_player)
     elsif (move_status == :kachi_lose)
     elsif (move_status == :kachi_lose)
-      result = GameResultIllegalKachiWin.new(self, @next_player, @current_player)
+      @result = GameResultIllegalKachiWin.new(self, @next_player, @current_player)
     elsif (move_status == :toryo)
     elsif (move_status == :toryo)
-      result = GameResultToryoWin.new(self, @next_player, @current_player)
+      @result = GameResultToryoWin.new(self, @next_player, @current_player)
     elsif (move_status == :outori)
       # The current player captures the next player's king
     elsif (move_status == :outori)
       # The current player captures the next player's king
-      result = GameResultOutoriWin.new(self, @current_player, @next_player)
+      @result = GameResultOutoriWin.new(self, @current_player, @next_player)
     elsif (move_status == :oute_sennichite_sente_lose)
     elsif (move_status == :oute_sennichite_sente_lose)
-      result = GameResultOuteSennichiteWin.new(self, @gote, @sente) # Sente is checking
+      @result = GameResultOuteSennichiteWin.new(self, @gote, @sente) # Sente is checking
     elsif (move_status == :oute_sennichite_gote_lose)
     elsif (move_status == :oute_sennichite_gote_lose)
-      result = GameResultOuteSennichiteWin.new(self, @sente, @gote) # Gote is checking
+      @result = GameResultOuteSennichiteWin.new(self, @sente, @gote) # Gote is checking
     elsif (move_status == :sennichite)
     elsif (move_status == :sennichite)
-      result = GameResultSennichiteDraw.new(self, @current_player, @next_player)
+      @result = GameResultSennichiteDraw.new(self, @current_player, @next_player)
     elsif (move_status == :uchifuzume)
       # the current player losed
     elsif (move_status == :uchifuzume)
       # the current player losed
-      result = GameResultUchifuzumeWin.new(self, @next_player, @current_player)
+      @result = GameResultUchifuzumeWin.new(self, @next_player, @current_player)
     elsif (move_status == :oute_kaihimore)
       # the current player losed
     elsif (move_status == :oute_kaihimore)
       # the current player losed
-      result = GameResultOuteKaihiMoreWin.new(self, @next_player, @current_player)
+      @result = GameResultOuteKaihiMoreWin.new(self, @next_player, @current_player)
     else
       finish_flag = false
     end
     else
       finish_flag = false
     end
-    result.process if result
+    @result.process if @result
     finish() if finish_flag
     @current_player, @next_player = @next_player, @current_player
     @start_time = Time::new
     finish() if finish_flag
     @current_player, @next_player = @next_player, @current_player
     @start_time = Time::new
index 39a9c62..81a438a 100644 (file)
@@ -32,7 +32,41 @@ class MonitorObserver
   end
 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
 #
 class GameResult
   include Observable
@@ -47,6 +81,10 @@ class GameResult
   attr_reader :white
   # Command to send monitors such as '%TORYO' etc...
   attr_reader :result_type
   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
 
   def initialize(game, p1, p2)
     @game = game
@@ -62,12 +100,13 @@ class GameResult
       player.status = "connected"
     end
     @result_type = ""
       player.status = "connected"
     end
     @result_type = ""
-
+    @end_time = Time.now
     regist_observers
   end
 
   def regist_observers
     add_observer MonitorObserver.new
     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 &&
 
     if League::Floodgate.game_name?(@game.game_name) &&
        @game.sente.player_id &&
@@ -75,7 +114,6 @@ class GameResult
        $options["floodgate-history"]
       add_observer League::Floodgate::History.factory
     end
        $options["floodgate-history"]
       add_observer League::Floodgate::History.factory
     end
-
   end
 
   def process
   end
 
   def process
@@ -95,6 +133,20 @@ class GameResult
     log(@game.board.to_s.gsub(/^/, "\'").chomp)
   end
 
     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
 end
 
 class GameResultWin < GameResult
@@ -107,65 +159,77 @@ class GameResultWin < GameResult
     @loser.last_game_win  = false
   end
 
     @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
   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")
   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
     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")
   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
     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")
   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
     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")
   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
     notify
   end
 end
@@ -173,14 +237,15 @@ end
 class GameResultIllegalWin < GameResultWin
   def initialize(game, winner, loser, cause)
     super(game, winner, loser)
 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")
   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
     notify
   end
 end
@@ -203,33 +268,48 @@ class GameResultOuteKaihiMoreWin < GameResultIllegalWin
   end
 end
 
   end
 end
 
-class GameResultOutoriWin < GameResultWin
+# This won't happen, though.
+#
+class GameResultOutoriWin < GameResultIllegalWin
   def initialize(game, winner, loser)
   def initialize(game, winner, loser)
-    super(game, winner, loser)
+    super(game, winner, loser, "outori")
   end
 end
 
 class GameResultToryoWin < GameResultWin
   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")
   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
     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")
   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
 
     notify
   end
 end
 
+# Draw
+#
 class GameResultDraw < GameResult
   def initialize(game, p1, p2)
     super
 class GameResultDraw < GameResult
   def initialize(game, p1, p2)
     super
@@ -237,22 +317,30 @@ class GameResultDraw < GameResult
     p2.last_game_win = false
   end
   
     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
   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
   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
     notify
   end
 end
 
 end # ShogiServer
-
index f7c3d78..277ec11 100644 (file)
@@ -4,6 +4,9 @@ require 'test/unit'
 require 'shogi_server'
 require 'shogi_server/game'
 
 require 'shogi_server'
 require 'shogi_server/game'
 
+$league = ShogiServer::League.new(File.dirname(__FILE__))
+$league.event = "TC_game_result"
+
 module ShogiServer
   class BasicPlayer
     attr_accessor :sente, :status
 module ShogiServer
   class BasicPlayer
     attr_accessor :sente, :status
@@ -27,72 +30,84 @@ class TestGameResult < Test::Unit::TestCase
     gr = ShogiServer::GameResultWin.new(@game, @p1, @p2)
     assert_equal(@p1.last_game_win, true)
     assert_equal(@p2.last_game_win, false)
     gr = ShogiServer::GameResultWin.new(@game, @p1, @p2)
     assert_equal(@p1.last_game_win, true)
     assert_equal(@p2.last_game_win, false)
+    assert_equal(nil, gr.log_summary_type)
   end
 
   def test_game_result_abnormal_win
     gr = ShogiServer::GameResultAbnormalWin.new(@game, @p1, @p2)
     assert_equal(@p1.last_game_win, true)
     assert_equal(@p2.last_game_win, false)
   end
 
   def test_game_result_abnormal_win
     gr = ShogiServer::GameResultAbnormalWin.new(@game, @p1, @p2)
     assert_equal(@p1.last_game_win, true)
     assert_equal(@p2.last_game_win, false)
+    assert_equal("abnormal", gr.log_summary_type)
   end
 
   def test_game_result_kachi_win
     gr = ShogiServer::GameResultKachiWin.new(@game, @p1, @p2)
     assert_equal(@p1.last_game_win, true)
     assert_equal(@p2.last_game_win, false)
   end
 
   def test_game_result_kachi_win
     gr = ShogiServer::GameResultKachiWin.new(@game, @p1, @p2)
     assert_equal(@p1.last_game_win, true)
     assert_equal(@p2.last_game_win, false)
+    assert_equal("kachi", gr.log_summary_type)
   end
 
   def test_game_result_illegal_kachi_win
     gr = ShogiServer::GameResultIllegalKachiWin.new(@game, @p1, @p2)
     assert_equal(@p1.last_game_win, true)
     assert_equal(@p2.last_game_win, false)
   end
 
   def test_game_result_illegal_kachi_win
     gr = ShogiServer::GameResultIllegalKachiWin.new(@game, @p1, @p2)
     assert_equal(@p1.last_game_win, true)
     assert_equal(@p2.last_game_win, false)
+    assert_equal("illegal kachi", gr.log_summary_type)
   end
 
   def test_game_result_illegal_move_win
     gr = ShogiServer::GameResultIllegalMoveWin.new(@game, @p1, @p2)
     assert_equal(@p1.last_game_win, true)
     assert_equal(@p2.last_game_win, false)
   end
 
   def test_game_result_illegal_move_win
     gr = ShogiServer::GameResultIllegalMoveWin.new(@game, @p1, @p2)
     assert_equal(@p1.last_game_win, true)
     assert_equal(@p2.last_game_win, false)
+    assert_equal("illegal move", gr.log_summary_type)
   end
 
   def test_game_result_uchifuzume_win
     gr = ShogiServer::GameResultUchifuzumeWin.new(@game, @p1, @p2)
     assert_equal(@p1.last_game_win, true)
     assert_equal(@p2.last_game_win, false)
   end
 
   def test_game_result_uchifuzume_win
     gr = ShogiServer::GameResultUchifuzumeWin.new(@game, @p1, @p2)
     assert_equal(@p1.last_game_win, true)
     assert_equal(@p2.last_game_win, false)
+    assert_equal("uchifuzume", gr.log_summary_type)
   end
 
   def test_game_result_oute_kaihi_more_win
     gr = ShogiServer::GameResultOuteKaihiMoreWin.new(@game, @p1, @p2)
     assert_equal(@p1.last_game_win, true)
     assert_equal(@p2.last_game_win, false)
   end
 
   def test_game_result_oute_kaihi_more_win
     gr = ShogiServer::GameResultOuteKaihiMoreWin.new(@game, @p1, @p2)
     assert_equal(@p1.last_game_win, true)
     assert_equal(@p2.last_game_win, false)
+    assert_equal("oute_kaihimore", gr.log_summary_type)
   end
 
   def test_game_result_outori_win
     gr = ShogiServer::GameResultOutoriWin.new(@game, @p1, @p2)
     assert_equal(@p1.last_game_win, true)
     assert_equal(@p2.last_game_win, false)
   end
 
   def test_game_result_outori_win
     gr = ShogiServer::GameResultOutoriWin.new(@game, @p1, @p2)
     assert_equal(@p1.last_game_win, true)
     assert_equal(@p2.last_game_win, false)
+    assert_equal("outori", gr.log_summary_type)
   end
 
   def test_game_result_toryo_win
     gr = ShogiServer::GameResultToryoWin.new(@game, @p1, @p2)
     assert_equal(@p1.last_game_win, true)
     assert_equal(@p2.last_game_win, false)
   end
 
   def test_game_result_toryo_win
     gr = ShogiServer::GameResultToryoWin.new(@game, @p1, @p2)
     assert_equal(@p1.last_game_win, true)
     assert_equal(@p2.last_game_win, false)
+    assert_equal("toryo", gr.log_summary_type)
   end
 
   def test_game_result_oute_sennichite_win
     gr = ShogiServer::GameResultOuteSennichiteWin.new(@game, @p1, @p2)
     assert_equal(@p1.last_game_win, true)
     assert_equal(@p2.last_game_win, false)
   end
 
   def test_game_result_oute_sennichite_win
     gr = ShogiServer::GameResultOuteSennichiteWin.new(@game, @p1, @p2)
     assert_equal(@p1.last_game_win, true)
     assert_equal(@p2.last_game_win, false)
+    assert_equal("oute_sennichite", gr.log_summary_type)
   end
 
   def test_game_result_draw
     gr = ShogiServer::GameResultDraw.new(@game, @p1, @p2)
     assert_equal(@p1.last_game_win, false)
     assert_equal(@p2.last_game_win, false)
   end
 
   def test_game_result_draw
     gr = ShogiServer::GameResultDraw.new(@game, @p1, @p2)
     assert_equal(@p1.last_game_win, false)
     assert_equal(@p2.last_game_win, false)
+    assert_equal(nil, gr.log_summary_type)
   end
 
   def test_game_result_sennichite_draw
     gr = ShogiServer::GameResultSennichiteDraw.new(@game, @p1, @p2)
     assert_equal(@p1.last_game_win, false)
     assert_equal(@p2.last_game_win, false)
   end
 
   def test_game_result_sennichite_draw
     gr = ShogiServer::GameResultSennichiteDraw.new(@game, @p1, @p2)
     assert_equal(@p1.last_game_win, false)
     assert_equal(@p2.last_game_win, false)
+    assert_equal("sennichite", gr.log_summary_type)
   end
 
 end
   end
 
 end