mirror of
https://github.com/SleepingInsomniac/lx_chess_cr
synced 2024-12-26 09:58:57 +01:00
Add disambiguation to SAN generation
This commit is contained in:
parent
d8c2a79733
commit
5427797139
6 changed files with 133 additions and 24 deletions
|
@ -1,5 +1,5 @@
|
||||||
name: lx_chess
|
name: lx_chess
|
||||||
version: 0.1.0
|
version: 0.1.3
|
||||||
|
|
||||||
authors:
|
authors:
|
||||||
- Alex Clink <alexclink@gmail.com>
|
- Alex Clink <alexclink@gmail.com>
|
||||||
|
|
100
spec/lx_chess/game/move_to_san_spec.cr
Normal file
100
spec/lx_chess/game/move_to_san_spec.cr
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
require "../../spec_helper"
|
||||||
|
|
||||||
|
include LxChess
|
||||||
|
|
||||||
|
describe Game do
|
||||||
|
describe "#move_to_san" do
|
||||||
|
it "converts pawn captures" do
|
||||||
|
game = Game.new players: [Player.new, Player.new]
|
||||||
|
place(game.board, {
|
||||||
|
"e4" => 'P',
|
||||||
|
"d5" => 'p',
|
||||||
|
})
|
||||||
|
debug_board(game, ["e4", "d5"])
|
||||||
|
san = game.move_to_san(from: "e4", to: "d5", turn: 0)
|
||||||
|
puts san.to_s
|
||||||
|
san.to_s.should eq("exd5")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "converts pawn moves" do
|
||||||
|
game = Game.new players: [Player.new, Player.new]
|
||||||
|
place(game.board, {"e2" => 'P'})
|
||||||
|
debug_board(game, ["e2", "e4"])
|
||||||
|
san = game.move_to_san(from: "e2", to: "e4", turn: 0)
|
||||||
|
puts san.to_s
|
||||||
|
san.to_s.should eq("e4")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "disambiguates pawn captures" do
|
||||||
|
game = Game.new players: [Player.new, Player.new]
|
||||||
|
place(game.board, {
|
||||||
|
"c4" => 'P',
|
||||||
|
"e4" => 'P',
|
||||||
|
"d5" => 'p',
|
||||||
|
})
|
||||||
|
debug_board(game, ["e4", "d5"])
|
||||||
|
san = game.move_to_san(from: "e4", to: "d5", turn: 0)
|
||||||
|
puts san.to_s
|
||||||
|
san.to_s.should eq("exd5")
|
||||||
|
debug_board(game, ["c4", "d5"])
|
||||||
|
san = game.move_to_san(from: "c4", to: "d5", turn: 0)
|
||||||
|
puts san.to_s
|
||||||
|
san.to_s.should eq("cxd5")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "disambiguates rook moves" do
|
||||||
|
game = Game.new players: [Player.new, Player.new]
|
||||||
|
place(game.board, {
|
||||||
|
"e4" => 'R',
|
||||||
|
"d5" => 'R',
|
||||||
|
})
|
||||||
|
debug_board(game, ["e4", "e5"])
|
||||||
|
san = game.move_to_san(from: "e4", to: "e5", turn: 0)
|
||||||
|
puts san.to_s
|
||||||
|
san.to_s.should eq("Ree5")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "disambiguates knight moves" do
|
||||||
|
game = Game.new players: [Player.new, Player.new]
|
||||||
|
place(game.board, {
|
||||||
|
"f3" => 'N',
|
||||||
|
"e2" => 'N',
|
||||||
|
})
|
||||||
|
debug_board(game, ["e2", "d4"])
|
||||||
|
san = game.move_to_san(from: "e2", to: "d4", turn: 0)
|
||||||
|
puts san.to_s
|
||||||
|
san.to_s.should eq("Ned4")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "disambiguates knight moves on the same file" do
|
||||||
|
game = Game.new players: [Player.new, Player.new]
|
||||||
|
place(game.board, {
|
||||||
|
"e4" => 'N',
|
||||||
|
"e2" => 'N',
|
||||||
|
})
|
||||||
|
debug_board(game, ["e2", "c3"])
|
||||||
|
san = game.move_to_san(from: "e2", to: "c3", turn: 0)
|
||||||
|
puts san.to_s
|
||||||
|
san.to_s.should eq("Ne2c3")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "detects check" do
|
||||||
|
game = Game.new players: [Player.new, Player.new]
|
||||||
|
game.board["e1"] = Piece.from_fen('K')
|
||||||
|
game.board["c8"] = Piece.from_fen('r')
|
||||||
|
debug_board(game, ["c8", "e8"])
|
||||||
|
san = game.move_to_san(from: "c8", to: "e8", turn: 1)
|
||||||
|
puts san.to_s
|
||||||
|
san.to_s.should eq("Re8+")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "detects checkmate" do
|
||||||
|
fen = Fen.parse("r1bqkb1r/pppp1ppp/2n2n2/4p2Q/2B1P3/8/PPPP1PPP/RNB1K1NR w KQkq - 4 4")
|
||||||
|
game = Game.new(board: fen.board, players: [Player.new, Player.new])
|
||||||
|
san = game.move_to_san(from: "h5", to: "f7", turn: 0)
|
||||||
|
debug_board(game, ["h5", "f7"])
|
||||||
|
puts san.to_s
|
||||||
|
san.to_s.should eq("Qxf7#")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -74,25 +74,6 @@ describe Game do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#move_to_san" do
|
|
||||||
it "detects check" do
|
|
||||||
game = Game.new players: [Player.new, Player.new]
|
|
||||||
game.board["e1"] = Piece.from_fen('K')
|
|
||||||
game.board["c8"] = Piece.from_fen('r')
|
|
||||||
debug_board(game, ["c8", "e8"])
|
|
||||||
san = game.move_to_san(from: "c8", to: "e8", turn: 1)
|
|
||||||
san.to_s.should eq("Re8+")
|
|
||||||
end
|
|
||||||
|
|
||||||
it "detects checkmate" do
|
|
||||||
fen = Fen.parse("r1bqkb1r/pppp1ppp/2n2n2/4p2Q/2B1P3/8/PPPP1PPP/RNB1K1NR w KQkq - 4 4")
|
|
||||||
game = Game.new(board: fen.board, players: [Player.new, Player.new])
|
|
||||||
san = game.move_to_san(from: "h5", to: "f7", turn: 0)
|
|
||||||
debug_board(game, ["h5", "f7"])
|
|
||||||
san.to_s.should eq("Qxf7#")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "#in_check?" do
|
describe "#in_check?" do
|
||||||
it "detects if the player is in check" do
|
it "detects if the player is in check" do
|
||||||
game = Game.new players: [Player.new, Player.new]
|
game = Game.new players: [Player.new, Player.new]
|
||||||
|
|
|
@ -175,18 +175,46 @@ module LxChess
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
candidate_move_sets = @board.select do |candidate|
|
||||||
|
next unless candidate
|
||||||
|
next if candidate == piece
|
||||||
|
candidate.fen_symbol == piece.fen_symbol
|
||||||
|
end.compact.map do |candidate|
|
||||||
|
moves(candidate.index)
|
||||||
|
end.compact.select do |move_set|
|
||||||
|
move_set.moves.includes?(to)
|
||||||
|
end
|
||||||
|
|
||||||
|
origin = nil
|
||||||
|
takes = en_passant || !@board[to].nil?
|
||||||
|
|
||||||
|
if candidate_move_sets.any?
|
||||||
|
origin ||= ""
|
||||||
|
origin += @board.cord(from)[0]
|
||||||
|
end
|
||||||
|
|
||||||
|
if candidate_move_sets.any? { |set| @board.cord(set.piece.index)[0] == @board.cord(from)[0] }
|
||||||
|
origin ||= ""
|
||||||
|
origin += @board.cord(from)[1]
|
||||||
|
end
|
||||||
|
|
||||||
|
if origin.nil? && piece.pawn? && takes
|
||||||
|
origin = @board.cord(from)[0].to_s
|
||||||
|
end
|
||||||
|
|
||||||
Notation.new(
|
Notation.new(
|
||||||
square: @board.cord(to),
|
square: @board.cord(to),
|
||||||
promotion: promotion,
|
promotion: promotion,
|
||||||
piece_abbr: piece.fen_symbol,
|
piece_abbr: piece.fen_symbol,
|
||||||
from: @board.cord(from),
|
from: @board.cord(from),
|
||||||
to: @board.cord(to),
|
to: @board.cord(to),
|
||||||
takes: en_passant || !@board[to].nil?,
|
takes: takes,
|
||||||
en_passant: en_passant,
|
en_passant: en_passant,
|
||||||
check: check && !checkmate,
|
check: check && !checkmate,
|
||||||
checkmate: checkmate,
|
checkmate: checkmate,
|
||||||
castles_k: castles_k,
|
castles_k: castles_k,
|
||||||
castles_q: castles_q
|
castles_q: castles_q,
|
||||||
|
origin: origin
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -156,7 +156,7 @@ module LxChess
|
||||||
when castles_q?
|
when castles_q?
|
||||||
"O-O-O"
|
"O-O-O"
|
||||||
else
|
else
|
||||||
piece_abbr != 'P' || @takes ? piece_abbr : nil
|
piece_abbr unless piece_abbr == 'P'
|
||||||
end
|
end
|
||||||
|
|
||||||
if @en_passant
|
if @en_passant
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
module LxChess
|
module LxChess
|
||||||
VERSION = "0.1.2"
|
VERSION = "0.1.3"
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue