OSDN Git Service

Fixed a bug in the uchifuzume check.
authorbeatles <beatles@b8c68f68-1e22-0410-b08e-880e1f8202b4>
Sat, 16 Feb 2008 13:04:28 +0000 (13:04 +0000)
committerbeatles <beatles@b8c68f68-1e22-0410-b08e-880e1f8202b4>
Sat, 16 Feb 2008 13:04:28 +0000 (13:04 +0000)
changelog
shogi-server

index 65eb2ce..5df3ca0 100644 (file)
--- a/changelog
+++ b/changelog
@@ -3,6 +3,9 @@
        * [shogi-server]
          - Thread.abort_on_exception is now false, meaning that 
            a thread's abort does not affect the others. 
+         - The uchifuzume check did not generate promoting moves, which
+           could crash the server with illegal moves. This issue has
+           been fixed.
 
 2008-02-14 Daigo Moriwaki <daigo at debian dot org>
 
index 00a7bad..36e933e 100755 (executable)
@@ -1297,7 +1297,7 @@ class Board
         return false
       end
     else                        # gote
-      if ((rival_ou.y != 0) &&
+      if ((rival_ou.y != 1) &&
           (@array[rival_ou.x][rival_ou.y - 1]) &&
           (@array[rival_ou.x][rival_ou.y - 1].name == "FU") &&
           (@array[rival_ou.x][rival_ou.y - 1].sente == sente)) # uchifu true
@@ -1307,9 +1307,8 @@ class Board
         return false
       end
     end
-    
+
     ## case: rival_ou is moving
-    escaped = false
     rival_ou.movable_grids.each do |(cand_x, cand_y)|
       tmp_board = Marshal.load(Marshal.dump(self))
       s = tmp_board.move_to(rival_ou.x, rival_ou.y, cand_x, cand_y, "OU", ! sente)
@@ -1327,17 +1326,30 @@ class Board
         if (@array[x][y] &&
             (@array[x][y].sente != sente) &&
             @array[x][y].movable_grids.include?([fu_x, fu_y])) # capturable
+          
+          names = []
           if (@array[x][y].promoted)
-            name = @array[x][y].promoted_name
+            names << @array[x][y].promoted_name
           else
-            name = @array[x][y].name
+            names << @array[x][y].name
+            if @array[x][y].promoted_name && 
+               @array[x][y].move_to?(fu_x, fu_y, @array[x][y].promoted_name)
+              names << @array[x][y].promoted_name 
+            end
           end
-          tmp_board = Marshal.load(Marshal.dump(self))
-          s = tmp_board.move_to(x, y, fu_x, fu_y, name, ! sente)
-          raise "internal error" if (s != true)
-          if (! tmp_board.checkmated?(! sente)) # good move
-            return false
+          names.map! do |name|
+            tmp_board = Marshal.load(Marshal.dump(self))
+            s = tmp_board.move_to(x, y, fu_x, fu_y, name, ! sente)
+            if s == :illegal
+              s # result
+            else
+              tmp_board.checkmated?(! sente) # result
+            end
           end
+          all_illegal = names.find {|a| a != :illegal}
+          raise "internal error: legal move not found" if all_illegal == nil
+          r = names.find {|a| a == false} # good move
+          return false if r == false # found good move
         end
         y = y + 1
       end