X-Git-Url: http://git.sourceforge.jp/view?p=shogi-server%2Fshogi-server.git;a=blobdiff_plain;f=shogi_server%2Fboard.rb;h=66d4d01d95d96f0b43145c18784fab221792bc25;hp=d7f94669d5f7d14980a18072cefd5a626987ea22;hb=b44ab891a52ed746631ff05a5f8b80eb4e5f24b1;hpb=2da79bca4e0c25714cc4e7b74fa17f859c83183a;ds=sidebyside diff --git a/shogi_server/board.rb b/shogi_server/board.rb index d7f9466..66d4d01 100644 --- a/shogi_server/board.rb +++ b/shogi_server/board.rb @@ -1,7 +1,7 @@ ## $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 @@ -25,23 +25,65 @@ class WrongMoves < ArgumentError; end class Board + # Initial board setup. + # The string ends with '+', not a line break. + # + INITIAL_HIRATE_POSITION = (<<-EOF).chomp +P1-KY-KE-GI-KI-OU-KI-GI-KE-KY +P2 * -HI * * * * * -KA * +P3-FU-FU-FU-FU-FU-FU-FU-FU-FU +P4 * * * * * * * * * +P5 * * * * * * * * * +P6 * * * * * * * * * +P7+FU+FU+FU+FU+FU+FU+FU+FU+FU +P8 * +KA * * * * * +HI * +P9+KY+KE+GI+KI+OU+KI+GI+KE+KY ++ +EOF + # Split a moves line into an array of a move string. # If it fails to parse the moves, it raises WrongMoves. - # @param moves a moves line. Ex. "+776FU-3334Fu" - # @return an array of a move string. Ex. ["+7776FU", "-3334FU"] + # @param moves a moves line. Ex. "+776FU-3334FU" or + # moves with times. Ex "+776FU,T2-3334FU,T5" + # @return an array of a move string. Ex. ["+7776FU", "-3334FU"] or + # an array of arrays. Ex. [["+7776FU","T2"], ["-3334FU", "T5"]] # def Board.split_moves(moves) ret = [] - rs = moves.gsub %r{[\+\-]\d{4}\w{2}} do |s| - ret << s - "" - end - raise WrongMoves, rs unless rs.empty? + i=0 + tmp = "" + while i true, white => false @initial_moves = [] + @move = nil + @ous = [nil, nil] # keep OU pieces of Sente and Gote end attr_accessor :array, :sente_hands, :gote_hands, :history, :sente_history, :gote_history, :teban attr_reader :move_count @@ -61,6 +105,11 @@ class Board # moves. attr_reader :initial_moves + # A move parsed by handle_one_move. If the move is not :normal, the board + # position may or may not be rolled back. + # + attr_reader :move + # See if self equals rhs, including a logical board position (i.e. # not see object IDs) and sennichite stuff. # @@ -111,6 +160,17 @@ class Board @teban = true end + # Cache OU piece. + # Piece#new will call back this method. + # + def add_ou(ou) + if ou.sente + @ous[0] = ou + else + @ous[1] = ou + end + end + # Set up a board with the strs. # Failing to parse the moves raises an StandardError. # @param strs a board text @@ -213,14 +273,21 @@ class Board # Set up a board starting with a position after the moves. # Failing to parse the moves raises an ArgumentError. - # @param moves an array of moves. ex. ["+7776FU", "-3334FU"] + # @param moves an array of moves. ex. ["+7776FU", "-3334FU"] or + # an array of arrays. ex. [["+7776FU","T2"], ["-3334FU","T5"]] # def set_from_moves(moves) initial() return :normal if moves.empty? rt = nil moves.each do |move| - rt = handle_one_move(move, @teban) + rt = nil + case move + when Array + rt = handle_one_move(move[0], @teban) + when String + rt = handle_one_move(move, @teban) + end raise ArgumentError, "bad moves: #{moves}" unless rt == :normal end @initial_moves = moves.dup @@ -307,22 +374,13 @@ class Board end # def each_reserved_square - + def look_for_ou(sente) - x = 1 - while (x <= 9) - y = 1 - while (y <= 9) - if (@array[x][y] && - (@array[x][y].name == "OU") && - (@array[x][y].sente == sente)) - return @array[x][y] - end - y = y + 1 - end - x = x + 1 + if sente + return @ous[0] + else + return @ous[1] end - raise "can't find ou" end # See if sente is checked (i.e. loosing) or not. @@ -626,18 +684,18 @@ class Board return :illegal # can't put on existing piece end - move = Move.new(x0, y0, x1, y1, name, sente) - result = move_to(move) + @move = Move.new(x0, y0, x1, y1, name, sente) + result = move_to(@move) if (result == :illegal) # self is unchanged return :illegal end if (checkmated?(sente)) - move_back(move) + move_back(@move) return :oute_kaihimore end if ((x0 == 0) && (y0 == 0) && (name == "FU") && uchifuzume?(sente)) - move_back(move) + move_back(@move) return :uchifuzume end @@ -645,12 +703,12 @@ class Board update_sennichite(sente) os_result = oute_sennichite?(sente) if os_result # :oute_sennichite_sente_lose or :oute_sennichite_gote_lose - move_back(move) + move_back(@move) restore_sennichite_stuff(*sennichite_stuff) return os_result end if sennichite? - move_back(move) + move_back(@move) restore_sennichite_stuff(*sennichite_stuff) return :sennichite end @@ -658,6 +716,8 @@ class Board return :normal end + # Return a CSA-styled string notation of the current position. + # def to_s a = Array::new y = 1 @@ -694,6 +754,14 @@ class Board a.push("%s\n" % [@teban ? "+" : "-"]) return a.join end + + # Return a CSA-styled string notation of the initial position. + # + def initial_string + tmp_board = self.class.new + tmp_board.initial + return tmp_board.to_s + end end end # ShogiServer