Add moving pieces based on input SAN

This commit is contained in:
Alex Clink 2021-09-11 21:14:05 -04:00
parent e496f6c51a
commit 466075bee9
4 changed files with 31 additions and 15 deletions

View file

@ -35,25 +35,23 @@ fen = LxChess::Fen.parse(options["fen_string"])
game = LxChess::Game.new(board: fen.board)
gb = LxChess::TermBoard.new(game.board)
gb.draw
puts
loop do
gb.draw
puts
print " > "
input = gets
if input
notation = LxChess::Notation.new(input)
input = input.to_i16 if input =~ /^\d+$/
if move_set = game.moves(input)
puts move_set.moves.map { |m| game.board.cord(m) }
from, to = game.parse_san(notation)
if from && to
piece = game.board.move(from, to)
puts "#{notation.to_s}: #{game.board.cord(from)} => #{game.board.cord(to)}"
end
# from, to = game.parse_san(notation)
# if from && to
# puts "#{notation.to_s}: #{game.board.cord(from)} => #{game.board.cord(to)}"
# end
end
rescue e : LxChess::Notation::InvalidNotation
puts e.message
rescue e : LxChess::Game::SanError
puts e.message
end
# gb.flip!

View file

@ -44,7 +44,7 @@ module LxChess
# Set a piece an the board at a certain *index*
def []=(index : Int, piece : Piece | Nil)
piece.index = index.to_i16
piece.index = index.to_i16 if piece
@squares[index] = piece
end
@ -100,5 +100,11 @@ module LxChess
rank, _ = index.divmod(@width)
rank
end
def move(from : (String | Int), to : (String | Int))
piece = self[from.to_i16]
self[from.to_i16] = nil
self[to.to_i16] = piece
end
end
end

View file

@ -2,9 +2,12 @@ require "./player"
require "./board"
require "./notation"
require "./move_set"
require "./error"
module LxChess
class Game
class SanError < Error; end
property turn : Int8, board : Board
def initialize(@board : Board = Board.new, @players = [] of Player)
@ -15,11 +18,16 @@ module LxChess
def parse_san(notation : Notation)
index = @board.index(notation.square)
fen_symbol = notation.fen_symbol(@turn == 0 ? "w" : "b")
pieces = @board.select { |piece| piece && piece.fen_symbol == fen_symbol }
pieces = pieces.select { |piece| piece && moves(piece.index.as(Int16)).includes?(index) }
pieces = @board.select do |piece|
next if piece.nil?
next unless piece.fen_symbol == fen_symbol
if move_set = moves(piece.index.as(Int16))
move_set.moves.includes?(index)
end
end
raise "Ambiguous SAN" if pieces.size > 1
raise "Illegal move" if pieces.size == 0
raise SanError.new("Ambiguous SAN") if pieces.size > 1
raise SanError.new("Illegal move") if pieces.size == 0
piece = pieces.first
# from, to

View file

@ -65,6 +65,7 @@ module LxChess
@from = nil
@to = nil
validate
end
def initialize(
@ -82,7 +83,10 @@ module LxChess
@to = nil
)
@piece_abbr = "K" if @castles_q || @castles_k
validate
end
def validate
raise InvalidMove.new("Cannot castle and promote") if castles? && promotion
raise InvalidMove.new("Cannot capture while castling") if castles? && takes?
end