Fixes to how moves are counted and minor style improvements
This commit is contained in:
parent
a52783fa15
commit
36e9b7d620
|
@ -212,6 +212,18 @@ proc getEnPassantTarget*(self: ChessBoard): Location =
|
||||||
return self.position.enPassantSquare.targetSquare
|
return self.position.enPassantSquare.targetSquare
|
||||||
|
|
||||||
|
|
||||||
|
proc getMoveCount*(self: ChessBoard): int =
|
||||||
|
## Returns the number of full moves that
|
||||||
|
## have been played
|
||||||
|
return self.position.fullMoveCount
|
||||||
|
|
||||||
|
|
||||||
|
proc getHalfMoveCount*(self: ChessBoard): int =
|
||||||
|
## Returns the current number of half-moves
|
||||||
|
## since the last irreversible move
|
||||||
|
return self.position.halfMoveClock
|
||||||
|
|
||||||
|
|
||||||
func getStartRow(piece: Piece): int {.inline.} =
|
func getStartRow(piece: Piece): int {.inline.} =
|
||||||
## Retrieves the starting row of
|
## Retrieves the starting row of
|
||||||
## the given piece inside our 8x8
|
## the given piece inside our 8x8
|
||||||
|
@ -467,6 +479,11 @@ func rankToColumn(rank: int): int =
|
||||||
return indeces[rank - 1]
|
return indeces[rank - 1]
|
||||||
|
|
||||||
|
|
||||||
|
func rowToRank(row: int): int =
|
||||||
|
const indeces = [8, 7, 6, 5, 4, 3, 2, 1]
|
||||||
|
return indeces[row]
|
||||||
|
|
||||||
|
|
||||||
proc algebraicToLocation*(s: string): Location =
|
proc algebraicToLocation*(s: string): Location =
|
||||||
## Converts a square location from algebraic
|
## Converts a square location from algebraic
|
||||||
## notation to its corresponding row and column
|
## notation to its corresponding row and column
|
||||||
|
@ -480,16 +497,16 @@ proc algebraicToLocation*(s: string): Location =
|
||||||
if s[1] notin '1'..'8':
|
if s[1] notin '1'..'8':
|
||||||
raise newException(ValueError, &"algebraic position has invalid second character ('{s[1]}')")
|
raise newException(ValueError, &"algebraic position has invalid second character ('{s[1]}')")
|
||||||
|
|
||||||
let file = int(uint8(s[0]) - uint8('a'))
|
let rank = int(uint8(s[0]) - uint8('a'))
|
||||||
# Convert the rank character to a number
|
# Convert the file character to a number
|
||||||
let rank = rankToColumn(int(uint8(s[1]) - uint8('0')))
|
let file = rankToColumn(int(uint8(s[1]) - uint8('0')))
|
||||||
return (rank, file)
|
return (file, rank)
|
||||||
|
|
||||||
|
|
||||||
proc locationToAlgebraic*(loc: Location): string =
|
proc locationToAlgebraic*(loc: Location): string =
|
||||||
## Converts a location from our internal row, column
|
## Converts a location from our internal row, column
|
||||||
## notation to a square in algebraic notation
|
## notation to a square in algebraic notation
|
||||||
return &"{char(uint8(loc.col) + uint8('a'))}{char(uint8(loc.row) + uint8('0'))}"
|
return &"{char(uint8(loc.col) + uint8('a'))}{rowToRank(loc.row)}"
|
||||||
|
|
||||||
|
|
||||||
proc getPiece*(self: ChessBoard, square: string): Piece =
|
proc getPiece*(self: ChessBoard, square: string): Piece =
|
||||||
|
@ -961,14 +978,18 @@ proc doMove(self: ChessBoard, move: Move) =
|
||||||
# Final checks
|
# Final checks
|
||||||
|
|
||||||
# Needed to detect draw by the 50 move rule
|
# Needed to detect draw by the 50 move rule
|
||||||
if move.piece.kind != Pawn and not self.isCapture(move):
|
var
|
||||||
inc(self.position.halfMoveClock)
|
halfMoveClock = self.position.halfMoveClock
|
||||||
|
fullMoveCount = self.position.fullMoveCount
|
||||||
|
if move.piece.kind == Pawn or self.isCapture(move):
|
||||||
|
halfMoveClock = 0
|
||||||
else:
|
else:
|
||||||
self.position.halfMoveClock = 0
|
inc(halfMoveClock)
|
||||||
if (self.position.halfMoveClock and 1) == 0: # Equivalent to (x mod 2) == 0, just much faster
|
if move.piece.color == Black:
|
||||||
inc(self.position.fullMoveCount)
|
inc(fullMoveCount)
|
||||||
# TODO: Castling
|
# TODO: Castling
|
||||||
|
|
||||||
|
# Record the move in the position
|
||||||
self.position.move = move
|
self.position.move = move
|
||||||
|
|
||||||
# Update position and attack metadata
|
# Update position and attack metadata
|
||||||
|
@ -979,6 +1000,8 @@ proc doMove(self: ChessBoard, move: Move) =
|
||||||
self.positions.add(self.position)
|
self.positions.add(self.position)
|
||||||
# Create new position with
|
# Create new position with
|
||||||
var newPos = Position(plyFromRoot: self.position.plyFromRoot + 1,
|
var newPos = Position(plyFromRoot: self.position.plyFromRoot + 1,
|
||||||
|
halfMoveClock: halfMoveClock,
|
||||||
|
fullMoveCount: fullMoveCount,
|
||||||
captured: emptyPiece(),
|
captured: emptyPiece(),
|
||||||
turn: self.getActiveColor().opposite,
|
turn: self.getActiveColor().opposite,
|
||||||
# Inherit values from current position
|
# Inherit values from current position
|
||||||
|
|
|
@ -13,13 +13,14 @@ when isMainModule:
|
||||||
data: string
|
data: string
|
||||||
move: Move
|
move: Move
|
||||||
|
|
||||||
|
echo "\x1Bc"
|
||||||
while true:
|
while true:
|
||||||
echo &"{board.pretty()}"
|
echo &"{board.pretty()}"
|
||||||
echo &"Turn: {board.getActiveColor()}"
|
echo &"Turn: {board.getActiveColor()}"
|
||||||
|
echo &"Moves: {board.getMoveCount()} full, {board.getHalfMoveCount()} half"
|
||||||
stdout.write(&"En passant target: ")
|
stdout.write(&"En passant target: ")
|
||||||
if board.getEnPassantTarget() != emptyLocation():
|
if board.getEnPassantTarget() != emptyLocation():
|
||||||
echo board.getEnPassantTarget()
|
echo board.getEnPassantTarget().locationToAlgebraic()
|
||||||
else:
|
else:
|
||||||
echo "None"
|
echo "None"
|
||||||
stdout.write(&"Check: ")
|
stdout.write(&"Check: ")
|
||||||
|
@ -34,13 +35,16 @@ when isMainModule:
|
||||||
echo ""
|
echo ""
|
||||||
break
|
break
|
||||||
if data == "undo":
|
if data == "undo":
|
||||||
echo &"Undo: {board.undoLastMove()}"
|
echo &"\x1BcUndo: {board.undoLastMove()}"
|
||||||
continue
|
continue
|
||||||
if len(data) != 4:
|
if len(data) != 4:
|
||||||
|
echo "\x1BcError: invalid move"
|
||||||
continue
|
continue
|
||||||
try:
|
try:
|
||||||
move = board.makeMove(data[0..1], data[2..3])
|
move = board.makeMove(data[0..1], data[2..3])
|
||||||
except ValueError:
|
except ValueError:
|
||||||
echo &"Error: {getCurrentExceptionMsg()}"
|
echo &"\x1BcError: {getCurrentExceptionMsg()}"
|
||||||
if move == emptyMove():
|
if move == emptyMove():
|
||||||
echo &"Error: move is illegal"
|
echo &"\x1BcError: move is illegal"
|
||||||
|
else:
|
||||||
|
echo "\x1Bc"
|
||||||
|
|
Loading…
Reference in New Issue