Minor improvements to board module

This commit is contained in:
Mattia Giambirtone 2023-10-12 10:14:37 +02:00
parent 24d1cd0c82
commit 85648d883c
Signed by: nocturn9x
GPG Key ID: 8270F9F467971E59
1 changed files with 31 additions and 10 deletions

View File

@ -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)
proc newDefaultChessboard*: ChessBoard =
## Initializes a chessboard with the
## starting position
return newChessboardFromFEN("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1")