public static void foreachRookSquare(Position pos, Square pieceSquare, functionByPiece callback) { foreachLineSquare(pos, pieceSquare, 0, 1, callback); foreachLineSquare(pos, pieceSquare, 0, -1, callback); foreachLineSquare(pos, pieceSquare, 1, 0, callback); foreachLineSquare(pos, pieceSquare, -1, 0, callback); }
private void pieceCalculation(Position pos, Square pieceSquare, List <Move> allMoves) { char pieceChar = pos.board[pieceSquare.rank, pieceSquare.line]; bool pieceIsWhite = isWhite(pieceChar); if (pieceIsWhite != pos.whiteToMove) { return; } if (pieceChar == '\0') { return; } if (pieceChar > 'a') { pieceChar = (char)(pieceChar - ('a' - 'A')); //Gör om tecknet till stor bokstav. } char pieceOnCurrentSquare; void addMoveIfValid(Square currentSquare) { pieceOnCurrentSquare = pos.board[currentSquare.rank, currentSquare.line]; if (pieceOnCurrentSquare == '\0' || isWhite(pieceOnCurrentSquare) != pieceIsWhite) { allMoves.Add(new Move(pieceSquare, currentSquare)); } } functionByPiece amiv = new functionByPiece(addMoveIfValid); switch (pieceChar) { case '\0': return; case 'P': pawnMoves(pos, pieceSquare, pieceIsWhite, allMoves); break; case 'N': foreachKnightSquare(pos, pieceSquare, amiv); break; case 'B': foreachBishopSquare(pos, pieceSquare, amiv); break; case 'R': foreachRookSquare(pos, pieceSquare, amiv); break; case 'Q': foreachBishopSquare(pos, pieceSquare, amiv); foreachRookSquare(pos, pieceSquare, amiv); break; case 'K': kingMoves(pos, pieceSquare, pieceIsWhite, allMoves, amiv); break; default: return; } }
public static void foreachKingSquare(Position pos, Square pieceSquare, functionByPiece callback) { Square currentSquare = new Square(); for (sbyte i = -1; i <= 1; i++) { for (sbyte j = -1; j <= 1; j++) { if (i == 0 && j == 0) { continue; } currentSquare.rank = (sbyte)(pieceSquare.rank + i); currentSquare.line = (sbyte)(pieceSquare.line + j); if (validSquare(currentSquare)) { callback(currentSquare); } } } }
public static void foreachKnightSquare(Position pos, Square pieceSquare, functionByPiece callback) { Square currentSquare = new Square(); int newRank, newLine; void callbackByOffset(sbyte rankOffset, sbyte lineOffset) { newRank = (pieceSquare.rank + rankOffset); newLine = (pieceSquare.line + lineOffset); if (newLine < 8 && newLine >= 0) { currentSquare.rank = (sbyte)newRank; currentSquare.line = (sbyte)newLine; callback(currentSquare); } } if (pieceSquare.rank < 7) { callbackByOffset(1, 2); callbackByOffset(1, -2); if (pieceSquare.rank < 6) { callbackByOffset(2, 1); callbackByOffset(2, -1); } } if (pieceSquare.rank > 0) { callbackByOffset(-1, 2); callbackByOffset(-1, -2); if (pieceSquare.rank > 1) { callbackByOffset(-2, 1); callbackByOffset(-2, -1); } } }
private bool isControlledBy(Position pos, Square relevantSquare, bool byWhite) { //Tab (\t) används om inget annat tecken skall sökas efter. bool isControlled = false; char pieceOnCurrentSquare; char[] piecesToLookFor = byWhite ? new char[] { 'B', 'Q' }: new char[] { 'b', 'q' }; void CheckIfPieceToLookFor(Square currentSquare) { pieceOnCurrentSquare = pos.board[currentSquare.rank, currentSquare.line]; if (piecesToLookFor[0] == pieceOnCurrentSquare || piecesToLookFor[1] == pieceOnCurrentSquare) { isControlled = true; } } functionByPiece ciptlf = new functionByPiece(CheckIfPieceToLookFor); foreachBishopSquare(pos, relevantSquare, ciptlf); if (isControlled) { return(true); } piecesToLookFor[0] = byWhite ? 'R' : 'r'; foreachRookSquare(pos, relevantSquare, ciptlf); if (isControlled) { return(true); } piecesToLookFor[0] = byWhite ? 'K' : 'k'; piecesToLookFor[1] = byWhite ? '\t' : '\t'; //Kommer aldrig återfinnas. foreachKingSquare(pos, relevantSquare, ciptlf); if (isControlled) { return(true); } piecesToLookFor[0] = byWhite ? 'N' : 'n'; foreachKnightSquare(pos, relevantSquare, ciptlf); if (isControlled) { return(true); } //Bönder sbyte riktning = byWhite ? (sbyte)1 : (sbyte)-1; char pawnToLookFor = byWhite ? 'P' : 'p'; Square currentPawnSquare; currentPawnSquare.rank = (sbyte)(relevantSquare.rank + riktning); for (sbyte i = -1; i <= 1; i += 2) { currentPawnSquare.line = (sbyte)(relevantSquare.line + i); if (validSquare(currentPawnSquare)) { if (pos.board[currentPawnSquare.rank, currentPawnSquare.line] == pawnToLookFor) { return(true); } } } return(false); }
public static void foreachLineSquare(Position pos, Square pieceSquare, sbyte rankOffset, sbyte lineOffset, functionByPiece callback) { //Generell funktion som itererar över en linje/diagonal så länge det är giltiga fält. pieceSquare.rank += rankOffset; pieceSquare.line += lineOffset; char[,] board = pos.board; while (validSquare(pieceSquare)) { callback(pieceSquare); char pieceOnCurrentSquare = board[pieceSquare.rank, pieceSquare.line]; if (pieceOnCurrentSquare != '\0') //Ett fält där en pjäs står. { break; } pieceSquare.rank += rankOffset; pieceSquare.line += lineOffset; } }
private void kingMoves(Position pos, Square pieceSquare, bool pieceIsWhite, List <Move> possibleMoves, functionByPiece addMoveIfValid) { foreachKingSquare(pos, pieceSquare, addMoveIfValid); sbyte castlingRank = pieceIsWhite ? (sbyte)7: (sbyte)0; if (pieceSquare.rank == castlingRank && pieceSquare.line == 4 && !isControlledBy(pos, pieceSquare, !pieceIsWhite)) { //Kungen står på ett fält där rockad skulle kunna vara möjligt. char correctRook = pieceIsWhite ? 'R' : 'r'; sbyte castlingRightOffset = pieceIsWhite ? (sbyte)0: (sbyte)2; if (pos.board[castlingRank, 0] == correctRook && pos.castlingRights[castlingRightOffset + 1]) { //Lång rockad Square rookTo = new Square(castlingRank, (sbyte)3); Square kingTo = new Square(castlingRank, (sbyte)2); if (pos.board[rookTo.rank, rookTo.line] == '\0' && pos.board[kingTo.rank, kingTo.line] == '\0' && pos.board[kingTo.rank, kingTo.line - 1] == '\0' && !isControlledBy(pos, rookTo, !pieceIsWhite) && !isControlledBy(pos, kingTo, !pieceIsWhite && !isControlledBy(pos, pieceSquare, !pieceIsWhite))) { Square rookFrom = new Square(castlingRank, (sbyte)0); possibleMoves.Insert(0, new Castle(pieceSquare, kingTo, rookFrom, rookTo)); } } if (pos.board[castlingRank, 7] == correctRook && pos.castlingRights[castlingRightOffset]) { //Kort rockad Square rookTo = new Square(castlingRank, (sbyte)5); Square kingTo = new Square(castlingRank, (sbyte)6); if (pos.board[rookTo.rank, rookTo.line] == '\0' && pos.board[kingTo.rank, kingTo.line] == '\0' && !isControlledBy(pos, rookTo, !pieceIsWhite) && !isControlledBy(pos, kingTo, !pieceIsWhite && !isControlledBy(pos, pieceSquare, !pieceIsWhite))) { Square rookFrom = new Square(castlingRank, (sbyte)7); possibleMoves.Insert(0, new Castle(pieceSquare, kingTo, rookFrom, rookTo)); } } } }