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
legal?()
click to toggle source
# File lib/ruby_shogi/board.rb, line 113 def legal? pieces = [0] * 20 @brd.each { |p| pieces[p + 9] += 1 } return false if pieces[-6 + 9] == 0 || pieces[6 + 9] == 0 true 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
# File lib/ruby_shogi/board.rb, line 453 def print_board s ="" 81.times do | i | x, y = i % 9, i / 9 p = @brd[9 * (8 - y) + x] ch = "." PIECES.each do |pie, num| if num.to_i == p.to_i ch = pie.to_s break end end s << " " if ch.length < 2 s << ch if (i + 1) % 9 == 0 s << " #{((9 - i / 9).to_i).to_s}\n" end end 9.times { |i| s << " " << ("a".ord + i).chr } s << "\n[ wtm: #{@wtm} ]\n" s << "[ r50: #{(@r50/2).to_i} ]\n" s << "[ pocket: #{pocket2str} ]\n" s << "[ fen: #{pos2fen} ]\n" puts s end
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