@ -22,7 +22,6 @@ type
board * : Board
board * : Board
toMove * : Color
toMove * : Color
previousBoard : seq [ Board ]
previousBoard : seq [ Board ]
previousCastleRights : seq [ CastleRights ]
halfMoveClock : int
halfMoveClock : int
fullMoveCounter * : int
fullMoveCounter * : int
castleRights : CastleRights
castleRights : CastleRights
@ -578,18 +577,30 @@ proc uncheckedMove(chess: var Chess, start: int, dest: int): bool {.discardable.
chess . board [ start ] = 0
chess . board [ start ] = 0
chess . board [ dest ] = piece
chess . board [ dest ] = piece
if start = = fieldToInd ( " e1 " ) :
if start = = fieldToInd ( " e1 " ) :
if chess . castleRights . wk or chess . castleRights . wq :
chess . previousBoard = @ [ ]
chess . castleRights . wk = false
chess . castleRights . wk = false
chess . castleRights . wq = false
chess . castleRights . wq = false
elif start = = fieldToInd ( " h1 " ) :
elif start = = fieldToInd ( " h1 " ) :
if chess . castleRights . wk :
chess . previousBoard = @ [ ]
chess . castleRights . wk = false
chess . castleRights . wk = false
elif start = = fieldToInd ( " a1 " ) :
elif start = = fieldToInd ( " a1 " ) :
if chess . castleRights . wq :
chess . previousBoard = @ [ ]
chess . castleRights . wq = false
chess . castleRights . wq = false
elif start = = fieldToInd ( " e8 " ) :
elif start = = fieldToInd ( " e8 " ) :
if chess . castleRights . bk or chess . castleRights . bq :
chess . previousBoard = @ [ ]
chess . castleRights . bk = false
chess . castleRights . bk = false
chess . castleRights . bq = false
chess . castleRights . bq = false
elif start = = fieldToInd ( " h8 " ) :
elif start = = fieldToInd ( " h8 " ) :
if chess . castleRights . bk :
chess . previousBoard = @ [ ]
chess . castleRights . bk = false
chess . castleRights . bk = false
elif start = = fieldToInd ( " a8 " ) :
elif start = = fieldToInd ( " a8 " ) :
if chess . castleRights . bq :
chess . previousBoard = @ [ ]
chess . castleRights . bq = false
chess . castleRights . bq = false
return true
return true
@ -744,6 +755,7 @@ proc castling(chess: var Chess, kstart: int, dest_kingside: bool,
return false
return false
chess . uncheckedMove ( kstart , kdest )
chess . uncheckedMove ( kstart , kdest )
chess . uncheckedMove ( rstart , rdest )
chess . uncheckedMove ( rstart , rdest )
chess . previousBoard = @ [ ]
chess . toMove = Color ( ord ( chess . toMove ) * ( - 1 ) )
chess . toMove = Color ( ord ( chess . toMove ) * ( - 1 ) )
return true
return true
return false
return false
@ -758,7 +770,6 @@ proc checkedMove*(chess: var Chess, move: Move): bool {.discardable.} =
let prom = move . prom
let prom = move . prom
if ( chess . toMove ! = color or start = = - 1 or dest = = - 1 ) :
if ( chess . toMove ! = color or start = = - 1 or dest = = - 1 ) :
return false
return false
var sequence = newSeq [ Move ] ( )
let piece = chess . board [ start ]
let piece = chess . board [ start ]
var createEnPassant : bool
var createEnPassant : bool
var capturedEnPassant : bool
var capturedEnPassant : bool
@ -771,8 +782,7 @@ proc checkedMove*(chess: var Chess, move: Move): bool {.discardable.} =
fiftyMoveRuleReset = true
fiftyMoveRuleReset = true
if ( chess . board [ move . dest ] ! = 0 ) :
if ( chess . board [ move . dest ] ! = 0 ) :
fiftyMoveRuleReset = true
fiftyMoveRuleReset = true
sequence . add ( chess . genLegalMoves ( start , color ) )
if ( move in chess . genLegalMoves ( start , color ) ) :
if ( move in sequence ) :
chess . enPassantSquare = - 1
chess . enPassantSquare = - 1
if ( piece = = WKing * ord ( color ) and ( start - dest = = ( W + W ) ) ) :
if ( piece = = WKing * ord ( color ) and ( start - dest = = ( W + W ) ) ) :
return chess . castling ( start , true , color )
return chess . castling ( start , true , color )
@ -788,15 +798,13 @@ proc checkedMove*(chess: var Chess, move: Move): bool {.discardable.} =
if ( ( fieldToInd ( " h8 " ) < dest and dest < fieldToInd ( " a8 " ) ) or ( fieldToInd ( " h1 " ) < dest and dest < fieldToInd ( " a1 " ) ) ) and
if ( ( fieldToInd ( " h8 " ) < dest and dest < fieldToInd ( " a8 " ) ) or ( fieldToInd ( " h1 " ) < dest and dest < fieldToInd ( " a1 " ) ) ) and
chess . board [ dest ] = = WPawn * ord ( color ) :
chess . board [ dest ] = = WPawn * ord ( color ) :
chess . board [ dest ] = prom
chess . board [ dest ] = prom
var prevBoard = chess . previousBoard
var prevCastle = chess . previousCastleRights
chess . previousBoard . add ( chess . board )
chess . previousBoard . add ( chess . board )
chess . previousCastleRights . add ( chess . castleRights )
chess . halfMoveClock = chess . halfMoveClock + 1
chess . halfMoveClock = chess . halfMoveClock + 1
if color = = Color . Black :
if color = = Color . Black :
chess . fullMoveCounter + = 1
chess . fullMoveCounter + = 1
if fiftyMoveRuleReset :
if fiftyMoveRuleReset :
chess . halfMoveClock = 0
chess . halfMoveClock = 0
chess . previousBoard = @ [ ]
return true
return true
proc isCheckmate * ( chess : Chess , color : Color ) : bool =
proc isCheckmate * ( chess : Chess , color : Color ) : bool =
@ -806,19 +814,17 @@ proc isCheckmate*(chess: Chess, color: Color): bool =
proc threeMoveRep ( chess : Chess ) : bool =
proc threeMoveRep ( chess : Chess ) : bool =
## Returns true if a 3-fold repitition happened on the last move of the
## Returns true if a 3-fold repitition happened on the last move of the
## `chess`.
## `chess`.
if chess . previousBoard = = [] :
if chess . previousBoard = = @ [] :
return false
return false
var lastState = chess . previousBoard [ chess . previousBoard . high ]
var lastState = chess . previousBoard [ chess . previousBoard . high ]
var lastCastleRights = chess . previousCastleRights [ chess . previousBoard . high ]
var reps : int
var reps : int
for stateInd in ( chess . previousBoard . low ) .. ( chess . previousBoard . high ) :
for stateInd in ( chess . previousBoard . low ) .. ( chess . previousBoard . high ) :
if ( chess . previousBoard [ stateInd ] = = lastState and
if ( chess . previousBoard [ stateInd ] = = lastState ) :
chess . previousCastleRights [ stateInd ] = = lastCastleRights ) :
reps = reps + 1
reps = reps + 1
return reps > = 3
return reps > = 3
proc isDrawClaimable * ( chess : Chess ) : bool =
proc isDrawClaimable * ( chess : Chess ) : bool =
## Returns true if a draw is claimable by ei ther player.
## Returns true if a draw is claimable by the cu rrent player.
return chess . threeMoveRep ( ) or chess . halfMoveClock > = 100
return chess . threeMoveRep ( ) or chess . halfMoveClock > = 100
proc checkInsufficientMaterial ( board : Board ) : bool =
proc checkInsufficientMaterial ( board : Board ) : bool =