3 ## Copyright (C) 2004 NABEYA Kenichi (aka nanami@2ch)
4 ## Copyright (C) 2007-2012 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
20 module ShogiServer # for a namespace
23 PROMOTE = {"FU" => "TO", "KY" => "NY", "KE" => "NK",
24 "GI" => "NG", "KA" => "UM", "HI" => "RY"}
25 def initialize(board, x, y, sente, promoted=false)
32 if ((x == 0) || (y == 0))
34 hands = board.sente_hands
36 hands = board.gote_hands
43 @board.array[x][y] = self
46 attr_accessor :promoted, :sente, :x, :y, :board
48 def room_of_head?(x, y, name)
53 return adjacent_movable_grids + far_movable_grids
61 if ((1 <= x) && (x <= 9) && (1 <= y) && (y <= 9))
62 if ((@board.array[x][y] == nil) || # dst is empty
63 (@board.array[x][y].sente != @sente)) # dst is enemy
71 if ((1 <= x) && (x <= 9) && (1 <= y) && (y <= 9))
72 if (@board.array[x][y] == nil) # dst is empty?
79 def adjacent_movable_grids
82 moves = @promoted_moves
86 moves.each do |(dx, dy)|
93 if (jump_to?(cand_x, cand_y))
94 grids.push([cand_x, cand_y])
100 def move_to?(x, y, name)
101 return false if (! room_of_head?(x, y, name))
102 return false if ((name != @name) && (name != @promoted_name))
103 return false if (@promoted && (name != @promoted_name)) # can't un-promote
106 return false if (((@x == 0) || (@y == 0)) && (name != @name)) # can't put promoted piece
108 return false if ((4 <= @y) && (4 <= y) && (name != @name)) # can't promote
110 return false if ((6 >= @y) && (6 >= y) && (name != @name))
114 if ((@x == 0) || (@y == 0))
115 return jump_to?(x, y)
117 return movable_grids.include?([x, y])
122 if ((@x == 0) || (@y == 0))
124 @board.sente_hands.delete(self)
126 @board.gote_hands.delete(self)
128 @board.array[x][y] = self
129 elsif ((x == 0) || (y == 0))
130 @promoted = false # clear promoted flag before moving to hands
132 @board.sente_hands.push(self)
134 @board.gote_hands.push(self)
136 @board.array[@x][@y] = nil
138 @board.array[@x][@y] = nil
139 @board.array[x][y] = self
158 return @promoted ? @promoted_name : @name
167 return sg + current_name
171 class PieceFU < Piece
174 @normal_moves = [[0, +1]]
175 @promoted_moves = [[0, +1], [+1, +1], [-1, +1], [+1, +0], [-1, +0], [0, -1]]
177 @promoted_name = "TO"
180 def room_of_head?(x, y, name)
183 return false if (y == 1)
185 return false if (y == 9)
191 if ((iy != @y) && # not source position
192 @board.array[x][iy] &&
193 (@board.array[x][iy].sente == @sente) && # mine
194 (@board.array[x][iy].name == "FU") &&
195 (@board.array[x][iy].promoted == false))
205 class PieceKY < Piece
209 @promoted_moves = [[0, +1], [+1, +1], [-1, +1], [+1, +0], [-1, +0], [0, -1]]
211 @promoted_name = "NY"
214 def room_of_head?(x, y, name)
217 return false if (y == 1)
219 return false if (y == 9)
224 def far_movable_grids
232 while (jump_to?(cand_x, cand_y))
233 grids.push([cand_x, cand_y])
234 break if (! put_to?(cand_x, cand_y))
240 while (jump_to?(cand_x, cand_y))
241 grids.push([cand_x, cand_y])
242 break if (! put_to?(cand_x, cand_y))
251 class PieceKE < Piece
254 @normal_moves = [[+1, +2], [-1, +2]]
255 @promoted_moves = [[0, +1], [+1, +1], [-1, +1], [+1, +0], [-1, +0], [0, -1]]
257 @promoted_name = "NK"
260 def room_of_head?(x, y, name)
263 return false if ((y == 1) || (y == 2))
265 return false if ((y == 9) || (y == 8))
271 class PieceGI < Piece
274 @normal_moves = [[0, +1], [+1, +1], [-1, +1], [+1, -1], [-1, -1]]
275 @promoted_moves = [[0, +1], [+1, +1], [-1, +1], [+1, +0], [-1, +0], [0, -1]]
277 @promoted_name = "NG"
281 class PieceKI < Piece
284 @normal_moves = [[0, +1], [+1, +1], [-1, +1], [+1, +0], [-1, +0], [0, -1]]
291 class PieceKA < Piece
295 @promoted_moves = [[0, +1], [+1, 0], [-1, 0], [0, -1]]
297 @promoted_name = "UM"
300 def far_movable_grids
305 while (jump_to?(cand_x, cand_y))
306 grids.push([cand_x, cand_y])
307 break if (! put_to?(cand_x, cand_y))
314 while (jump_to?(cand_x, cand_y))
315 grids.push([cand_x, cand_y])
316 break if (! put_to?(cand_x, cand_y))
323 while (jump_to?(cand_x, cand_y))
324 grids.push([cand_x, cand_y])
325 break if (! put_to?(cand_x, cand_y))
332 while (jump_to?(cand_x, cand_y))
333 grids.push([cand_x, cand_y])
334 break if (! put_to?(cand_x, cand_y))
341 class PieceHI < Piece
345 @promoted_moves = [[+1, +1], [-1, +1], [+1, -1], [-1, -1]]
347 @promoted_name = "RY"
350 def far_movable_grids
355 while (jump_to?(cand_x, cand_y))
356 grids.push([cand_x, cand_y])
357 break if (! put_to?(cand_x, cand_y))
363 while (jump_to?(cand_x, cand_y))
364 grids.push([cand_x, cand_y])
365 break if (! put_to?(cand_x, cand_y))
371 while (jump_to?(cand_x, cand_y))
372 grids.push([cand_x, cand_y])
373 break if (! put_to?(cand_x, cand_y))
379 while (jump_to?(cand_x, cand_y))
380 grids.push([cand_x, cand_y])
381 break if (! put_to?(cand_x, cand_y))
387 class PieceOU < Piece
390 @normal_moves = [[0, +1], [+1, +1], [-1, +1], [+1, +0], [-1, +0], [0, -1], [+1, -1], [-1, -1]]