From b056d2d4459729b927cc163394774217fa32afac Mon Sep 17 00:00:00 2001 From: Alex Clink Date: Sun, 12 Sep 2021 23:55:15 -0400 Subject: [PATCH] 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 --- src/lx_chess/board.cr | 24 ++++++++++++++++-------- src/lx_chess/game.cr | 10 ++++------ 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/lx_chess/board.cr b/src/lx_chess/board.cr index c89429f..86a9bc1 100644 --- a/src/lx_chess/board.cr +++ b/src/lx_chess/board.cr @@ -34,7 +34,7 @@ module LxChess nil end - # Retrieve a piece at a human cord ex: `A1` + # Retrieve a piece at a human cord ex: `a1` def [](cord : String) self[index(cord)] end @@ -48,13 +48,13 @@ module LxChess (index + (y * @width) + x).to_i16 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) piece.index = index.to_i16 if piece @squares[index] = piece 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) self[index(cord)] = piece end @@ -66,13 +66,14 @@ module LxChess end # Convert human *cord* into an index on the board. - # Ex: `A1` => `0` + # Ex: `a1` => `0` def index(cord : String) x = LETTERS.index(cord[0].downcase) || 0 y = cord[1].to_i - 1 index(x, y) end + # Convert an *index* into a human coordinate (ex: `a1`) def cord(index : Int) y, x = index.divmod(@width) "#{LETTERS[x]}#{y + 1}" @@ -102,20 +103,27 @@ module LxChess index + (@width - dist_left) - 1 end + # The rank of a given index + # `rank(4) # => 0` + # `rank(8) # => 1` def rank(index : Int16) rank, _ = index.divmod(@width) rank end + # The file of a given index + # `file(4) # => 4` + # `file(8) # => 0` def file(index : Int16) _, file = index.divmod(@width) file end - def move(from : (String | Int), to : (String | Int)) - piece = self[from.to_i16] - self[from.to_i16] = nil - self[to.to_i16] = piece + # Move a piece *from* a position *to* a new position + def move(from : (String | Int16), to : (String | Int16)) + piece = self[from] + self[from] = nil + self[to] = piece end end end diff --git a/src/lx_chess/game.cr b/src/lx_chess/game.cr index aefd050..64649a1 100644 --- a/src/lx_chess/game.cr +++ b/src/lx_chess/game.cr @@ -36,15 +36,13 @@ module LxChess end end - if pieces.size > 1 - pieces = disambiguate_candidates(notation, pieces) - end + pieces = disambiguate_candidates(notation, pieces) raise SanError.new("#{notation.to_s} is ambiguous") if pieces.size > 1 if piece = pieces.first? # from, to - [piece.index, index] + [piece.index.as(Int16), index.as(Int16)] else - raise SanError.new("#{notation.to_s} is an illegal move") + raise SanError.new("no moves for #{notation.to_s}") end end @@ -156,7 +154,7 @@ module LxChess make_move(from: @board.index(from), to: @board.index(to), promotion: promotion) 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) piece = @board.move(from, to) next_turn