class RubyShogi::Board

Constants

PIECES
START_POS

Attributes

bking[RW]
black_pocket[RW]
brd[RW]
drop[RW]
eat[RW]
from[RW]
fullmoves[RW]
hash[RW]
index[RW]
nodetype[RW]
promo[RW]
r50[RW]
score[RW]
to[RW]
variant[RW]
white_pocket[RW]
wking[RW]
wtm[RW]

Public Class Methods

new() click to toggle source
# File lib/ruby_shogi/board.rb, line 46
def initialize
        initme
end

Public Instance Methods

brd2str() click to toggle source
# File lib/ruby_shogi/board.rb, line 66
def brd2str
        s, empty, counter = "", 0, 0
        80.times do |j|
                i = 10 * (7 - j / 10) + ( j % 10 )
                p = @brd[i]
                if p != 0
                        if empty > 0
                                s += empty.to_s 
                                empty = 0
                        end
                        s += "fcakqrbnp.PNBRQKACF"[p + 9]
                else
                        empty += 1
                end
                counter += 1
                if counter % 10 == 0
                        s += empty.to_s if empty > 0
                        s += "/" if counter < 80
                        empty = 0
                end
        end
        s
end
copy_me() click to toggle source
# File lib/ruby_shogi/board.rb, line 163
def copy_me()
        copy = RubyShogi::Board.new
        copy.brd = @brd.dup
        copy.white_pocket = @white_pocket.dup
        copy.black_pocket = @black_pocket.dup
        copy.wtm = @wtm
        copy.from = @from
        copy.to = @to
        copy.r50 = @r50
        copy.wking = @wking
        copy.bking = @bking
        copy
end
count_jishogi_b() click to toggle source
# File lib/ruby_shogi/board.rb, line 246
def count_jishogi_b
        res = 0
        81.times do |i|
                if [-10, -12].include?(@brd[i])
                        res += 5 
                elsif @brd[i] != -14
                        res += 1
                end
        end
        res
end
count_jishogi_w() click to toggle source
# File lib/ruby_shogi/board.rb, line 234
def count_jishogi_w
        res = 0
        81.times do |i|
                if [10, 12].include?(@brd[i])
                        res += 5 
                elsif @brd[i] != 14
                        res += 1
                end
        end
        res
end
create_hash() click to toggle source
# File lib/ruby_shogi/board.rb, line 107
def create_hash
        @hash = 0
        81.times { | i | @hash ^= RubyShogi::Zobrist.get(20 * i + 8 + @brd[i]) }
        @hash ^= RubyShogi::Zobrist.get(20 * 80 + (@wtm ? 1 : 0))
end
distance(p1, p2) click to toggle source
# File lib/ruby_shogi/board.rb, line 209
def distance(p1, p2)
        [(p1 % 9 - p2 % 9 ).abs, (p1 / 9 - p2 / 9).abs].max
end
empty?(i) click to toggle source
# File lib/ruby_shogi/board.rb, line 189
def empty?(i)
        @brd[i].zero?
end
eval() click to toggle source
# File lib/ruby_shogi/board.rb, line 387
def eval
        Eval.eval(self)
end
fen(str) click to toggle source
# File lib/ruby_shogi/board.rb, line 372
def fen(str)
        initme
        s = str.strip.split(" ")
        fail if s.length < 3
        t = s[0].strip.split("[")
        fen_board(t[0])
        fen_pocket(t[1])
        @wtm = s[1] == "w" ? true : false
        @r50 = 2 * s[2].to_i if s.length >= 3
        @fullmoves = 2 * s[3].to_i if s.length >= 4
        mirror_board
        @wking = find_white_king
        @bking = find_black_king
end
fen2(s = nil) click to toggle source
# File lib/ruby_shogi/board.rb, line 364
def fen2(s = nil)
        if s.nil?
                fen(START_POS)
        else
                fen(s)
        end
end
fen_board(s) click to toggle source
# File lib/ruby_shogi/board.rb, line 327
def fen_board(s)
        s = s.gsub(/\d+/) { | m | "_" * m.to_i }
                .gsub(/\//) { | m | "" }
        i, k = 0, 0
        while i < s.length
                piece = s[i]
                if s[i] == "+"# && i + 1 < s.length
                        i += 1
                        piece = "+#{s[i]}"
                end
                @brd[k] = piece2number(piece)
                k += 1
                i += 1
        end
end
fen_pocket(s) click to toggle source
# File lib/ruby_shogi/board.rb, line 343
def fen_pocket(s)
        @white_pocket = []
        @black_pocket = []
        s.strip!
        return if s == "-"
        i = 0
        while i < s.length
                num = piece2number(s[i])
                if num > 0
                        @white_pocket.push(num)
                elsif num < 0
                        @black_pocket.push(num)
                end
                i += 1
        end
end
fen_wtm(s) click to toggle source
# File lib/ruby_shogi/board.rb, line 360
def fen_wtm(s)
        @wtm = s == "w" ? true : false
end
find_black_king() click to toggle source
# File lib/ruby_shogi/board.rb, line 130
def find_black_king
        @brd.index { | x | x == -14 }
end
find_piece(start_square, end_square, me, diff = 1) click to toggle source

scans ->

# File lib/ruby_shogi/board.rb, line 139
def find_piece(start_square, end_square, me, diff = 1)
        i = start_square
        loop do
                return i if @brd[i] == me
                fail "ShurikenShogi Error: Couldn't Find: '#{me}'" if i == end_square
                i += diff
        end
end
find_piece_all(piece) click to toggle source
# File lib/ruby_shogi/board.rb, line 134
def find_piece_all(piece)
        @brd.index { | x | x == piece }
end
find_white_king() click to toggle source
# File lib/ruby_shogi/board.rb, line 126
def find_white_king
        @brd.index { | x | x == 14 }
end
first_rank?(x) click to toggle source
# File lib/ruby_shogi/board.rb, line 185
def first_rank?(x)
        y_coord(x) == 0
end
flip_coord(coord) click to toggle source
# File lib/ruby_shogi/board.rb, line 269
def flip_coord(coord)
        (9 - 1 - y_coord(coord)) * 9 + x_coord(coord)
end
good_coord?(i) click to toggle source
# File lib/ruby_shogi/board.rb, line 205
def good_coord?(i)     
        i >= 0 && i < 81
end
initme() click to toggle source
# File lib/ruby_shogi/board.rb, line 50
def initme
        @brd = [0] * 81
        @wtm, @from, @to, @eat = true, 0, 0, 0
        @score, @promo = 0, 0
        @white_pocket = []
        @black_pocket = []
        @index = 0
        @r50 = 0
        @drop = 0
        @hash = 0
        @wking = 0
        @bking = 0
        @fullmoves = 2
        @nodetype = 0 # 2 draw 1 win -1 loss
end
is_on_board?(x, y) click to toggle source
# File lib/ruby_shogi/board.rb, line 201
def is_on_board?(x, y) 
        x >= 0 && x <= 8 && y >= 0 && y <= 8
end
jishogi?() click to toggle source

TODO improve likely?

# File lib/ruby_shogi/board.rb, line 226
def jishogi?
        wking, bking = find_white_king, find_black_king
        if wking / 9 >= 6 && bking / 9 <= 2 && jishogi_likely_w?(wking) && jishogi_likely_b?(bking)
                return true
        end
        false
end
jishogi_likely_b?(bking) click to toggle source
# File lib/ruby_shogi/board.rb, line 219
def jishogi_likely_b?(bking)
        res = 0
        81.times { |i| res += 1 if @brd[i] < 0 && distance(bking, i) < 3 }
        res > 5
end
jishogi_likely_w?(wking) click to toggle source
# File lib/ruby_shogi/board.rb, line 213
def jishogi_likely_w?(wking)
        res = 0
        81.times { |i| res += 1 if @brd[i] > 0 && distance(wking, i) < 3 }
        res > 5
end
just_kings?() click to toggle source

scans ->

# File lib/ruby_shogi/board.rb, line 149
def just_kings?
        81.times do |i|
                return false if @brd[i] != 14 && @brd[i] != -14
        end
        true
end
last_rank?(square) click to toggle source
# File lib/ruby_shogi/board.rb, line 181
def last_rank?(square)
        y_coord(square) == 8
end
make_move(me, from, to) click to toggle source
# File lib/ruby_shogi/board.rb, line 120
def make_move(me, from, to)
        @eat = @brd[to]
        @brd[to] = me
        @brd[from] = 0
end
material() click to toggle source
# File lib/ruby_shogi/board.rb, line 391
def material
        Eval.material(self)
end
material_draw?() click to toggle source
# File lib/ruby_shogi/board.rb, line 156
def material_draw?
        81.times do |i|
                return false if @brd[i] != 14 && @brd[i] != -14 && @brd[i] != 0
        end
        true
end
mgen_generator() click to toggle source
# File lib/ruby_shogi/board.rb, line 103
def mgen_generator
        @wtm ? RubyShogi::MgenWhite.new(self) : RubyShogi::MgenBlack.new(self)
end
mirror_board() click to toggle source
# File lib/ruby_shogi/board.rb, line 258
def mirror_board
        (4*9).times do | i |
                x, y = i % 9, i / 9
                flip_y = x + (8 - y) * 9
                p1 = @brd[i]
                p2 = @brd[flip_y]
                @brd[i] = p2
                @brd[flip_y] = p1
        end
end
move2str() click to toggle source
# File lib/ruby_shogi/board.rb, line 402
def move2str
        move_str
end
move_str() click to toggle source
# File lib/ruby_shogi/board.rb, line 406
def move_str
        if @drop != 0
                s = "#{number2piece(@drop).upcase}@"
                tox, toy = @to % 9, @to / 9
                s << ("a".ord + tox).chr
                s << (toy + 1).to_s
                return s
        end
        fromx, fromy = @from % 9, @from / 9
        tox, toy = @to % 9, @to / 9
        s = ("a".ord + fromx).chr
        s << (fromy + 1).to_s
        s << ("a".ord + tox).chr
        s << (toy + 1).to_s
        if @promo == 2
                s << "+"
        elsif @promo == 1
                s << "="
        end
        s
end
mustbeok() click to toggle source
# File lib/ruby_shogi/board.rb, line 90
def mustbeok
        fail if find_white_king != @wking
        fail if find_black_king != @bking
end
number2piece(num) click to toggle source

TODO optimize

# File lib/ruby_shogi/board.rb, line 274
def number2piece(num)
        ret = 0
        PIECES.each { |piece2, num2| 
                if num.to_i == num2.to_i
                        ret = piece2
                        break
                end
        }
        ret.to_s
end
piece2number(piece) click to toggle source

TODO optimize

# File lib/ruby_shogi/board.rb, line 286
def piece2number(piece)
        ret = 0
        PIECES.each { |piece2, num| 
                if piece == piece2.to_s
                        ret = num 
                        break
                end
        }
        ret
end
pocket2str() click to toggle source
# File lib/ruby_shogi/board.rb, line 395
def pocket2str
        s = ""
        @white_pocket.each { |num| s << number2piece(num) }
        @black_pocket.each { |num| s << number2piece(num) }
        s.strip.length == 0 ? "-" : s
end
pos2fen() click to toggle source
# File lib/ruby_shogi/board.rb, line 297
def pos2fen
        s = ""
        9.times do |y|
                empty = 0
                9.times do |x|
                        p = @brd[9 * (8 - y) + x]
                        if p == 0
                                empty += 1
                        else
                                if empty > 0
                                        s << empty.to_s
                                        empty = 0
                                end
                                s << number2piece(p)
                        end
                end
                s << empty.to_s if empty > 0
                s << "/" if y < 8
        end
        s << "["
        @white_pocket.each { |p| s << number2piece(p) }
        @black_pocket.each { |p| s << number2piece(p) }
        s << "-" if @white_pocket.empty? && @black_pocket.empty?
        s << "] "
        s << (@wtm ? "w" : "b")
        s << " #{@r50.to_s}"
        s << " #{(@fullmoves/2).to_i}"
        s
end
print_board() click to toggle source
randpos() click to toggle source
# File lib/ruby_shogi/board.rb, line 441
def randpos
        brd = nil
        loop do
                brd = randpos2
                mgen = brd.mgen_generator
                next if mgen.checks_b? || mgen.checks_w?
                break
        end
        brd.mustbeok
        brd
end
randpos2() click to toggle source
# File lib/ruby_shogi/board.rb, line 428
def randpos2
        copy = RubyShogi::Board.new
        copy.brd[rand(0..9)] = 14
        copy.brd[rand(71..80)] = -14
        8.times { |i| copy.brd[32 + i] = rand(-13..13) if rand < 0.3 }
        3.times { |i| copy.white_pocket.push([1, 3, 5, 7, 9].sample) if rand < 0.3  }
        3.times { |i| copy.black_pocket.push([-1, -3, -5, -7, -9].sample) if rand < 0.3 }
        copy.wking = copy.find_white_king
        copy.bking = copy.find_black_king
        copy
end
startpos() click to toggle source
# File lib/ruby_shogi/board.rb, line 177
def startpos
        fen(START_POS)
end
tofen() click to toggle source
# File lib/ruby_shogi/board.rb, line 99
def tofen
        "#{brd2str} #{wtm2str}"
end
walkable_b?(square) click to toggle source
# File lib/ruby_shogi/board.rb, line 197
def walkable_b?(square)
        @brd[square] >= 0
end
walkable_w?(square) click to toggle source
# File lib/ruby_shogi/board.rb, line 193
def walkable_w?(square)
        @brd[square] <= 0
end
wtm2str() click to toggle source
# File lib/ruby_shogi/board.rb, line 95
def wtm2str
        @wtm ? "w" : "b"
end