diff --git a/src/lx_chess.cr b/src/lx_chess.cr index e7c2b4e..4747fb8 100644 --- a/src/lx_chess.cr +++ b/src/lx_chess.cr @@ -33,7 +33,9 @@ end log = [] of String fen = LxChess::Fen.parse(options["fen_string"]) -game = LxChess::Game.new(board: fen.board) +player_white = LxChess::Player.new +player_black = LxChess::Player.new +game = LxChess::Game.new(board: fen.board, players: [player_white, player_black]) gb = LxChess::TermBoard.new(game.board) term = LxChess::Terminal.new @@ -74,6 +76,22 @@ loop do from + to end.compact.join(" | ") log.unshift move_string + when /\s*([a-z]\d)\s*([a-z]\d)\s*(?:=\s*)?([RNBQ])?/i + if input + if matches = input.downcase.match(/\s*([a-z]\d)\s*([a-z]\d)\s*(?:=\s*)?([RNBQ])?/i) + from = matches[1] + to = matches[2] + promo = if matches[3]? + matches[3][0] + end + if from && to + gb.clear + san = game.make_move(from, to) + gb.highlight([game.board.index(from), game.board.index(to)]) + log.unshift "#{san.to_s}: #{from} => #{to}" + end + end + end when nil else if input @@ -81,10 +99,9 @@ loop do from, to = game.parse_san(notation) if from && to gb.clear - piece = game.board.move(from, to) - game.next_turn + san = game.make_move(from, to) gb.highlight([from.to_i16, to.to_i16]) - log.unshift "#{notation.to_s}: #{game.board.cord(from)} => #{game.board.cord(to)}" + log.unshift "#{san.to_s}: #{game.board.cord(from)} => #{game.board.cord(to)}" end end end diff --git a/src/lx_chess/game.cr b/src/lx_chess/game.cr index 996ada2..aefd050 100644 --- a/src/lx_chess/game.cr +++ b/src/lx_chess/game.cr @@ -20,11 +20,6 @@ module LxChess @en_passant_target = @board.index(cord) end - def next_turn - @turn = (@turn == 0 ? 1 : 0).to_i8 - @move_clock += 1 - end - def full_moves (@move_clock / 2).to_i16 end @@ -53,7 +48,8 @@ module LxChess end end - def move_to_san(from : Int16, to : Int16, promotion : String? = nil) + # TODO: add check, checkmate, etc. + def move_to_san(from : Int, to : Int, promotion : String? = nil) raise "No piece at #{@board.cord(from)}" unless piece = @board[from] en_passant = piece.pawn? && to == @en_passant_target @@ -155,5 +151,22 @@ module LxChess set end end + + def make_move(from : String, to : String, promotion : Char? = nil) + make_move(from: @board.index(from), to: @board.index(to), promotion: promotion) + end + + def make_move(from : Int, to : Int, promotion : Char? = nil) + san = move_to_san(from, to, promotion) + piece = @board.move(from, to) + next_turn + san + end + + def next_turn + @turn += 1 + @turn = @turn % @players.size + @move_clock += 1 + end end end diff --git a/src/lx_chess/notation.cr b/src/lx_chess/notation.cr index ae6a355..c34462d 100644 --- a/src/lx_chess/notation.cr +++ b/src/lx_chess/notation.cr @@ -19,22 +19,22 @@ module LxChess (\+)?\s* # 8. check (\#)?\s* # 9. checkmate (e\.?p\.?)?\s* # 10. en passant - \z}ix + \z}x @match : Regex::MatchData? - property square : String?, - castles_k : Bool, - castles_q : Bool, - en_passant : Bool, - check : Bool, - checkmate : Bool, - takes : Bool, - piece_abbr : Char?, - origin : String?, - promotion : Char?, - from : String?, - to : String? + property square : String? + property castles_k : Bool + property castles_q : Bool + property en_passant : Bool + property check : Bool + property checkmate : Bool + property takes : Bool + getter piece_abbr : Char? + property origin : String? + property promotion : Char? + property from : String? + property to : String? def initialize(notation : String) unless match = notation.match(NOTATION_REGEX) @@ -83,7 +83,7 @@ module LxChess @from = nil, @to = nil ) - @piece_abbr = "K" if @castles_q || @castles_k + @piece_abbr = 'K' if @castles_q || @castles_k validate end @@ -92,6 +92,12 @@ module LxChess raise InvalidMove.new("Cannot capture while castling") if castles? && takes? end + def piece_abbr + if abbr = @piece_abbr + abbr.upcase + end + end + def en_passant? @en_passant end @@ -146,7 +152,7 @@ module LxChess when castles_q? "O-O-O" else - @piece_abbr + piece_abbr != 'P' || @takes ? piece_abbr : nil end if @en_passant diff --git a/src/lx_chess/piece.cr b/src/lx_chess/piece.cr index 7c55f46..580b461 100644 --- a/src/lx_chess/piece.cr +++ b/src/lx_chess/piece.cr @@ -48,5 +48,9 @@ module LxChess def fen_symbol FEN_SYMBOLS[@id] end + + def pawn? + @id & 0b0111 == PAWN + end end end diff --git a/src/lx_chess/player.cr b/src/lx_chess/player.cr index b1a0feb..84f5184 100644 --- a/src/lx_chess/player.cr +++ b/src/lx_chess/player.cr @@ -1,4 +1,7 @@ module LxChess + property castle_left = true + property castle_right = true + class Player end end