From 4410adb40bfed8c56135880c2048c8a3b46c0acf Mon Sep 17 00:00:00 2001 From: Mattia Giambirtone Date: Thu, 12 Oct 2023 10:14:37 +0200 Subject: [PATCH] Minor improvements to board module --- src/Chess/board.nim | 41 +++++++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 10 deletions(-) diff --git a/src/Chess/board.nim b/src/Chess/board.nim index e7a658f..809b1df 100644 --- a/src/Chess/board.nim +++ b/src/Chess/board.nim @@ -15,6 +15,7 @@ import ../util/matrix import std/strutils +import std/strformat type @@ -36,12 +37,14 @@ type Position* = object piece*: Piece location*: tuple[row, col: int] - Board* = ref object + ChessBoard* = ref object + ## A chess board object grid: Matrix[Piece] - ply: PieceColor + # Currently active color + turn: PieceColor # Number of half moves since - # last piece capture. Used - # for the 50-move rule + # last piece capture or pawn movement. + # Used for the 50-move rule halfMoveClock: int # Full move counter. Increments # every 2 ply @@ -67,7 +70,21 @@ proc algebraicToPosition(s: string): tuple[row, col: int] {.inline.} = result = (int(uint8(s[0]) - (uint8('a') - 1)), int(uint8(s[1]) - uint8('0'))) -proc newChessboardFromFEN*(state: string): Board = +proc `$`*(self: ChessBoard): string = + result &= "- - - - - - - -" + for row in self.grid: + result &= "\n" + for piece in row: + if piece.kind == Empty: + result &= " " + if piece.color == White: + result &= &"{char(piece.kind).toUpperAscii()} " + else: + result &= &"{char(piece.kind)} " + result &= "\n- - - - - - - -" + + +proc newChessboardFromFEN*(state: string): ChessBoard = ## Initializes a chessboard with the ## state encoded by the given FEN string new(result) @@ -110,11 +127,11 @@ proc newChessboardFromFEN*(state: string): Board = # Active color case c: of 'w': - result.ply = White + result.turn = White of 'b': - result.ply = Black + result.turn = Black else: - raise newException(ValueError, "invalid next move identifier in FEN string") + raise newException(ValueError, "invalid active color identifier in FEN string") of 2: # Castling availability case c: @@ -142,7 +159,7 @@ proc newChessboardFromFEN*(state: string): Board = result.enPassantSquare.location = state[index..index+1].algebraicToPosition() # Just for cleanliness purposes, we fill in the other positional metadata as # well - result.enPassantSquare.piece.color = if result.ply == Black: White else: Black + result.enPassantSquare.piece.color = if result.turn == Black: White else: Black result.enPassantSquare.piece.kind = Pawn # Square metadata is 2 bytes long inc(index) @@ -167,4 +184,8 @@ proc newChessboardFromFEN*(state: string): Board = raise newException(ValueError, "too many fields in FEN string") inc(index) - \ No newline at end of file + +proc newDefaultChessboard*: ChessBoard = + ## Initializes a chessboard with the + ## starting position + return newChessboardFromFEN("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1") \ No newline at end of file