Always disambiguate moves, update method docs

a move like bc4 previously would have moved P c2 = c4, it's most
likely that the user intended Bc4, thus disambiguation removes
the c4 square possibility, because the b file is specified
This commit is contained in:
Alex Clink 2021-09-12 23:55:15 -04:00
parent d7623482fd
commit b056d2d445
2 changed files with 20 additions and 14 deletions

View file

@ -34,7 +34,7 @@ module LxChess
nil nil
end end
# Retrieve a piece at a human cord ex: `A1` # Retrieve a piece at a human cord ex: `a1`
def [](cord : String) def [](cord : String)
self[index(cord)] self[index(cord)]
end end
@ -48,13 +48,13 @@ module LxChess
(index + (y * @width) + x).to_i16 (index + (y * @width) + x).to_i16
end end
# Set a piece an the board at a certain *index* # Set a piece on the board at a certain *index*
def []=(index : Int, piece : Piece | Nil) def []=(index : Int, piece : Piece | Nil)
piece.index = index.to_i16 if piece piece.index = index.to_i16 if piece
@squares[index] = piece @squares[index] = piece
end end
# Set a piece an the board at a certain human readable *cord* # Set a piece on the board at a certain human readable *cord*
def []=(cord : String, piece : Piece | Nil) def []=(cord : String, piece : Piece | Nil)
self[index(cord)] = piece self[index(cord)] = piece
end end
@ -66,13 +66,14 @@ module LxChess
end end
# Convert human *cord* into an index on the board. # Convert human *cord* into an index on the board.
# Ex: `A1` => `0` # Ex: `a1` => `0`
def index(cord : String) def index(cord : String)
x = LETTERS.index(cord[0].downcase) || 0 x = LETTERS.index(cord[0].downcase) || 0
y = cord[1].to_i - 1 y = cord[1].to_i - 1
index(x, y) index(x, y)
end end
# Convert an *index* into a human coordinate (ex: `a1`)
def cord(index : Int) def cord(index : Int)
y, x = index.divmod(@width) y, x = index.divmod(@width)
"#{LETTERS[x]}#{y + 1}" "#{LETTERS[x]}#{y + 1}"
@ -102,20 +103,27 @@ module LxChess
index + (@width - dist_left) - 1 index + (@width - dist_left) - 1
end end
# The rank of a given index
# `rank(4) # => 0`
# `rank(8) # => 1`
def rank(index : Int16) def rank(index : Int16)
rank, _ = index.divmod(@width) rank, _ = index.divmod(@width)
rank rank
end end
# The file of a given index
# `file(4) # => 4`
# `file(8) # => 0`
def file(index : Int16) def file(index : Int16)
_, file = index.divmod(@width) _, file = index.divmod(@width)
file file
end end
def move(from : (String | Int), to : (String | Int)) # Move a piece *from* a position *to* a new position
piece = self[from.to_i16] def move(from : (String | Int16), to : (String | Int16))
self[from.to_i16] = nil piece = self[from]
self[to.to_i16] = piece self[from] = nil
self[to] = piece
end end
end end
end end

View file

@ -36,15 +36,13 @@ module LxChess
end end
end end
if pieces.size > 1
pieces = disambiguate_candidates(notation, pieces) pieces = disambiguate_candidates(notation, pieces)
end
raise SanError.new("#{notation.to_s} is ambiguous") if pieces.size > 1 raise SanError.new("#{notation.to_s} is ambiguous") if pieces.size > 1
if piece = pieces.first? if piece = pieces.first?
# from, to # from, to
[piece.index, index] [piece.index.as(Int16), index.as(Int16)]
else else
raise SanError.new("#{notation.to_s} is an illegal move") raise SanError.new("no moves for #{notation.to_s}")
end end
end end
@ -156,7 +154,7 @@ module LxChess
make_move(from: @board.index(from), to: @board.index(to), promotion: promotion) make_move(from: @board.index(from), to: @board.index(to), promotion: promotion)
end end
def make_move(from : Int, to : Int, promotion : Char? = nil) def make_move(from : Int16, to : Int16, promotion : Char? = nil)
san = move_to_san(from, to, promotion) san = move_to_san(from, to, promotion)
piece = @board.move(from, to) piece = @board.move(from, to)
next_turn next_turn