mirror of
https://github.com/SleepingInsomniac/lx_chess_cr
synced 2024-11-16 19:49:34 +01:00
Fix capture distinction in notation regex
This commit is contained in:
parent
1397a01aaf
commit
c9448fe368
2 changed files with 100 additions and 24 deletions
74
spec/lx_chess/notation_spec.cr
Normal file
74
spec/lx_chess/notation_spec.cr
Normal file
|
@ -0,0 +1,74 @@
|
|||
require "../spec_helper"
|
||||
require "../../src/lx_chess/notation"
|
||||
|
||||
include LxChess
|
||||
|
||||
describe Notation do
|
||||
describe "#new" do
|
||||
it "parses castling kingside" do
|
||||
notation = Notation.new("O-O")
|
||||
notation.castles_k?.should eq(true)
|
||||
end
|
||||
|
||||
it "parses pawn moves" do
|
||||
notation = Notation.new("e4")
|
||||
notation.square.should eq("e4")
|
||||
end
|
||||
|
||||
it "parses pawn moves that specify pawn" do
|
||||
notation = Notation.new("Pe4")
|
||||
notation.square.should eq("e4")
|
||||
notation.piece_abbr.should eq('P')
|
||||
end
|
||||
|
||||
it "parses pawn moves that specify captures" do
|
||||
notation = Notation.new("Pxe4")
|
||||
notation.square.should eq("e4")
|
||||
notation.piece_abbr.should eq('P')
|
||||
notation.takes.should be_true
|
||||
end
|
||||
|
||||
it "parses weird moves from larger boards" do
|
||||
notation = Notation.new("Pwxr32")
|
||||
notation.square.should eq("r32")
|
||||
notation.piece_abbr.should eq('P')
|
||||
notation.origin.should eq("w")
|
||||
notation.takes.should be_true
|
||||
end
|
||||
|
||||
it "parses file disambiguation" do
|
||||
notation = Notation.new("exd5")
|
||||
notation.origin.should eq("e")
|
||||
notation.takes.should be_true
|
||||
notation.square.should eq("d5")
|
||||
end
|
||||
|
||||
it "parses rank disambiguation" do
|
||||
notation = Notation.new("4xd5")
|
||||
notation.origin.should eq("4")
|
||||
notation.takes.should be_true
|
||||
notation.square.should eq("d5")
|
||||
end
|
||||
|
||||
it "parses bxe5 as a pawn move" do
|
||||
notation = Notation.new("bxe5")
|
||||
notation.origin.should eq("b")
|
||||
notation.takes.should be_true
|
||||
notation.square.should eq("e5")
|
||||
end
|
||||
|
||||
it "parses Bxe5 as a bishop move" do
|
||||
notation = Notation.new("Bxe5")
|
||||
notation.piece_abbr.should eq('B')
|
||||
notation.takes.should be_true
|
||||
notation.square.should eq("e5")
|
||||
end
|
||||
|
||||
it "parses promotions" do
|
||||
notation = Notation.new("dxe8=Q")
|
||||
notation.takes.should be_true
|
||||
notation.square.should eq("e8")
|
||||
notation.promotion.should eq('Q')
|
||||
end
|
||||
end
|
||||
end
|
|
@ -10,18 +10,20 @@ module LxChess
|
|||
|
||||
class InvalidMove < Error; end
|
||||
|
||||
NOTATION_REGEX = %r{\A\s*
|
||||
(^[O0]-[O0])?\s* # 1. castles kingside
|
||||
(^[O0]-[O0]-[O0])?\s* # 2. castles queenside
|
||||
(^[RNBQKP](?!\d$))?\s* # 3. piece abbreviation
|
||||
((?:[a-z]|\d|[a-z]\d)(?=.*?[a-z]\d))?\s* # 4. origin square
|
||||
(x)?\s* # 5. takes
|
||||
([a-z]\d)?\s* # 6. destination square
|
||||
(\=\s*[RNBQ])?\s* # 7. promotion
|
||||
(\+)?\s* # 8. check
|
||||
(\#)?\s* # 9. checkmate
|
||||
(e\.?p\.?)?\s* # 10. en passant
|
||||
\z}x
|
||||
NOTATION_REGEX = %r{
|
||||
\A\s*
|
||||
(?<castle_k> ^[Oo0]-[Oo0] )?\s*
|
||||
(?<castle_q> ^[Oo0]-[Oo0]-[Oo0] )?\s*
|
||||
(?<piece_abbr> ^[RNBQKP](?!\d$) )?\s*
|
||||
(?<origin> (?:[a-wyz]|\d+|[a-z]\d+)(?=\s*x?\s*[a-z]\d+) )?\s*
|
||||
(?<takes> x )?\s*
|
||||
(?<dest> [a-z]\d+ )?\s*
|
||||
(?<promo> \=\s*[RNBQrnbq] )?\s*
|
||||
(?<check> \+ )?\s*
|
||||
(?<checkmate> \# )?\s*
|
||||
(?<en_passent> e\.?p\.? )?\s*
|
||||
\z
|
||||
}x
|
||||
|
||||
@match : Regex::MatchData?
|
||||
|
||||
|
@ -47,23 +49,23 @@ module LxChess
|
|||
@square = _square.downcase
|
||||
end
|
||||
|
||||
@castles_k = match[1]? ? true : false
|
||||
@castles_q = match[2]? ? true : false
|
||||
@en_passant = match[10]? ? true : false
|
||||
@check = match[8]? ? true : false
|
||||
@checkmate = match[9]? ? true : false
|
||||
@takes = match[5]? ? true : false
|
||||
@castles_k = match["castle_k"]? ? true : false
|
||||
@castles_q = match["castle_q"]? ? true : false
|
||||
@en_passant = match["en_passant"]? ? true : false
|
||||
@check = match["check"]? ? true : false
|
||||
@checkmate = match["checkmate"]? ? true : false
|
||||
@takes = match["takes"]? ? true : false
|
||||
|
||||
if _piece_abbr = match[3]?
|
||||
@piece_abbr = _piece_abbr[0].upcase
|
||||
match["piece_abbr"]?.try do |abbr|
|
||||
@piece_abbr = abbr[0].upcase
|
||||
end
|
||||
|
||||
if _origin = match[4]?
|
||||
@origin = _origin.downcase
|
||||
match["origin"]?.try do |origin|
|
||||
@origin = origin.downcase
|
||||
end
|
||||
|
||||
if _promo = match[7]?
|
||||
@promotion = _promo[-1].upcase
|
||||
match["promo"]?.try do |promo|
|
||||
@promotion = promo[-1].upcase
|
||||
end
|
||||
|
||||
@from = nil
|
||||
|
|
Loading…
Reference in a new issue