public Engine() { // create all classes bitboard = new BitBoard(); magicMoves = new MagicMoves(); transpositionTable = new TranspositionTable(); pawnEvalTT = new PawnsTT(); evalTT = new EvalTT(); board = new Board(true); evaluator = new My_Evaluator(); moveGenerator = new MoveGenerator(); searchMove = new SearchMove(); attack = new Attack(); // Setup dependency : assign pointers to classes SetupClassDependency(); searchMove.SearchMoveHasNewResults = StoreCurrentEngineResults; SetupInitialBoard(true); MoveHistory = new Move[100]; }
private void StoreCurrentThinking(int score) { // stores the best found mobes, so far and the score currentScore = score; int nrPVMoves = PrincipalVariation.Length; if (nrPVMoves > maxNrThinkMoves) nrPVMoves = maxNrThinkMoves; bool TTStillMatchesPV = true; // this signals if the PV matches the TT int nrThinkMoves = 0; Move[] thinkMoves = new Move[maxNrThinkMoves]; ulong[] thinkMoveHashValues = new ulong[maxNrThinkMoves]; // First store everything in a clone, since making captures reorders the indices of pieces in PiecePos. // This reorders future moves. Somehow, this gives problems Board clone = new Board(false); clone.LoadFrom(board); // for (int i = 0; i < nrPVMoves; i++) { if (TTStillMatchesPV) { int ttIndex = transpositionTable.GetIndex(board.HashValue, 0); if (ttIndex >= 0) { Move ttMove = new Move(transpositionTable.slots[ttIndex].compressedMove); if (ttMove != PrincipalVariation[i]) TTStillMatchesPV = false; } else TTStillMatchesPV = false; } thinkMoves[i] = PrincipalVariation[i]; thinkMoveHashValues[i] = board.HashValue; board.MakeMove(PrincipalVariation[i]); nrThinkMoves++; } // finished the PrincipalVariation. Now follow the TT nrCurrentMovesFromPV = nrThinkMoves; int ttIndex2; while ((ttIndex2 = transpositionTable.GetIndex(board.HashValue, 0)) != -1) { Move move = new Move(transpositionTable.slots[ttIndex2].compressedMove); if (move.moveType == Const.NoMoveID) break; if (nrThinkMoves >= maxNrThinkMoves - 1) break; thinkMoves[nrThinkMoves] = move; thinkMoveHashValues[nrThinkMoves] = board.HashValue; board.MakeMove(move); nrThinkMoves++; // Check if this move has occured before. Otherwise an endless loop would occurr. // Allow for 3 entries, since this is possible for the 3-move rule (?) int nrSameEntries = 0; for (int i = 0; i < nrThinkMoves; i++) if (thinkMoveHashValues[i] == board.HashValue) nrSameEntries++; if (nrSameEntries >= 3) break; } // now rewind the board by undoing the moves made for (int i = nrThinkMoves - 1; i >= 0; i--) board.UnMakeMove(thinkMoves[i]); // switch back to the original board board.LoadFrom(clone); // // So found the moves, now store them currentMoves = new Move[nrThinkMoves]; for (int i = 0; i < nrThinkMoves; i++) currentMoves[i] = thinkMoves[i]; }
private bool IsCheckOrStallMate(out bool isStallMate) { // Use this only in between moves, since it's quite 'slow' (20 microseconds); // slow, but exact way to see if the color to move is check-mate // Do this with a clone, since making captures reorders the indices of pieces in PiecePos. // This reorders future moves. Somehow, this gives problems Board clone = new Board(false); clone.LoadFrom(board); Move[] moves = moveGenerator.GenerateMoves(null); // try all moves. If no one is valid. It's checkmate. bool hasValidMove = false; for (int i = 0; i < moveGenerator.nrGeneratedMoves; i++) { if (board.MakeMove(moves[i])) { hasValidMove = true; } board.UnMakeMove(moves[i]); if (hasValidMove) break; } board.LoadFrom(clone); if (!hasValidMove) { // maybe it's a stall-mate : in this case, the king is not in check isStallMate = !board.IsInCheck(); } else isStallMate = false; return !hasValidMove; }
public bool UserMoveIsLegal(string moveString) { // slow : only use for validation of user move Move move = board.FindMoveOnBoard(moveString); if (move == Move.NoMove()) return false; // not found // check if this move leaves the king in check : // Do this with a clone, since making captures reorders the indices of pieces in PiecePos. // This reorders future moves. Somehow, this gives problems Board clone = new Board(false); clone.LoadFrom(board); board.MakeMove(move); board.ToggleMoveColor(); // this was toggled by MakeMove. Undo it. bool leavesKingInCheck = board.IsInCheck(); board.LoadFrom(clone); return !leavesKingInCheck; }
public void LoadFrom(Board clone) { // load the entire contents from a clone magicMoves = clone.magicMoves; transpositionTable = clone.transpositionTable; evaluator = clone.evaluator; ClearBoard(); moveGenerator = clone.moveGenerator; // pieces = new ulong[clone.pieces.Length]; for (int i = 0; i < clone.pieces.Length; i++) pieces[i] = clone.pieces[i]; allPiecesBB = clone.allPiecesBB; for (int i = 0; i < Const.NrColors; i++) for (int j = 0; j < Const.NrPieceTypes; j++) pieceBB[i, j] = clone.pieceBB[i, j]; // PiecePos for (int i = 0; i < Const.NrColors; i++) for (int j = 0; j < Const.NrPieceTypes; j++) for (int k = 0; k < Const.MaxNrPiecesPerType; k++) PiecePos[i, j, k] = clone.PiecePos[i, j, k]; //.. // nrPieces for (int i = 0; i < Const.NrColors; i++) { TotalNrPieces[i] = clone.TotalNrPieces[i]; for (int j = 0; j < Const.NrPieceTypes; j++) NrPieces[i, j] = clone.NrPieces[i, j]; } // SquareContents for (int i = 0; i < Const.NrSquares; i++) SquareContents[i] = clone.SquareContents[i]; // // state of the game info colorToMove = clone.colorToMove; enemyColor = clone.enemyColor; for (int i = 0; i < Const.NrColors; i++) { canCastleKingSide[i] = clone.canCastleKingSide[i]; canCastleQueenSide[i] = clone.canCastleQueenSide[i]; hasCastled[i] = clone.hasCastled[i]; } // .. enPassantPosition = clone.enPassantPosition; // halfMoveNr = clone.halfMoveNr; fiftyMoveNr = clone.fiftyMoveNr; capturedPiecePosition = clone.capturedPiecePosition; capturedPieceType = clone.capturedPieceType; repeatedPosition_SearchOffset = clone.repeatedPosition_SearchOffset; // maxNrStoredBoardStates = clone.maxNrStoredBoardStates; nrStoredBoardStates = clone.nrStoredBoardStates; storedBoardStates = new BoardState[clone.storedBoardStates.Length]; for (int i = 0; i < clone.storedBoardStates.Length; i++) storedBoardStates[i] = clone.storedBoardStates[i]; // HashValue = clone.HashValue; bwPawnsHashValue = clone.bwPawnsHashValue; for (int i = 0; i < Const.NrColors; i++) { StaticMaterialScore[i] = clone.StaticMaterialScore[i]; StaticPositionalScore[i] = clone.StaticPositionalScore[i]; } // nrHashValuesInHistory = clone.nrHashValuesInHistory; HashValueHistory = new ulong[clone.HashValueHistory.Length]; for (int i = 0; i < clone.HashValueHistory.Length; i++) HashValueHistory[i] = clone.HashValueHistory[i]; }
public bool Compare(Board clone) { for (int i = 0; i < pieces.Length; i++) if (clone.pieces[i] != pieces[i]) return false; if (clone.allPiecesBB != allPiecesBB) return false; for (int i = 0; i < Const.NrColors; i++) for (int j = 0; j < Const.NrPieceTypes; j++) if (clone.pieceBB[i, j] != pieceBB[i, j]) return false; // PiecePos int nrPiecePosErrors = 0; for (int i = 0; i < Const.NrColors; i++) for (int j = 0; j < Const.NrPieceTypes; j++) for (int k = 0; k < Const.MaxNrPiecesPerType; k++) if (clone.PiecePos[i, j, k] != PiecePos[i, j, k]) nrPiecePosErrors++; if (nrPiecePosErrors > 0) return false; // nrPieces for (int i = 0; i < Const.NrColors; i++) { if (clone.TotalNrPieces[i] != TotalNrPieces[i]) return false; for (int j = 0; j < Const.NrPieceTypes; j++) if (clone.NrPieces[i, j] != NrPieces[i, j]) return false; } // SquareContents for (int i = 0; i < Const.NrSquares; i++) { if (clone.SquareContents[i].pieceColor != SquareContents[i].pieceColor) return false; if (clone.SquareContents[i].pieceIndex != SquareContents[i].pieceIndex) return false; if (clone.SquareContents[i].pieceType != SquareContents[i].pieceType) return false; } // // state of the game info if (clone.colorToMove != colorToMove) return false; if (clone.enemyColor != enemyColor) return false; for (int i = 0; i < Const.NrColors; i++) { if (clone.canCastleKingSide[i] != canCastleKingSide[i]) return false; if (clone.canCastleQueenSide[i] != canCastleQueenSide[i]) return false; if (clone.hasCastled[i] != hasCastled[i]) return false; } if (clone.enPassantPosition != enPassantPosition) return false; // if (clone.halfMoveNr != halfMoveNr) return false; if (clone.fiftyMoveNr != fiftyMoveNr) return false; if (clone.capturedPiecePosition != capturedPiecePosition) return false; if (clone.capturedPieceType != capturedPieceType) return false; if (clone.repeatedPosition_SearchOffset != repeatedPosition_SearchOffset) return false; // if (clone.maxNrStoredBoardStates != maxNrStoredBoardStates) return false; if (clone.nrStoredBoardStates != nrStoredBoardStates) return false; for (int i = 0; i < storedBoardStates.Length; i++) { if (!clone.storedBoardStates[i].Equals(storedBoardStates[i]) ) return false; } // if (clone.HashValue != HashValue) return false; if (clone.bwPawnsHashValue != bwPawnsHashValue) return false; for (int i = 0; i < Const.NrColors; i++) { if (clone.StaticMaterialScore[i] != StaticMaterialScore[i]) return false; if (clone.StaticPositionalScore[i] != StaticPositionalScore[i]) return false; } // if (clone.nrHashValuesInHistory != nrHashValuesInHistory) return false; for (int i = 0; i < HashValueHistory.Length; i++) if (clone.HashValueHistory[i] != HashValueHistory[i]) return false; // return true; }
public Board Clone() { // use the empty creator : otherwise to many things are set. Board clone = new Board(false); clone.magicMoves = magicMoves; clone.transpositionTable = transpositionTable; clone.evaluator = evaluator; clone.ClearBoard(); clone.moveGenerator = moveGenerator; // clone.pieces = new ulong[pieces.Length]; for (int i = 0; i < pieces.Length; i++) clone.pieces[i] = pieces[i]; clone.allPiecesBB = allPiecesBB; for (int i = 0; i < Const.NrColors; i++) for (int j = 0; j < Const.NrPieceTypes; j++) clone.pieceBB[i, j] = pieceBB[i, j]; // PiecePos for (int i = 0; i < Const.NrColors; i++) for (int j = 0; j < Const.NrPieceTypes; j++) for (int k = 0; k < Const.MaxNrPiecesPerType; k++) clone.PiecePos[i, j, k] = PiecePos[i, j, k]; // nrPieces for (int i = 0; i < Const.NrColors; i++) { clone.TotalNrPieces[i] = TotalNrPieces[i]; for (int j = 0; j < Const.NrPieceTypes; j++) clone.NrPieces[i, j] = NrPieces[i, j]; } // SquareContents for (int i = 0; i < Const.NrSquares; i++) clone.SquareContents[i] = SquareContents[i]; // // state of the game info clone.colorToMove = colorToMove; clone.enemyColor = enemyColor; for (int i = 0; i < Const.NrColors; i++) { clone.canCastleKingSide[i] = canCastleKingSide[i]; clone.canCastleQueenSide[i] = canCastleQueenSide[i]; clone.hasCastled[i] = hasCastled[i]; } // .. clone.enPassantPosition = enPassantPosition; // clone.halfMoveNr = halfMoveNr; clone.fiftyMoveNr = fiftyMoveNr; clone.capturedPiecePosition = capturedPiecePosition; clone.capturedPieceType = capturedPieceType; clone.repeatedPosition_SearchOffset = repeatedPosition_SearchOffset; // clone.maxNrStoredBoardStates = maxNrStoredBoardStates; clone.nrStoredBoardStates = nrStoredBoardStates; clone.storedBoardStates = new BoardState[storedBoardStates.Length]; for (int i = 0; i < storedBoardStates.Length; i++) clone.storedBoardStates[i] = storedBoardStates[i]; // clone.HashValue = HashValue; clone.bwPawnsHashValue = bwPawnsHashValue; for (int i = 0; i < Const.NrColors; i++) { clone.StaticMaterialScore[i] = StaticMaterialScore[i]; clone.StaticPositionalScore[i] = StaticPositionalScore[i]; } // clone.nrHashValuesInHistory = nrHashValuesInHistory; clone.HashValueHistory = new ulong[HashValueHistory.Length]; for (int i = 0; i < HashValueHistory.Length; i++) clone.HashValueHistory[i] = HashValueHistory[i]; // return clone; }