Computer Chess Club Archives


Search

Terms

Messages

Subject: Here's the actual code (LONG)

Author: Scott Gasch

Date: 11:37:34 01/14/02

Go up one level in this thread


Here's the code if anyone is interested:

Original C code:

void
GetAttacks(SEE_LIST *pList,
           POSITION *pos,
           COORD cSquare,
           unsigned int iSide)
{
    register int x;
    PIECE p;
    COORD c;
    int iIndex;
    register COORD cBlockIndex;
    int iDelta;

    ASSERT(pList);
    ASSERT(pos);
    ASSERT(ONBOARD(cSquare));
    ASSERT((WHITE == iSide) || (BLACK == iSide));

    pList->iCount = 0;
    ASSERT(pos->iPawnCount[iSide] >= 0);
    ASSERT(pos->iPawnCount[iSide] <= 8);

    if (iSide == WHITE)
    {
        c = cSquare + 15;
        p = pos->pSquare[c];
        if ((ONBOARD(c) && (PIECE_PIECE(p) == WHITE_PAWN)))
        {
            pList->data[0].pPiece = p;
            pList->data[0].cLoc = c;
            pList->data[0].iVal = VALUE_PAWN;
            pList->iCount = 1;
        }
        c = cSquare + 17;
        p = pos->pSquare[c];
        if ((ONBOARD(c) && (PIECE_PIECE(p) == WHITE_PAWN)))
        {
            pList->data[pList->iCount].pPiece = p;
            pList->data[pList->iCount].cLoc = c;
            pList->data[pList->iCount].iVal = VALUE_PAWN;
            pList->iCount++;
        }
    }
    else
    {
        c = cSquare - 17;
        p = pos->pSquare[c];
        if ((ONBOARD(c) && (PIECE_PIECE(p) == BLACK_PAWN)))
        {
            pList->data[0].pPiece = p;
            pList->data[0].cLoc = c;
            pList->data[0].iVal = VALUE_PAWN;
            pList->iCount = 1;
        }
        c = cSquare - 15;
        p = pos->pSquare[c];
        if ((ONBOARD(c) && (PIECE_PIECE(p) == BLACK_PAWN)))
        {
            pList->data[pList->iCount].pPiece = p;
            pList->data[pList->iCount].cLoc = c;
            pList->data[pList->iCount].iVal = VALUE_PAWN;
            pList->iCount++;
        }
    }

    ASSERT(pos->iNonPawnCount[iSide] >= 1);
    ASSERT(pos->iNonPawnCount[iSide] <= 16);

    for (x = pos->iNonPawnCount[iSide] - 1;
         x >= 0;
         x--)
    {
        c = pos->cNonPawns[iSide][x];
        ASSERT(KILLED != c);
        ASSERT(ONBOARD(c));

        p = pos->pSquare[c];
        ASSERT(p && !IS_PAWN(p));
        ASSERT(COLOR(p) == iSide);

        iIndex = c - cSquare + 128;

        //
        // If there is no way for that kind of piece to get to this
        // square then keep looking.
        //
        if (0 == (g_VectorDeltaTable[iIndex].iVector[iSide] &
                  (1 << (PIECE_PIECE(p) >> 1))))
        {
            continue;
        }

        //
        // Knights and kings do not slide so if they can get there we do
        // not have to look for blockers.
        //
        if ((IS_KNIGHT(p)) ||
            (IS_KING(p)))
        {
            pList->data[pList->iCount].pPiece = p;
            pList->data[pList->iCount].cLoc = c;
            pList->data[pList->iCount].iVal = PIECE_VALUE(p);
            pList->iCount++;
            continue;
        }

        //
        // Check to see if there is a piece in the path from cSquare to
        // c that blocks the attack.
        //
        iDelta = -g_VectorDeltaTable[iIndex].iDelta;
#ifdef PARANOID
        if (c == cSquare)
        {
            ASSERT(iDelta == 0);
        }
        else
        {
            if (RANK(c) == RANK(cSquare))
            {
                if (c < cSquare)
                {
                    ASSERT(iDelta == -1);
                }
                else
                {
                    ASSERT(iDelta == +1);
                }
            }
            else if (FILE(c) == FILE(cSquare))
            {
                if (c < cSquare)
                {
                    ASSERT(iDelta == -16);
                }
                else
                {
                    ASSERT(iDelta == +16);
                }
            }
        }
#endif

        for (cBlockIndex = cSquare + iDelta;
             cBlockIndex != c;
             cBlockIndex += iDelta)
        {
            if (!IS_EMPTY(pos->pSquare[cBlockIndex]))
            {
                goto done;
            }
        }

        //
        // Nothing in the way.
        //
        pList->data[pList->iCount].pPiece = p;
        pList->data[pList->iCount].cLoc = c;
        pList->data[pList->iCount].iVal = PIECE_VALUE(p);
        pList->iCount++;
 done:
        ;
    }
}

Here's my assembly version:

void
GetAttacks(SEE_LIST *pList,
           POSITION *pos,
           COORD cSquare,
           unsigned int iSide)
{
    int x;
    COORD c;
    int iIndex;

    ASSERT(pList);
    ASSERT(pos);
    ASSERT(ONBOARD(cSquare));
    ASSERT((WHITE == iSide) || (BLACK == iSide));
    ASSERT(pos->iPawnCount[iSide] >= 0);
    ASSERT(pos->iPawnCount[iSide] <= 8);

    __asm
    {
        // pList->iCount = 0;
        mov         ebx,dword ptr [pList]
        mov         dword ptr [ebx],0

//side_is_white:
        // if (iSide == WHITE)
        // {
        cmp         dword ptr [iSide],1
        jne         side_is_black

//try_white_1:
        //
        // Test c+15 for white pawnness
        //

        // c = cSquare + 15;
        mov         ecx,dword ptr [cSquare]
        add         ecx,0Fh
        // if (!ONBOARD(c)) goto try other white pawn
        test        ecx,88h
        jne         try_white_2

        // p = pos->pSquare[c];
        mov         eax,dword ptr [pos]
        mov         edx,dword ptr [eax+ecx*4]

        // if ((PIECE_PIECE(p) != WHITE_PAWN)) goto try other white pawn
        mov         eax,edx
        and         eax,0Fh
        cmp         eax,3
        jne         try_white_2

        // if we get here there's a white pawn at c+17

        // pList->pPiece[pList->iCount] = p;
        mov         dword ptr [ebx+4],edx

        // pList->cLoc[pList->iCount] = c;
        mov         dword ptr [ebx+8],ecx

        // pList->iVal[pList->iCount] = VALUE_PAWN;
        mov         dword ptr [ebx+0Ch],64h

        // pList->iCount++;
        mov         dword ptr [ebx],1

try_white_2:
        //
        // test c + 17 for white pawnness
        //

        // c = cSquare + 17;
        add         ecx,2

        // if (!ONBOARD(c)) goto done testing pawns
        test        ecx,88h
        jne         done_pawns

        // p = pos->pSquare[c];
        mov         eax,dword ptr [pos]
        mov         edx,dword ptr [eax+ecx*4]

        // if (PIECE_PIECE(p) != WHITE_PAWN) goto done testing pawns
        mov         eax,edx
        and         eax,0Fh
        cmp         eax,3
        jne         done_pawns

        // if we get here the piece at c+15 is a white pawn

        // pList->pPiece[pList->iCount] = p;
        mov         eax,dword ptr [ebx]
        imul        eax,eax,0Ch
        mov         dword ptr [ebx+eax+4],edx

        // pList->cLoc[pList->iCount] = c;
        mov         dword ptr [ebx+eax+8],ecx

        // pList->iVal[pList->iCount] = VALUE_PAWN;
        mov         dword ptr [ebx+eax+0Ch],64h

        // pList->iCount++;
        mov         eax,dword ptr [ebx]
        add         eax,1
        mov         dword ptr [ebx],eax

        // goto done testing pawns
        jmp done_pawns

side_is_black:
        // c = cSquare - 17;
        mov         ecx,dword ptr [cSquare]
        sub         ecx,11h

        // if (!ONBOARD(c)) goto test other black pawn
        test        ecx,88h
        jne         try_black_2

        // p = pos->pSquare[c];
        mov         eax,dword ptr [pos]
        mov         edx,dword ptr [eax+ecx*4]

        // if (PIECE_PIECE(p) != BLACK_PAWN) goto test other black pawn
        mov         eax,edx
        and         eax,0Fh
        cmp         eax,2
        jne         try_black_2

        // if we get here the piece at c-17 is a black pawn

        // pList->pPiece[pList->iCount] = p;
        mov         dword ptr [ebx+4],edx

        // pList->cLoc[pList->iCount] = c;
        mov         dword ptr [ebx+8],ecx

        // pList->iVal[pList->iCount] = VALUE_PAWN;
        mov         dword ptr [ebx+0Ch],64h

        // pList->iCount++;
        mov         dword ptr [ebx],1

try_black_2:
        // c = cSquare - 15;
        add         ecx,2

        // if (!ONBOARD(c)) goto done with pawns
        test        ecx,88h
        jne         done_pawns

        // p = pos->pSquare[c];
        mov         eax,dword ptr [pos]
        mov         edx,dword ptr [eax+ecx*4]

        // if (PIECE_PIECE(p) != BLACK_PAWN) goto done with pawns
        mov         eax,edx
        and         eax,0Fh
        cmp         eax,2
        jne         done_pawns

        // if we get here the piece at c-15 is a black pawn

        // pList->pPiece[pList->iCount] = p;
        mov         eax,dword ptr [ebx]
        imul        eax,eax,0Ch
        mov         dword ptr [ebx+eax+4],edx

        // pList->cLoc[pList->iCount] = c;
        mov         dword ptr [ebx+eax+8],ecx

        // pList->iVal[pList->iCount] = VALUE_PAWN;
        mov         dword ptr [ebx+eax+0Ch],64h

        // pList->iCount++;
        mov         eax,dword ptr [ebx]
        add         eax,1
        mov         dword ptr [ebx],eax

done_pawns:
        //
        // Do pieces now
        //

        // for (x = pos->iNonPawnCount[iSide] - 1;
        //      x >= 0;
        //      x--)
        // {
        mov         eax,dword ptr [iSide]
        mov         ecx,dword ptr [pos]
        mov         ebx,dword ptr [ecx+eax*4+308h]
        mov         dword ptr [x], ebx

loop_continue:
        mov         ebx,dword ptr [x]
        sub         ebx,1

//loop_cond:
        cmp         ebx,0
        jl          done
        mov         dword ptr [x],ebx

        // c = pos->cNonPawns[iSide][x];
        mov         ecx,dword ptr [iSide]
        shl         ecx,6
        mov         edx,dword ptr [pos]
        lea         ecx,[edx+ecx+288h]
        mov         ecx,dword ptr [ecx+ebx*4]
        mov         dword ptr [c],ecx

        // p = pos->pSquare[c];
        mov         ebx,dword ptr [edx+ecx*4]

        // iIndex = c - cSquare + 128;
        sub         ecx,dword ptr [cSquare]
        add         ecx,80h
        mov         dword ptr [iIndex],ecx

        //
        // If there is no way for that kind of piece to get to this
        // square then keep looking.
        //
        // if (0 == (g_VectorDeltaTable[iIndex].iVector[iSide] &
        //          (1 << (PIECE_PIECE(p) >> 1)))) continue;
        mov         edx,dword ptr [iSide]
        xor         eax,eax
        mov         al,byte ptr [edx+ecx*4+g_VectorDeltaTable]
        mov         ecx,ebx
        and         ecx,0Fh
        shr         ecx,1
        mov         edx,1
        shl         edx,cl
        and         eax,edx
        test        eax,eax
        je          loop_continue

        //
        // Knights and kings do not slide so if they can get there we do
        // not have to look for blockers.
        //
        // if ((p & 0x6) == 0x4)
        // {
        mov         eax,ebx
        and         eax,6
        cmp         eax,4
        jne         not_knight_king

        // pList->pPiece[pList->iCount] = p;
        mov         edx,dword ptr [pList]
        mov         eax,dword ptr [edx]
        imul        eax,eax,0Ch
        mov         dword ptr [edx+eax+4],ebx

        // pList->cLoc[pList->iCount] = c;
        mov         ecx,dword ptr [c]
        mov         dword ptr [edx+eax+8],ecx

        // pList->iVal[pList->iCount] = PIECE_VALUE(p);
        mov         ecx,ebx
        and         ecx,0Eh
        shl         ecx,3
        mov         ecx,dword ptr g_PieceData[ecx]
        mov         dword ptr [edx+eax+0Ch],ecx

        // pList->iCount++;
        mov         eax,dword ptr [edx]
        add         eax,1
        mov         dword ptr [edx],eax

        // continue;
        jmp loop_continue;

not_knight_king:
        //
        // Check to see if there is a piece in the path from cSquare to
        // c that blocks the attack.
        //
        // iDelta = g_VectorDeltaTable[iIndex].iNegDelta;
        mov         eax,dword ptr [iIndex]
        movsx       ecx,byte ptr [eax*4+g_VectorDeltaTable+3]

        // cBlockIndex = cSquare + iDelta
        mov         eax,dword ptr [cSquare]


block_loop:
        add         eax,ecx

        // if (cBlockIndex != c)
        // {
        cmp         eax,dword ptr [c]
        je          nothing_blocks

        //     if (IS_EMPTY(pos->pSquare[cBlockIndex]))
        //     {
        mov         edx,dword ptr [pos]
        cmp         dword ptr [edx+eax*4],0
        jne         loop_continue

        // goto cond
        jmp         block_loop

nothing_blocks:
        //
        // nothing in the way, add to the list
        //
        // pList->pPiece[pList->iCount] = p;
        mov         eax,dword ptr [pList]
        mov         ecx,dword ptr [eax]
        imul        ecx,ecx,0Ch
        mov         dword ptr [eax+ecx+4],ebx

        // pList->iVal[pList->iCount] = PIECE_VALUE(p);
        and         ebx,0Eh
        shl         ebx,3
        mov         ebx,dword ptr g_PieceData[ebx]
        mov         dword ptr [eax+ecx+0Ch],ebx

        // pList->cLoc[pList->iCount] = c;
        mov         ebx,dword ptr [c]
        mov         dword ptr [eax+ecx+8],ebx

        // pList->iCount++;
        mov         ecx,dword ptr [eax]
        add         ecx,1
        mov         dword ptr [eax],ecx

        // next x
        jmp         loop_continue
    }
done:
    ;
}



This page took 0 seconds to execute

Last modified: Thu, 15 Apr 21 08:11:13 -0700

Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.