コード例 #1
0
 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);
 }
コード例 #2
0
        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;
            }
        }
コード例 #3
0
        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);
                    }
                }
            }
        }
コード例 #4
0
        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);
                }
            }
        }
コード例 #5
0
        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);
        }
コード例 #6
0
        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;
            }
        }
コード例 #7
0
        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));
                    }
                }
            }
        }