The wrong way

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

Henk
Posts: 7218
Joined: Mon May 27, 2013 10:31 am

The wrong way

Post by Henk »

This is Skippers code for collecting captures. I tried to make it faster. But did not help much.

Code: Select all

      public void QCollectMoves&#40;List<MoveBase> moves&#41;
        &#123;
            var whitePieces = Board.WhitePieces;
            var blackPieces = Board.BlackPieces;
            ColorSign colorSign = &#40;ColorSign&#41;Board.CurPlayer;

            var curPieces = colorSign == ColorSign.White ? whitePieces &#58; blackPieces;


            var opponentPieces = Board.Occupiers & ~curPieces;
            var pawns = Board.Pawns;

 
            IField Location = null;
            if &#40;colorSign == ColorSign.White&#41;
            &#123;
                if (&#40;curPieces & pawns & ChessBoard.SEVENTH_ROW_BITMAP&#41; != 0&#41;
                &#123;
                    CPosition.fieldIterator.Reset&#40;curPieces & pawns & ChessBoard.SEVENTH_ROW_BITMAP&#41;;
                    while (&#40;Location = CPosition.fieldIterator.Next&#40;ChessBoard&#41;) != null&#41;
                    &#123;
                        Location.AddPromotionsWhitePawn&#40;moves, this&#41;;
                    &#125;
                &#125;
           &#125;
           else if ( &#40;curPieces & pawns & ChessBoard.SECOND_ROW_BITMAP&#41; != 0&#41;
           &#123;
                CPosition.fieldIterator.Reset&#40;curPieces & pawns & ChessBoard.SECOND_ROW_BITMAP&#41;;
                while (&#40;Location = CPosition.fieldIterator.Next&#40;ChessBoard&#41;) != null&#41;
                &#123;
                    Location.AddPromotionsBlackPawn&#40;moves, this&#41;;
                &#125;
            &#125;

            BitBoardIndex bbIndex = BitBoardIndex.Instance;
            UInt64 bits = curPieces;
            while &#40;bits != 0&#41;
            &#123;
                var bit = bits & (~bits + 1&#41;;
                bits &= bits - 1;
                Location = ChessBoard.GetField&#40;bbIndex, bit&#41;;
                ChessPiece.Sort PieceSort = Location.Occupier.PieceSort;

                if (&#40;Location.XRayMoves&#40;PieceSort&#41; & opponentPieces&#41; != 0 )
                &#123;


                    int dir;
                    switch &#40;PieceSort&#41;
                    &#123;
                        case ChessPiece.Sort.whiteKing&#58;
                            dir = 8;
                            DirectionMoves allMovesKing = (&#40;Field&#41; Location&#41;.dirMoves&#91;&#40;int&#41;ChessPiece.Sort.whiteKing&#93;;
                            while &#40;dir-- > 0&#41;
                            &#123;

                                var dirMoves2 = allMovesKing&#91;dir&#93;;
                                int n = dirMoves2.Count;
                                for &#40;int i = 0; i < n; i++)
                                &#123;
                                    var move = dirMoves2&#91;i&#93;;
                                    ChessPiece capture = move.End.Occupier;
                                    if &#40;capture == null&#41;
                                    &#123;
                                    &#125;
                                    else
                                    &#123;
                                      
                                        if &#40;capture.Colour == ColorSign.Black&#41;
                                        &#123;
                                            switch &#40;capture.PieceKind&#41;
                                            &#123;
                                                case ChessPiece.Kind.King&#58;
                                                    moves.Clear&#40;);
                                                    moves.Add&#40;move&#41;;
                                                    return;
                                                case ChessPiece.Kind.Pawn&#58;
                                                    move.Value = ChessPiece.PK_MVVA_VALUE;
                                                    break;
                                                case ChessPiece.Kind.Knight&#58;
                                                    move.Value = ChessPiece.NK_MVVA_VALUE;
                                                    break;
                                                case ChessPiece.Kind.Bishop&#58;
                                                    move.Value = ChessPiece.BK_MVVA_VALUE;
                                                    break;

                                                case ChessPiece.Kind.Rook&#58;
                                                    move.Value = ChessPiece.RK_MVVA_VALUE;
                                                    break;

                                                case ChessPiece.Kind.Queen&#58;
                                                    move.Value = ChessPiece.QK_MVVA_VALUE;
                                                    break;

                                                default&#58;
                                                    move.Value = ChessPiece.MVVAPoints&#40;capture.PieceKind&#41; - ChessPiece.KING_VALUE;
                                                    moves.Add&#40;move&#41;;
                                                    break;
                                            &#125;
                                             moves.Add&#40;move&#41;;
                                        &#125;
                                        break;
                                    &#125;
                                &#125;
                            &#125;
                            break;
                        case ChessPiece.Sort.blackKing&#58;
                            dir = 8;
                            DirectionMoves allMovesKingB = (&#40;Field&#41;Location&#41;.dirMoves&#91;&#40;int&#41;ChessPiece.Sort.blackKing&#93;;
                            while &#40;dir-- > 0&#41;
                            &#123;

                                var dirMoves2 = allMovesKingB&#91;dir&#93;;
                                int n = dirMoves2.Count;
                                for &#40;int i = 0; i < n; i++)
                                &#123;
                                    var move = dirMoves2&#91;i&#93;;
                                    ChessPiece capture = move.End.Occupier;
                                    if &#40;capture == null&#41;
                                    &#123;
                                    &#125;
                                    else
                                    &#123;
 
                                        if &#40;capture.Colour == ColorSign.White&#41;
                                        &#123;
                                            switch &#40;capture.PieceKind&#41;
                                            &#123;
                                                case ChessPiece.Kind.King&#58;
                                                    moves.Clear&#40;);
                                                    moves.Add&#40;move&#41;;
                                                    return;
                                                case ChessPiece.Kind.Pawn&#58;
                                                    move.Value = ChessPiece.PK_MVVA_VALUE;
                                                    break;
                                                case ChessPiece.Kind.Knight&#58;
                                                    move.Value = ChessPiece.NK_MVVA_VALUE;
                                                    break;
                                                case ChessPiece.Kind.Bishop&#58;
                                                    move.Value = ChessPiece.BK_MVVA_VALUE;
                                                    break;

                                                case ChessPiece.Kind.Rook&#58;
                                                    move.Value = ChessPiece.RK_MVVA_VALUE;
                                                    break;

                                                case ChessPiece.Kind.Queen&#58;
                                                    move.Value = ChessPiece.QK_MVVA_VALUE;
                                                    break;

                                             &#125;
                                            moves.Add&#40;move&#41;;

                                        &#125;
                                        break;
                                    &#125;
                                &#125;
                            &#125;
                            break;
                        case ChessPiece.Sort.whiteKnight&#58;
                            dir = 8;
                            DirectionMoves allMovesKnight = (&#40;Field&#41;Location&#41;.dirMoves&#91;&#40;int&#41;ChessPiece.Sort.whiteKnight&#93;;
                            while &#40;dir-- > 0&#41;
                            &#123;
                                var dirMoves2 = allMovesKnight&#91;dir&#93;;
                                int n = dirMoves2.Count;
                                for &#40;int i = 0; i < n; i++)
                                &#123;
                                    var move = dirMoves2&#91;i&#93;;
                                    ChessPiece capture = move.End.Occupier;
                                    if &#40;capture == null&#41;
                                    &#123;
                                    &#125;
                                    else
                                    &#123;
                                        if &#40;capture.Colour == ColorSign.Black&#41;
                                        &#123;
                                            switch &#40;capture.PieceKind&#41;
                                            &#123;
                                                case ChessPiece.Kind.King&#58;
                                                    moves.Clear&#40;);
                                                    moves.Add&#40;move&#41;;
                                                    return;
                                                case ChessPiece.Kind.Pawn&#58;
                                                    move.Value = ChessPiece.PN_MVVA_VALUE;
                                                    break;
                                                case ChessPiece.Kind.Knight&#58;
                                                    move.Value = ChessPiece.NN_MVVA_VALUE;
                                                    break;
                                                case ChessPiece.Kind.Bishop&#58;
                                                    move.Value = ChessPiece.BN_MVVA_VALUE;
                                                    break;

                                                case ChessPiece.Kind.Rook&#58;
                                                    move.Value = ChessPiece.RN_MVVA_VALUE;
                                                    break;

                                                case ChessPiece.Kind.Queen&#58;
                                                    move.Value = ChessPiece.QN_MVVA_VALUE;
                                                    break;

 
                                            &#125;
                                            moves.Add&#40;move&#41;;
                                        &#125;
                                        break;
                                    &#125;
                                &#125;
                            &#125;
                            break;
                        case ChessPiece.Sort.blackKnight&#58;
                            dir = 8;
                            DirectionMoves allMovesKnightB = (&#40;Field&#41;Location&#41;.dirMoves&#91;&#40;int&#41;ChessPiece.Sort.blackKnight&#93;;
                           while &#40;dir-- > 0&#41;
                            &#123;
                                var dirMoves2 = allMovesKnightB&#91;dir&#93;;
                                int n = dirMoves2.Count;
                                for &#40;int i = 0; i < n; i++)
                                &#123;
                                    var move = dirMoves2&#91;i&#93;;
                                    ChessPiece capture = move.End.Occupier;
                                    if &#40;capture == null&#41;
                                    &#123;
                                    &#125;
                                    else
                                    &#123;
                                        if &#40;capture.Colour == ColorSign.White&#41;
                                        &#123;
                                            switch &#40;capture.PieceKind&#41;
                                            &#123;
                                                case ChessPiece.Kind.King&#58;
                                                    moves.Clear&#40;);
                                                    moves.Add&#40;move&#41;;
                                                    return;
                                                case ChessPiece.Kind.Pawn&#58;
                                                    move.Value = ChessPiece.PN_MVVA_VALUE;
                                                    break;
                                                case ChessPiece.Kind.Knight&#58;
                                                    move.Value = ChessPiece.NN_MVVA_VALUE;
                                                    break;
                                                case ChessPiece.Kind.Bishop&#58;
                                                    move.Value = ChessPiece.BN_MVVA_VALUE;
                                                    break;

                                                case ChessPiece.Kind.Rook&#58;
                                                    move.Value = ChessPiece.RN_MVVA_VALUE;
                                                    break;

                                                case ChessPiece.Kind.Queen&#58;
                                                    move.Value = ChessPiece.QN_MVVA_VALUE;
                                                    break;

  
                                            &#125;
                                            moves.Add&#40;move&#41;;
                                        &#125;
                                        break;
                                    &#125;
                                &#125;
                            &#125;
                            break;
                        case ChessPiece.Sort.whitePawn&#58;
                            DirectionMoves allMoves = (&#40;Field&#41;Location&#41;.dirMoves&#91;&#40;int&#41;ChessPiece.Sort.whitePawn&#93;;
                            int colNr = Location.ColNr;
                            if &#40;colNr > ChessBoard.FIRSTCOLUMN&#41;
                            &#123;
                                MoveBase move = allMoves&#91;&#40;int&#41;Pawn.Direction.LEFT&#93;&#91;0&#93;;
                                Debug.Assert&#40;!&#40;move is EPMove&#41;);

                                ChessPiece capture = move.End.Occupier;
                                if &#40;capture != null && capture.Colour == ColorSign.Black&#41; // capture
                                &#123;
                                    switch &#40;capture.PieceKind&#41;
                                    &#123;
                                        case ChessPiece.Kind.King&#58;
                                            moves.Clear&#40;);
                                            moves.Add&#40;move&#41;;
                                            return;
                                        case ChessPiece.Kind.Pawn&#58;
                                            move.Value = ChessPiece.PP_MVVA_VALUE;
                                            break;
                                        case ChessPiece.Kind.Knight&#58;
                                            move.Value = ChessPiece.NP_MVVA_VALUE;
                                            break;
                                        case ChessPiece.Kind.Bishop&#58;
                                            move.Value = ChessPiece.BP_MVVA_VALUE;
                                            break;

                                        case ChessPiece.Kind.Rook&#58;
                                            move.Value = ChessPiece.RP_MVVA_VALUE;
                                            break;

                                        case ChessPiece.Kind.Queen&#58;
                                            move.Value = ChessPiece.QP_MVVA_VALUE;
                                            break;

 
                                    &#125;
                                    moves.Add&#40;move&#41;;

                                &#125;
                                var epMoves = allMoves&#91;&#40;int&#41;Pawn.Direction.EP_LEFT&#93;;
                                if &#40;epMoves.Count > 0&#41;
                                &#123;
                                    move = epMoves&#91;0&#93;;
                                    if &#40;move.CanMove&#40;colorSign, this, Location&#41;)
                                    &#123;
                                            Debug.Assert&#40;&#40;move is EPMove&#41;);

                                            capture = &#40;ChessPiece&#41;move.GetCapture&#40;this&#41;;
                                            switch &#40;capture.PieceKind&#41;
                                            &#123;
                                                case ChessPiece.Kind.King&#58;
                                                    moves.Clear&#40;);
                                                    moves.Add&#40;move&#41;;
                                                    return;
                                                case ChessPiece.Kind.Pawn&#58;
                                                    move.Value = ChessPiece.PP_MVVA_VALUE;
                                                    break;
                                                case ChessPiece.Kind.Knight&#58;
                                                    move.Value = ChessPiece.NP_MVVA_VALUE;
                                                    break;
                                                case ChessPiece.Kind.Bishop&#58;
                                                    move.Value = ChessPiece.BP_MVVA_VALUE;
                                                    break;

                                                case ChessPiece.Kind.Rook&#58;
                                                    move.Value = ChessPiece.RP_MVVA_VALUE;
                                                    break;

                                                case ChessPiece.Kind.Queen&#58;
                                                    move.Value = ChessPiece.QP_MVVA_VALUE;
                                                    break;


                                            &#125;
                                            moves.Add&#40;move&#41;;

                                     &#125;
                                &#125;
                            &#125;
                            if &#40;colNr < ChessBoard.LASTCOLUMN&#41;
                            &#123;
                                MoveBase move = allMoves&#91;&#40;int&#41;Pawn.Direction.RIGHT&#93;&#91;0&#93;;
                                Debug.Assert&#40;!&#40;move is EPMove&#41;);

                                ChessPiece capture = move.End.Occupier;
                                if &#40;capture != null && capture.Colour == ColorSign.Black&#41; // capture
                                &#123;
                                     switch &#40;capture.PieceKind&#41;
                                    &#123;
                                        case ChessPiece.Kind.King&#58;
                                            moves.Clear&#40;);
                                            moves.Add&#40;move&#41;;
                                            return;
                                        case ChessPiece.Kind.Pawn&#58;
                                            move.Value = ChessPiece.PP_MVVA_VALUE;
                                            break;
                                        case ChessPiece.Kind.Knight&#58;
                                            move.Value = ChessPiece.NP_MVVA_VALUE;
                                            break;
                                        case ChessPiece.Kind.Bishop&#58;
                                            move.Value = ChessPiece.BP_MVVA_VALUE;
                                            break;

                                        case ChessPiece.Kind.Rook&#58;
                                            move.Value = ChessPiece.RP_MVVA_VALUE;
                                            break;

                                        case ChessPiece.Kind.Queen&#58;
                                            move.Value = ChessPiece.QP_MVVA_VALUE;
                                            break;


                                    &#125;

                                    moves.Add&#40;move&#41;;
                                &#125;
                                var epMoves = allMoves&#91;&#40;int&#41;Pawn.Direction.EP_RIGHT&#93;;
                                if &#40;epMoves.Count > 0&#41;
                                &#123;
                                    move = epMoves&#91;0&#93;;
                                    if &#40;move.CanMove&#40;colorSign, this, Location&#41;)
                                    &#123;
                                        Debug.Assert&#40;&#40;move is EPMove&#41;);

                                            capture = &#40;ChessPiece&#41;move.GetCapture&#40;this&#41;;
                                            switch &#40;capture.PieceKind&#41;
                                            &#123;
                                                case ChessPiece.Kind.King&#58;
                                                    moves.Clear&#40;);
                                                    moves.Add&#40;move&#41;;
                                                    return;
                                                case ChessPiece.Kind.Pawn&#58;
                                                    move.Value = ChessPiece.PP_MVVA_VALUE;
                                                    break;
                                                case ChessPiece.Kind.Knight&#58;
                                                    move.Value = ChessPiece.NP_MVVA_VALUE;
                                                    break;
                                                case ChessPiece.Kind.Bishop&#58;
                                                    move.Value = ChessPiece.BP_MVVA_VALUE;
                                                    break;

                                                case ChessPiece.Kind.Rook&#58;
                                                    move.Value = ChessPiece.RP_MVVA_VALUE;
                                                    break;

                                                case ChessPiece.Kind.Queen&#58;
                                                    move.Value = ChessPiece.QP_MVVA_VALUE;
                                                    break;


                                            &#125;
                                            moves.Add&#40;move&#41;;

                                     &#125;
                                &#125;
                            &#125;
                            break;

                        case ChessPiece.Sort.blackPawn&#58;
                            DirectionMoves allMovesBP = (&#40;Field&#41;Location&#41;.dirMoves&#91;&#40;int&#41;ChessPiece.Sort.blackPawn&#93;;
                            int colNrBP = Location.ColNr;
                            if &#40;colNrBP > ChessBoard.FIRSTCOLUMN&#41;
                            &#123;
                                MoveBase move = allMovesBP&#91;&#40;int&#41;Pawn.Direction.LEFT&#93;&#91;0&#93;;
                                Debug.Assert&#40;!&#40;move is EPMove&#41;);

                                ChessPiece occupier = move.End.Occupier;
                                if &#40;occupier != null && occupier.Colour == ColorSign.White&#41; // capture
                                &#123;
                                    IPiece capture = move.End.Occupier;
                                    switch &#40;capture.PieceKind&#41;
                                    &#123;
                                        case ChessPiece.Kind.King&#58;
                                            moves.Clear&#40;);
                                            moves.Add&#40;move&#41;;
                                            return;
                                        case ChessPiece.Kind.Pawn&#58;
                                            move.Value = ChessPiece.PP_MVVA_VALUE;
                                            break;
                                        case ChessPiece.Kind.Knight&#58;
                                            move.Value = ChessPiece.NP_MVVA_VALUE;
                                            break;
                                        case ChessPiece.Kind.Bishop&#58;
                                            move.Value = ChessPiece.BP_MVVA_VALUE;
                                            break;

                                        case ChessPiece.Kind.Rook&#58;
                                            move.Value = ChessPiece.RP_MVVA_VALUE;
                                            break;

                                        case ChessPiece.Kind.Queen&#58;
                                            move.Value = ChessPiece.QP_MVVA_VALUE;
                                            break;
  
                                    &#125;
                                    moves.Add&#40;move&#41;;

                                &#125;
                              
                                var epMoves = allMovesBP&#91;&#40;int&#41;Pawn.Direction.EP_LEFT&#93;;
                                if &#40;epMoves.Count > 0&#41;
                                &#123;
                                    move = epMoves&#91;0&#93;;

                                    if &#40;move.CanMove&#40;colorSign, this, Location&#41;)
                                    &#123;
                                        Debug.Assert&#40;&#40;move is EPMove&#41;);

                                            var capture = move.GetCapture&#40;this&#41;;
                                            switch &#40;capture.PieceKind&#41;
                                            &#123;
                                                case ChessPiece.Kind.King&#58;
                                                    moves.Clear&#40;);
                                                    moves.Add&#40;move&#41;;
                                                    return;
                                                case ChessPiece.Kind.Pawn&#58;
                                                    move.Value = ChessPiece.PP_MVVA_VALUE;
                                                    break;
                                                case ChessPiece.Kind.Knight&#58;
                                                    move.Value = ChessPiece.NP_MVVA_VALUE;
                                                    break;
                                                case ChessPiece.Kind.Bishop&#58;
                                                    move.Value = ChessPiece.BP_MVVA_VALUE;
                                                    break;

                                                case ChessPiece.Kind.Rook&#58;
                                                    move.Value = ChessPiece.RP_MVVA_VALUE;
                                                    break;

                                                case ChessPiece.Kind.Queen&#58;
                                                    move.Value = ChessPiece.QP_MVVA_VALUE;
                                                    break;


                                            &#125;
                                            moves.Add&#40;move&#41;;
                                    &#125;
                                &#125;
                            &#125;
                            if &#40;colNrBP < ChessBoard.LASTCOLUMN&#41;
                            &#123;
                                MoveBase move = allMovesBP&#91;&#40;int&#41;Pawn.Direction.RIGHT&#93;&#91;0&#93;;
                                Debug.Assert&#40;!&#40;move is EPMove&#41;);

                                ChessPiece occupier = move.End.Occupier;
                                if &#40;occupier != null && occupier.Colour == ColorSign.White&#41; // capture
                                &#123;
                                    IPiece capture = move.End.Occupier;
                                    switch &#40;capture.PieceKind&#41;
                                    &#123;
                                        case ChessPiece.Kind.King&#58;
                                            moves.Clear&#40;);
                                            moves.Add&#40;move&#41;;
                                            return;
                                        case ChessPiece.Kind.Pawn&#58;
                                            move.Value = ChessPiece.PP_MVVA_VALUE;
                                            break;
                                        case ChessPiece.Kind.Knight&#58;
                                            move.Value = ChessPiece.NP_MVVA_VALUE;
                                            break;
                                        case ChessPiece.Kind.Bishop&#58;
                                            move.Value = ChessPiece.BP_MVVA_VALUE;
                                            break;

                                        case ChessPiece.Kind.Rook&#58;
                                            move.Value = ChessPiece.RP_MVVA_VALUE;
                                            break;

                                        case ChessPiece.Kind.Queen&#58;
                                            move.Value = ChessPiece.QP_MVVA_VALUE;
                                            break;

                                    &#125;

                                    moves.Add&#40;move&#41;;
                                &#125;
                                var epMoves = allMovesBP&#91;&#40;int&#41;Pawn.Direction.EP_RIGHT&#93;;
                                if &#40;epMoves.Count > 0&#41;
                                &#123;
                                    move = epMoves&#91;0&#93;;
                                    if &#40;move.CanMove&#40;colorSign, this, Location&#41;)
                                    &#123;
                                        Debug.Assert&#40;&#40;move is EPMove&#41;);

                                           IPiece capture = move.GetCapture&#40;this&#41;;
                                            switch &#40;capture.PieceKind&#41;
                                            &#123;
                                                case ChessPiece.Kind.King&#58;
                                                    moves.Clear&#40;);
                                                    moves.Add&#40;move&#41;;
                                                    return;
                                                case ChessPiece.Kind.Pawn&#58;
                                                    move.Value = ChessPiece.PP_MVVA_VALUE;
                                                    break;
                                                case ChessPiece.Kind.Knight&#58;
                                                    move.Value = ChessPiece.NP_MVVA_VALUE;
                                                    break;
                                                case ChessPiece.Kind.Bishop&#58;
                                                    move.Value = ChessPiece.BP_MVVA_VALUE;
                                                    break;

                                                case ChessPiece.Kind.Rook&#58;
                                                    move.Value = ChessPiece.RP_MVVA_VALUE;
                                                    break;

                                                case ChessPiece.Kind.Queen&#58;
                                                    move.Value = ChessPiece.QP_MVVA_VALUE;
                                                    break;


                                            &#125;
                                            moves.Add&#40;move&#41;;
                                   &#125;
                                &#125;
                            &#125;
                            break;


                        case ChessPiece.Sort.whiteQueen&#58;

                            dir = 8;
                            var xrayMoves = (&#40;Field&#41;Location&#41;.dirMoves&#91;&#40;int&#41;ChessPiece.Sort.whiteQueen&#93;;
                            var dirMoves = Location.DirMoves&#40;ChessPiece.Sort.whiteQueen&#41;;
                            while &#40;dir-- > 0&#41;
                            &#123;

                                if (&#40;dirMoves&#91;dir&#93; & blackPieces&#41; == 0&#41;
                                &#123;
                                    // all moves in a direction don't hit any opponent pieces
                                    continue;
                                &#125;

                                var xrayDirMoves = xrayMoves&#91;dir&#93;;
                                int n = xrayDirMoves.Count;
                                for &#40;int i = 0; i < n;)
                                &#123;
                                    var move = xrayDirMoves&#91;i++&#93;;
                                    // check each move, there can only be one capture in a direction
                                    ChessPiece capture = move.End.Occupier;

                                    if &#40;capture == null&#41;
                                    &#123;
                                    &#125;
                                    else if &#40;capture.Colour == ColorSign.Black&#41;
                                    &#123;
                                         switch &#40;capture.PieceKind&#41;
                                        &#123;
                                            case ChessPiece.Kind.King&#58;
                                                moves.Clear&#40;);
                                                moves.Add&#40;move&#41;;
                                                return;
                                            case ChessPiece.Kind.Pawn&#58;
                                                move.Value = ChessPiece.PQ_MVVA_VALUE;
                                                break;
                                            case ChessPiece.Kind.Knight&#58;
                                                move.Value = ChessPiece.NQ_MVVA_VALUE;
                                                break;
                                            case ChessPiece.Kind.Bishop&#58;
                                                move.Value = ChessPiece.BQ_MVVA_VALUE;
                                                break;

                                            case ChessPiece.Kind.Rook&#58;
                                                move.Value = ChessPiece.RQ_MVVA_VALUE;
                                                break;

                                            case ChessPiece.Kind.Queen&#58;
                                                move.Value = ChessPiece.QQ_MVVA_VALUE;
                                                break;
 
                                        &#125;
                                       
                                        moves.Add&#40;move&#41;;

                                        break;
                                    &#125;
                                    else break;
                                &#125;
                            &#125;
                            break;
                        case ChessPiece.Sort.blackQueen&#58;

                            dir = 8;
                            var xrayMovesBQ = (&#40;Field&#41;Location&#41;.dirMoves&#91;&#40;int&#41;ChessPiece.Sort.blackQueen&#93;;
                            var dirMovesBQ = Location.DirMoves&#40;ChessPiece.Sort.blackQueen&#41;;
                            while &#40;dir-- > 0&#41;
                            &#123;

                                if (&#40;dirMovesBQ&#91;dir&#93; & whitePieces&#41; == 0&#41;
                                &#123;
                                    // all moves in a direction don't hit any opponent pieces
                                    continue;
                                &#125;

                                var xrayDirMoves = xrayMovesBQ&#91;dir&#93;;
                                int n = xrayDirMoves.Count;
                                for &#40;int i = 0; i < n;)
                                &#123;
                                    var move = xrayDirMoves&#91;i++&#93;;
                                    // check each move, there can only be one capture in a direction
                                    ChessPiece capture = move.End.Occupier;

                                    if &#40;capture == null&#41;
                                    &#123;
                                    &#125;
                                    else if &#40;capture.Colour == ColorSign.White&#41;
                                    &#123;
                                        switch &#40;capture.PieceKind&#41;
                                        &#123;
                                            case ChessPiece.Kind.King&#58;
                                                moves.Clear&#40;);
                                                moves.Add&#40;move&#41;;
                                                return;
                                            case ChessPiece.Kind.Pawn&#58;
                                                move.Value = ChessPiece.PQ_MVVA_VALUE;
                                                break;
                                            case ChessPiece.Kind.Knight&#58;
                                                move.Value = ChessPiece.NQ_MVVA_VALUE;
                                                break;
                                            case ChessPiece.Kind.Bishop&#58;
                                                move.Value = ChessPiece.BQ_MVVA_VALUE;
                                                break;

                                            case ChessPiece.Kind.Rook&#58;
                                                move.Value = ChessPiece.RQ_MVVA_VALUE;
                                                break;

                                            case ChessPiece.Kind.Queen&#58;
                                                move.Value = ChessPiece.QQ_MVVA_VALUE;
                                                break;
 
                                        &#125;
                                       
                                        moves.Add&#40;move&#41;;

                                        break;
                                    &#125;
                                    else break;
                                &#125;
                            &#125;
                            break;
                        case ChessPiece.Sort.whiteRook&#58;
                      
                            dir = 4;
                            var xrayMovesR = (&#40;Field&#41;Location&#41;.dirMoves&#91;&#40;int&#41;ChessPiece.Sort.whiteRook&#93;;
                            var dirMovesR = Location.DirMoves&#40;ChessPiece.Sort.whiteRook&#41;;
                            while &#40;dir-- > 0&#41;
                            &#123;

                                if (&#40;dirMovesR&#91;dir&#93; & blackPieces&#41; == 0&#41;
                                &#123;
                                    // all moves in a direction don't hit any opponent pieces
                                    continue;
                                &#125;

                                var xrayDirMoves = xrayMovesR&#91;dir&#93;;
                                int n = xrayDirMoves.Count;
                                for &#40;int i = 0; i < n;)
                                &#123;
                                    var move = xrayDirMoves&#91;i++&#93;;
                                    // check each move, there can only be one capture in a direction
                                    ChessPiece capture = move.End.Occupier;
                                    if &#40;capture == null&#41;
                                    &#123;
                                    &#125;
                                    else if &#40;capture.Colour == ColorSign.Black&#41;
                                    &#123;
                                        switch &#40;capture.PieceKind&#41;
                                        &#123;
                                            case ChessPiece.Kind.King&#58;
                                                moves.Clear&#40;);
                                                moves.Add&#40;move&#41;;
                                                return;
                                            case ChessPiece.Kind.Pawn&#58;
                                                move.Value = ChessPiece.PR_MVVA_VALUE;
                                                break;
                                            case ChessPiece.Kind.Knight&#58;
                                                move.Value = ChessPiece.NR_MVVA_VALUE;
                                                break;
                                            case ChessPiece.Kind.Bishop&#58;
                                                move.Value = ChessPiece.BR_MVVA_VALUE;
                                                break;

                                            case ChessPiece.Kind.Rook&#58;
                                                move.Value = ChessPiece.RR_MVVA_VALUE;
                                                break;

                                            case ChessPiece.Kind.Queen&#58;
                                                move.Value = ChessPiece.QR_MVVA_VALUE;
                                                break;
 
                                        &#125;
                                      
                                        moves.Add&#40;move&#41;;

                                        break;
                                    &#125;
                                    else break;
                                &#125;
                            &#125;
                            break;
                        case ChessPiece.Sort.blackRook&#58;
                            dir = 4;
                            var xrayMovesRB = (&#40;Field&#41;Location&#41;.dirMoves&#91;&#40;int&#41;ChessPiece.Sort.blackRook&#93;;
                            var dirMovesRB = Location.DirMoves&#40;ChessPiece.Sort.blackRook&#41;;
                            while &#40;dir-- > 0&#41;
                            &#123;

                                if (&#40;dirMovesRB&#91;dir&#93; & whitePieces&#41; == 0&#41;
                                &#123;
                                    // all moves in a direction don't hit any opponent pieces
                                    continue;
                                &#125;

                                var xrayDirMoves = xrayMovesRB&#91;dir&#93;;
                                int n = xrayDirMoves.Count;
                                for &#40;int i = 0; i < n;)
                                &#123;
                                    var move = xrayDirMoves&#91;i++&#93;;
                                    // check each move, there can only be one capture in a direction
                                    ChessPiece capture = move.End.Occupier;
                                    if &#40;capture == null&#41;
                                    &#123;
                                    &#125;
                                    else if &#40;capture.Colour == ColorSign.White&#41;
                                    &#123;
                                        switch &#40;capture.PieceKind&#41;
                                        &#123;
                                            case ChessPiece.Kind.King&#58;
                                                moves.Clear&#40;);
                                                moves.Add&#40;move&#41;;
                                                return;
                                            case ChessPiece.Kind.Pawn&#58;
                                                move.Value = ChessPiece.PR_MVVA_VALUE;
                                                break;
                                            case ChessPiece.Kind.Knight&#58;
                                                move.Value = ChessPiece.NR_MVVA_VALUE;
                                                break;
                                            case ChessPiece.Kind.Bishop&#58;
                                                move.Value = ChessPiece.BR_MVVA_VALUE;
                                                break;

                                            case ChessPiece.Kind.Rook&#58;
                                                move.Value = ChessPiece.RR_MVVA_VALUE;
                                                break;

                                            case ChessPiece.Kind.Queen&#58;
                                                move.Value = ChessPiece.QR_MVVA_VALUE;
                                                break;
 
                                        &#125;
                                        moves.Add&#40;move&#41;;

                                        break;
                                    &#125;
                                    else break;
                                &#125;
                            &#125;
                            break;
                        case ChessPiece.Sort.whiteBishop&#58;
                            dir = 4;
                            var xrayMovesB = (&#40;Field&#41;Location&#41;.dirMoves&#91;&#40;int&#41;ChessPiece.Sort.whiteBishop&#93;;
                            var dirMovesB = Location.DirMoves&#40;ChessPiece.Sort.whiteBishop&#41;;
                            while &#40;dir-- > 0&#41;
                            &#123;

                                if (&#40;dirMovesB&#91;dir&#93; & blackPieces&#41; == 0&#41;
                                &#123;
                                    // all moves in a direction don't hit any opponent pieces
                                    continue;
                                &#125;

                                var xrayDirMoves = xrayMovesB&#91;dir&#93;;
                                int n = xrayDirMoves.Count;
                                for &#40;int i = 0; i < n;)
                                &#123;
                                    var move = xrayDirMoves&#91;i++&#93;;
                                    // check each move, there can only be one capture in a direction
                                    ChessPiece capture = move.End.Occupier;
                                    if &#40;capture == null&#41;
                                    &#123;
                                    &#125;
                                    else if &#40;capture.Colour == ColorSign.Black&#41;
                                    &#123;
                                        switch &#40;capture.PieceKind&#41;
                                        &#123;
                                            case ChessPiece.Kind.King&#58;
                                                moves.Clear&#40;);
                                                moves.Add&#40;move&#41;;
                                                return;
                                            case ChessPiece.Kind.Pawn&#58;
                                                move.Value = ChessPiece.PB_MVVA_VALUE;
                                                break;
                                            case ChessPiece.Kind.Knight&#58;
                                                move.Value = ChessPiece.NB_MVVA_VALUE;
                                                break;
                                            case ChessPiece.Kind.Bishop&#58;
                                                move.Value = ChessPiece.BB_MVVA_VALUE;
                                                break;

                                            case ChessPiece.Kind.Rook&#58;
                                                move.Value = ChessPiece.RB_MVVA_VALUE;
                                                break;

                                            case ChessPiece.Kind.Queen&#58;
                                                move.Value = ChessPiece.QB_MVVA_VALUE;
                                                break;
                                       &#125;

                                        moves.Add&#40;move&#41;;
                                        break;
                                    &#125;
                                    else break;
                                &#125;
                            &#125;
                            break;

                        case ChessPiece.Sort.blackBishop&#58;

                            dir = 4;
                            var xrayMovesBB = (&#40;Field&#41;Location&#41;.dirMoves&#91;&#40;int&#41;ChessPiece.Sort.blackBishop&#93;;
                            var dirMovesBB = Location.DirMoves&#40;ChessPiece.Sort.blackBishop&#41;;
                            while &#40;dir-- > 0&#41;
                            &#123;

                                if (&#40;dirMovesBB&#91;dir&#93; & whitePieces&#41; == 0&#41;
                                &#123;
                                    // all moves in a direction don't hit any opponent pieces
                                    continue;
                                &#125;

                                var xrayDirMoves = xrayMovesBB&#91;dir&#93;;
                                int n = xrayDirMoves.Count;
                                for &#40;int i = 0; i < n;)
                                &#123;
                                    var move = xrayDirMoves&#91;i++&#93;;
                                    // check each move, there can only be one capture in a direction
                                    ChessPiece capture = move.End.Occupier;
                                    if &#40;capture == null&#41;
                                    &#123;
                                    &#125;
                                    else if &#40;capture.Colour == ColorSign.White&#41;
                                    &#123;
                                        switch &#40;capture.PieceKind&#41;
                                        &#123;
                                            case ChessPiece.Kind.King&#58;
                                                moves.Clear&#40;);
                                                moves.Add&#40;move&#41;;
                                                return;
                                            case ChessPiece.Kind.Pawn&#58;
                                                move.Value = ChessPiece.PB_MVVA_VALUE;
                                                break;
                                            case ChessPiece.Kind.Knight&#58;
                                                move.Value = ChessPiece.NB_MVVA_VALUE;
                                                break;
                                            case ChessPiece.Kind.Bishop&#58;
                                                move.Value = ChessPiece.BB_MVVA_VALUE;
                                                break;

                                            case ChessPiece.Kind.Rook&#58;
                                                move.Value = ChessPiece.RB_MVVA_VALUE;
                                                break;

                                            case ChessPiece.Kind.Queen&#58;
                                                move.Value = ChessPiece.QB_MVVA_VALUE;
                                                break;
                                            default&#58;
                                                move.Value = ChessPiece.MVVAPoints&#40;capture.PieceKind&#41;;
                                                break;
                                        &#125;

                                        moves.Add&#40;move&#41;;
                                        break;
                                    &#125;
                                    else break;
                                &#125;
                            &#125;
                            break;
                    &#125;

                &#125;

            &#125;


        &#125;
User avatar
hgm
Posts: 27795
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: The wrong way

Post by hgm »

Well, if you want things to be fast, switch statements are a no-no. Use the piece type as index in an array that contains the values you want to assign instead.
User avatar
hgm
Posts: 27795
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: The wrong way

Post by hgm »

Well, if you want things to be fast, switch statements are a no-no. Use the piece type as index in an array that contains the values you want to assign instead.
jdart
Posts: 4366
Joined: Fri Mar 10, 2006 5:23 am
Location: http://www.arasanchess.org

Re: The wrong way

Post by jdart »

Most programs do not spend most of their time in movegen. Usually it is sub 10% of the total search time. You can profile and see if this is the case for you.

I am not clear if you are using bitboards or not. Finding attacked pieces with bitboards and magic move generation is pretty fast and can be done with no looping at all.

--Jon
User avatar
lucasart
Posts: 3232
Joined: Mon May 31, 2010 1:29 pm
Full name: lucasart

Re: The wrong way

Post by lucasart »

That's some god-awful code you got. But, at least you wrote it yourself, which the way to progress (rather than make trivial changes to other people's code, which is the new trend in computer chess)

1/ Do not uglify your code for the sake of optimisation. Even in SF, which is incredibly fast/optimized, we almost never accept uglifying micro optimisation. And when we do, it's only after establishing there is no less ugly way of achieving the speedup, and the speedup is significant enough to pay for its ugliness.

2/ How do you even know that you actually optimized anything? Can you prove that before/after versions have the same functionality? Can you measure the speedup? I bet the answer is no to both questions, and you just uglified your code gratuitously , adding bugs while at it…

3/ Do not repeat block of codes. Use loops. Repeated code is harder to follow and maintain, makes it easier to introduce bugs… Conciceness is a huge part of code clarity and maintainability.

4/ Avoid switch if you can. Use loops, or reorganize your code in such a way that switch is not needed. Switch is one of those ugly things like goto: try to avoid it in general, and only resort to using it occasionally, when you dont have a better choice.
Theory and practice sometimes clash. And when that happens, theory loses. Every single time.
Dann Corbit
Posts: 12540
Joined: Wed Mar 08, 2006 8:57 pm
Location: Redmond, WA USA

Re: The wrong way

Post by Dann Corbit »

hgm wrote:Well, if you want things to be fast, switch statements are a no-no. Use the piece type as index in an array that contains the values you want to assign instead.
In release mode, the optimizer will make that table for you.
Switch statements are good and fast.
They are not processed like a list of if tests.
Or the compiler will come up with something else that is very efficient.
Like this:

int switchtest(int state)
{
int ret = 0;
switch (state)
{
case 1:
ret++;
break;
case 2:
ret+=3;
break;
case 3:
ret+=5;
break;
case 0: // Note, out of order
ret+=7;
break;
case 4:
ret+=9;
break;
case 5:
ret+=11;
break;
case 6:
ret+=13;
break;
case 7:
ret+=15;
break;
case 8:
ret+=17;
break;
case 9:
ret+=19;
break;
case 10:
ret+=21;
break;
case 11:
ret+=23;
break;
case 12:
ret+=25;
break;
case 13:
ret+=27;
break;
case 14:
ret+=29;
break;
case 15:
ret+=31;
break;
default:
ret--;
break;
}
return ret;
}
/*
; Listing generated by Microsoft (R) Optimizing Compiler Version 17.00.61030.0

include listing.inc

INCLUDELIB LIBCMT
INCLUDELIB OLDNAMES

PUBLIC switchtest
EXTRN __ImageBase:BYTE
; Function compile flags: /Ogtpy
_TEXT SEGMENT
state$ = 8
switchtest PROC
; File q:\cc\retswitch.c
; Line 5
cmp ecx, 15
ja SHORT $LN1@switchtest
lea rdx, OFFSET FLAT:__ImageBase
movsxd rax, ecx
mov ecx, DWORD PTR $LN22@switchtest[rdx+rax*4]
add rcx, rdx
jmp rcx
$LN17@switchtest:
; Line 8
mov eax, 1
; Line 60
ret 0
$LN16@switchtest:
; Line 11
mov eax, 3
; Line 60
ret 0
$LN15@switchtest:
; Line 14
mov eax, 5
; Line 60
ret 0
$LN14@switchtest:
; Line 17
mov eax, 7
; Line 60
ret 0
$LN13@switchtest:
; Line 20
mov eax, 9
; Line 60
ret 0
$LN12@switchtest:
; Line 23
mov eax, 11
; Line 60
ret 0
$LN11@switchtest:
; Line 26
mov eax, 13
; Line 60
ret 0
$LN10@switchtest:
; Line 29
mov eax, 15
; Line 60
ret 0
$LN9@switchtest:
; Line 32
mov eax, 17
; Line 60
ret 0
$LN8@switchtest:
; Line 35
mov eax, 19
; Line 60
ret 0
$LN7@switchtest:
; Line 38
mov eax, 21
; Line 60
ret 0
$LN6@switchtest:
; Line 41
mov eax, 23
; Line 60
ret 0
$LN5@switchtest:
; Line 44
mov eax, 25
; Line 60
ret 0
$LN4@switchtest:
; Line 47
mov eax, 27
; Line 60
ret 0
$LN3@switchtest:
; Line 50
mov eax, 29
; Line 60
ret 0
$LN2@switchtest:
; Line 53
mov eax, 31
; Line 60
ret 0
$LN1@switchtest:
; Line 56
or eax, -1
; Line 60
ret 0
npad 1
$LN22@switchtest:
DD $LN14@switchtest
DD $LN17@switchtest
DD $LN16@switchtest
DD $LN15@switchtest
DD $LN13@switchtest
DD $LN12@switchtest
DD $LN11@switchtest
DD $LN10@switchtest
DD $LN9@switchtest
DD $LN8@switchtest
DD $LN7@switchtest
DD $LN6@switchtest
DD $LN5@switchtest
DD $LN4@switchtest
DD $LN3@switchtest
DD $LN2@switchtest
switchtest ENDP
_TEXT ENDS
END

*/
Taking ideas is not a vice, it is a virtue. We have another word for this. It is called learning.
But sharing ideas is an even greater virtue. We have another word for this. It is called teaching.
Dann Corbit
Posts: 12540
Joined: Wed Mar 08, 2006 8:57 pm
Location: Redmond, WA USA

Re: The wrong way

Post by Dann Corbit »

The GCC version is even prettier:

Code: Select all

Q&#58;\cc>type retswitch.s
        .file   "retswitch.c"
        .section        .text.unlikely,"x"
.LCOLDB0&#58;
        .text
.LHOTB0&#58;
        .p2align 4,,15
        .globl  switchtest
        .def    switchtest;     .scl    2;      .type   32;     .endef
        .seh_proc       switchtest
switchtest&#58;
        .seh_endprologue
        movl    $-1, %eax
        cmpl    $15, %ecx
        ja      .L2
        leaq    CSWTCH.1&#40;%rip&#41;, %rax
        movl    %ecx, %ecx
        movl    (%rax,%rcx,4&#41;, %eax
.L2&#58;
        ret
        .seh_endproc
        .section        .text.unlikely,"x"
.LCOLDE0&#58;
        .text
.LHOTE0&#58;
        .section .rdata,"dr"
        .align 32
CSWTCH.1&#58;
        .long   7
        .long   1
        .long   3
        .long   5
        .long   9
        .long   11
        .long   13
        .long   15
        .long   17
        .long   19
        .long   21
        .long   23
        .long   25
        .long   27
        .long   29
        .long   31
        .ident  "GCC&#58; &#40;x86_64-posix-seh-rev0, Built by MinGW-W64 project&#41; 5.2.0"

Q&#58;\cc>
Taking ideas is not a vice, it is a virtue. We have another word for this. It is called learning.
But sharing ideas is an even greater virtue. We have another word for this. It is called teaching.
User avatar
hgm
Posts: 27795
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: The wrong way

Post by hgm »

That is awful and very slow code. It uses an indirect jump, which means a guaranteed misprediction. At least an order of magnitude slower (not to mention larger) than

ret=result[state];

[Edit] gcc got it right, but you see that not all compilers are that smart. Better to already write it in your source. That makes it more readable too.
Henk
Posts: 7218
Joined: Mon May 27, 2013 10:31 am

Re: The wrong way

Post by Henk »

jdart wrote:Most programs do not spend most of their time in movegen. Usually it is sub 10% of the total search time. You can profile and see if this is the case for you.

I am not clear if you are using bitboards or not. Finding attacked pieces with bitboards and magic move generation is pretty fast and can be done with no looping at all.

--Jon
Skipper uses 19% percent of it's time for collecting captures.
Other bottleneck is collecting remaining moves after killers. And that's another 10-20%.
jdart
Posts: 4366
Joined: Fri Mar 10, 2006 5:23 am
Location: http://www.arasanchess.org

Re: The wrong way

Post by jdart »

That's too much.

Take a look at https://github.com/jdart1/arasan-chess/ ... /attacks.h.

The code for Bishop attacks for example is:

Code: Select all

return *&#40;bishopMagicData&#91;sq&#93;.moves+&#40;int&#41;
	      ((&#40;occupied & bishopMagicData&#91;sq&#93;.mask&#41;*bishopMagicData&#91;sq&#93;.magic&#41;>>bishopMagicData&#91;sq&#93;.shift&#41;);
This is the 64-bit version. That is going to expand into maybe a dozen machine instructions, no loops.

--Jon