⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 movgen.cpp

📁 将UCOS与UCGUI整合到一起,并在BORLAND C++上运行通过的源程序.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// ObjectWindows - (C) Copyright 1992 by Borland International

#include <math.h>
#include "wcdefs.h"
#include "externs.h"

/*
 *  Globals
 */

static ATTACKTABTYPE attack[240];
ATTACKTABTYPE *AttackTab = &attack[120];
SETOFPIECE BitTab[7] = {0, 1, 2, 4, 8, 0x10, 0x20};
int DirTab[8] = { 1, -1, 0x10, -0x10, 0x11, -0x11, 0x0f, -0x0f};
int KnightDir[8] = {0x0E, -0x0E, 0x12, -0x12, 0x1f, -0x1f, 0x21, -0x21};
int PawnDir[2] = {0x10, -0x10};
MOVETYPE Next;
int BufCount, BufPnt;
MOVETYPE Buffer[81];
CASTMOVETYPE  CastMove[2][2] = { {{2, 4}, {6, 4}}, {{0x72, 0x74}, {0x76, 0x74}} };


void CalcAttackTab(void)
{
    DIRTYPE dir;
    int sq;
    unsigned char i;

    for (sq = -0x77; sq <= 0x77; sq++)
    {
        AttackTab[sq].pieceset = 0;
        AttackTab[sq].direction = 0;        
    }
    for (dir = 7; dir >=0; dir--)
    {
        for (i = 1; i < 8; i++)
        {
            if (dir < 4)
                AttackTab[DirTab[dir]*i].pieceset = BitTab[queen]+BitTab[rook];
            else
                AttackTab[DirTab[dir]*i].pieceset = BitTab[queen]+BitTab[bishop];
            AttackTab[DirTab[dir]*i].direction = DirTab[dir];
        }
        AttackTab[DirTab[dir]].pieceset += BitTab[king];
        AttackTab[KnightDir[dir]].pieceset = BitTab[knight];
        AttackTab[KnightDir[dir]].direction = KnightDir[dir];
    }
}


/*
 *  calculate whether apiece placed on asquare attacks the square
 */

short PieceAttacks(PIECETYPE apiece, COLORTYPE acolor,
                     SQUARETYPE asquare, SQUARETYPE square)
{
    EDGESQUARETYPE sq;
    int x;

    x = square - asquare;
    if (apiece == pawn)   /*  pawn attacks  */
        return (abs(x - PawnDir[acolor]) == 1);
    /*  other attacks: can the piece move to the square?  */
    else if (AttackTab[x].pieceset & BitTab[apiece])
    {
        if (apiece == king || apiece == knight)
            return 1;
        else
        {
        /*  are there any blocking pieces in between?  */
            sq = asquare;
            do
            {
                sq += AttackTab[x].direction;
            } while (sq != square && Board[sq].piece == empty );
            return (sq == square);
        }
    }
    else
        return 0;
}


/*
 *  calculate whether acolor attacks the square with at pawn
 */

short PawnAttacks(COLORTYPE acolor, SQUARETYPE square)
{
    EDGESQUARETYPE sq;

    sq = square - PawnDir[acolor] - 1;  /*  left square  */
    if (!(sq & 0x88))
        if (Board[sq].piece == pawn && Board[sq].color == acolor)
            return 1;
    sq += 2;   /*  right square  */
    if (!(sq & 0x88))
        if (Board[sq].piece == pawn && Board[sq].color == acolor)
            return 1;
    return 0;
}


/*
 *  Calculates whether acolor attacks the square
 */

short Attacks(COLORTYPE acolor, SQUARETYPE square)
{
    INDEXTYPE i;

    if (PawnAttacks(acolor, square))    /*  pawn attacks  */
        return 1;
    /*  Other attacks:  try all pieces, starting with the smallest  */
    for (i = OfficerNo[acolor]; i >= 0; i--)
        if (PieceTab[acolor][i].ipiece != empty)
            if (PieceAttacks(PieceTab[acolor][i].ipiece, acolor,
                    PieceTab[acolor][i].isquare, square))
                return 1;
    return 0;
}


/*
 *  check whether inpiece is placed on square and has never moved
 */

short Check(SQUARETYPE square, PIECETYPE inpiece, COLORTYPE incolor)
{
    DEPTHTYPE dep;

    if(Board[square].piece == inpiece && Board[square].color == incolor)
    {
        dep = Depth - 1;
        while (MovTab[dep].movpiece != empty)
        {
            if (MovTab[dep].new1 == square)
                return 0;
            dep--;
        }
        return 1;
    }
    return 0;
}


/*
 *  Calculate whether incolor can castle
 */

void CalcCastling(COLORTYPE incolor,  CASTDIRTYPE *cast)
{
    SQUARETYPE square = 0;

    if (incolor == black) square = 0x70;
    *cast = zero;
    if (Check(square + 4, king, incolor))  /*  check king  */
    {
        if (Check(square, rook, incolor))
            ((int)*cast) += lng;  /*  check a-rook  */
        if (Check(square + 7, rook, incolor))
            ((int)*cast) += shrt;  /*  check h-rook  */
    }
}


/*
 *  check if move is a pawn move or a capture
 */

inline short RepeatMove(MOVETYPE *move)
{
    return (move->movpiece != empty && move->movpiece != pawn &&
              move->content == empty && !move->spe);
}

/****************************************************************************/

/*
 *  Count the number of moves since last capture or pawn move
 *  The game is a draw when fiftymovecnt = 100
 */

FIFTYTYPE FiftyMoveCnt(void)
{
    FIFTYTYPE cnt = 0;

    while (RepeatMove(&MovTab[Depth - cnt]))
        cnt++;
    return cnt;
}


/*
 *  Calculate how many times the position has occured before
 *  The game is a draw when repetition = 3;
 *  movetab[back..Depth] contains the previous moves
 *  When immediate is set, only immediate repetion is checked
 */

REPEATTYPE Repetition(short immediate)
{
    DEPTHTYPE lastdep, compdep, tracedep, checkdep, samedepth;
    SQUARETYPE tracesq, checksq;
    REPEATTYPE repeatcount;

    repeatcount = 1;
    lastdep = samedepth = Depth + 1;    /*  current postion  */
    compdep = samedepth - 4;            /*  First position to compare  */

    /*  MovTab[lastdep..Depth] contains previous relevant moves  */
    while (RepeatMove(&MovTab[lastdep - 1]) && (compdep < lastdep ||
                 !immediate))
        lastdep--;
    if (compdep < lastdep)
        return repeatcount;
    checkdep = samedepth;
    do
    {
        checkdep--;
        checksq = MovTab[checkdep].new1;
        for (tracedep = checkdep + 2; tracedep < samedepth; tracedep += 2)
            if (MovTab[tracedep].old == checksq) goto TEN;

        /*  Trace the move backward to see if it has been 'undone' earlier  */
        tracedep = checkdep;
        tracesq = MovTab[tracedep].old;
        do
        {
            if (tracedep-2 < lastdep) return repeatcount;
            tracedep -= 2;
            /*  Check if piece has been moved before  */
            if (tracesq == MovTab[tracedep].new1) tracesq =
                    MovTab[tracedep].old;
        } while (tracesq != checksq || tracedep > compdep + 1);
        if (tracedep < compdep)    /*  Adjust evt. compdep  */
        {
            compdep = tracedep;
            if ((samedepth - compdep) % 2 == 1)
            {
                if (compdep == lastdep) return repeatcount;
                compdep --;
            }
            checkdep = samedepth;
        }
        /*  All moves between SAMEDEP and compdep have been checked,
            so a repetition is found  */
TEN :   if (checkdep <= compdep)
        {
            repeatcount++;
            if (compdep - 2 < lastdep) return repeatcount;
            checkdep = samedepth = compdep;
            compdep -= 2;
        }
    } while (1);
}


/*
 *  Test whether a move is possible
 *
 *  On entry:
 *    Move contains a full description of a move, which
 *    has been legally generated in a different position.
 *    MovTab[Depth - 1] contains last performed move.
 *
 *  On exit:
 *    KillMovGen indicates whether the move is possible
 */

short KillMovGen(MOVETYPE *move)
{
    SQUARETYPE castsq;
    PIECETYPE promote;
    CASTDIRTYPE castdir;
    CASTTYPE cast;
    short killmov;

    killmov = 0;
    if (move->spe && (move->movpiece == king))
    {
        CalcCastling(Player, &cast);     /*  Castling  */
        if (move->new1 > move->old)
            castdir = shrt;
        else
            castdir = lng;

        if (cast & castdir)    /*  Has king or rook moved before  */
        {
            castsq = (int)((move->new1 + move->old) / 2);
            /*  Are the squares empty ?  */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -