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

📄 init.c

📁 gun C 环境下编写的
💻 C
📖 第 1 页 / 共 2 页
字号:
/* GNU Chess 5.0 - init.c - initialization of variables code
   Copyright (c) 1999-2002 Free Software Foundation, Inc.

   GNU Chess is based on the two research programs 
   Cobalt by Chua Kong-Sian and Gazebo by Stuart Cracraft.

   GNU Chess is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   GNU Chess is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with GNU Chess; see the file COPYING.  If not, write to
   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.

   Contact Info: 
     bug-gnu-chess@gnu.org
     cracraft@ai.mit.edu, cracraft@stanfordalumni.org, cracraft@earthlink.net
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>

#include "common.h"
#include "version.h"
#include "lexpgn.h"

void Initialize (void)
/**************************************************************************
 *
 *  The main initialization driver.
 *
 **************************************************************************/
{
   InitLzArray ();
   InitBitPosArray ();
   InitMoveArray ();
   InitRay ();
   InitFromToRay (); 
   InitRankFileBit ();
   InitPassedPawnMask ();
   InitIsolaniMask ();
   InitSquarePawnMask ();
   InitBitCount ();
   InitRotAtak ();
   InitRandomMasks ();
   InitDistance ();
   InitVars ();
   InitHashCode ();
   InitHashTable ();
   CalcHashKey ();
   InitInput();

}


void InitFICS (void)
{
   if (flags & XBOARD) {
     printf ("tellics shout Greetings from %s %s. Ready for a game.\n", PROGRAM, VERSION);
     printf ("tellics set 1 %s %s.\n",PROGRAM,VERSION);
   }

}

#define NBITS 16

void InitLzArray (void)
/***************************************************************************
 *
 *  The lzArray is created.  This array is used when the position
 *  of the leading non-zero bit is required.  The convention used
 *  is that the leftmost bit is considered as position 0 and the
 *  rightmost bit position 63.
 *
 ***************************************************************************/
{
   int i, j, s, n;

   s = n = 1;
   for (i = 0; i < NBITS; i++)
   {
      for (j = s; j < s + n; j++)
         lzArray[j] = NBITS - 1 - i;
      s += n;
      n += n;
   }
}


void InitBitPosArray (void)
/***************************************************************************
 *
 *  BitPosArray[i] returns the bitboard whose ith bit is set to 1 
 *  and every other bits 0.  This ought to be faster than doing
 *  shifting all the time (I think).  
 *  Also compute the NotBitPosArray = ~BitPosArray.
 *
 ***************************************************************************/
{
   BitBoard b;
   int i;

   b = (BitBoard) 1;  
   for (i = 63; i >= 0; i--, b <<= 1)
   {
      BitPosArray[i] = b;
      NotBitPosArray[i] = ~b;
   }
}
 


/*  Data used for generating MoveArray  */

static const int dir[8][8] =
{
  { 0, 0, 0, 0, 0, 0, 0, 0 },
  { 9, 11, 0, 0, 0, 0, 0, 0 },
  { -21, -19, -12, -8, 8, 12, 19, 21 },
  { -11, -9, 9, 11, 0, 0, 0, 0 },
  { -10, -1, 1, 10, 0, 0, 0, 0 },
  { -11, -10, -9, -1, 1, 9, 10, 11 },
  { -11, -10, -9, -1, 1, 9, 10, 11 },
  { -9, -11, 0, 0, 0, 0, 0, 0 }
};
static const int ndir[8] = 
{ 0, 2, 8, 4, 4, 8, 8, 2 };

static const int map[120] =
{
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  -1,  0,  1,  2,  3,  4,  5,  6,  7, -1,
  -1,  8,  9, 10, 11, 12, 13, 14, 15, -1,
  -1, 16, 17, 18, 19, 20, 21, 22, 23, -1,
  -1, 24, 25, 26, 27, 28, 29, 30, 31, -1,
  -1, 32, 33, 34, 35, 36, 37, 38, 39, -1,
  -1, 40, 41, 42, 43, 44, 45, 46, 47, -1,
  -1, 48, 49, 50, 51, 52, 53, 54, 55, -1,
  -1, 56, 57, 58, 59, 60, 61, 62, 63, -1,
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 
};


void InitMoveArray (void)
/***************************************************************************
 * 
 *  Generate the move bitboards.  For e.g. the bitboard for all
 *  the moves of a knight on f3 is given by MoveArray[knight][21].
 *
 ***************************************************************************/
{
   int piece, fsq, tsq, f, t, n;
   BitBoard *b;

   for (piece = pawn; piece <= bpawn; piece++)
   {
      for (fsq = 0; fsq < 120; fsq++)
      {
         if ((f = map[fsq]) == -1) continue;
         b = &MoveArray[piece][f];
         *b = NULLBITBOARD;
         for (n = 0; n < ndir[piece]; n++)
         {
            tsq = fsq;
            do
            {
               tsq += dir[piece][n];
               if ((t = map[tsq]) != -1)
                  SETBIT (*b, t);
            } while (range[piece] && t != -1);
         }
      }
   }
}


void InitRay (void)
/**************************************************************************
 *
 *  For each square, there are 8 rays.  The first 4 rays are diagonals 
 *  for the bishops and the next 4  are file/rank for the rooks.  
 *  The queen uses all 8 rays.
 *  These rays are used for move generation rather than MoveArray[].
 *  Also initialize the directions[][] array.  directions[f][t] returns
 *  the index into Ray[f] array allow us to find the ray in that direction.
 *
 **************************************************************************/
{
   int piece, fsq, tsq, f, t, n, ray;
   BitBoard *b;

   memset (directions, -1, sizeof (directions));
   for (fsq = 0; fsq < 120; fsq++)
   {
      if ((f = map[fsq]) == -1) continue;
      ray = -1;
      for (piece = bishop; piece <= rook; piece++)
      {
         for (n = 0; n < ndir[piece]; n++)
         {
            b = &Ray[f][++ray];
            *b = NULLBITBOARD;
            tsq = fsq;
            do
            {
               tsq += dir[piece][n];
               if ((t = map[tsq]) != -1)
	       {
                  SETBIT (*b, t);
	          directions[f][t] = ray;
	       }
            } while (t != -1);
         }
      }
   }
}


void InitFromToRay (void)
/***************************************************************************
 *
 *  The FromToRay[b2][f6] gives the diagonal ray from c3 to f6;
 *  It also produces horizontal/vertical rays as well.   If no
 *  ray is possible, then a 0 is returned.
 *
 ***************************************************************************/
{
   int piece, fsq, tsq, f, t, n;
   BitBoard *b;

   memset (FromToRay, 0, sizeof (FromToRay));
   for (piece = bishop; piece <= rook; piece++)
   {
      for (fsq = 0; fsq < 120; fsq++)
      {
         if ((f = map[fsq]) == -1) continue;
         for (n = 0; n < ndir[piece]; n++)
         {
            tsq = fsq;
            t = map[tsq];
            do
            {
               b = &FromToRay[f][t];
               tsq += dir[piece][n];         
               if ((t = map[tsq]) != -1)
               {
                  SETBIT (FromToRay[f][t], t);
                  FromToRay[f][t] |= *b;
               }
            } while (t != -1);
         }
      }
   }
}


void InitRankFileBit (void)
/***************************************************************************
 *
 *  RankBit[2] has all the bits on the 3rd rank 1 and others 0.
 *  FileBit[2] has all the bits on the 3rd file 1 and others 0.
 *
 ***************************************************************************/
{
   BitBoard b;
   int i;

   i = 8;
   b = (BitBoard) 255;
   while (i--)
   {
      RankBit[i] = b;
      b <<= 8;
   }
   
   i = 8;
   b = ULL(0x0101010101010101);
   while (i--)
   {
      FileBit[i] = b;
      b <<= 1;
   }
}


void InitRandomMasks (void)
{
  mask_kr_trapped_w[0]=BitPosArray[H2];
  mask_kr_trapped_w[1]=BitPosArray[H1]|BitPosArray[H2];
  mask_kr_trapped_w[2]=BitPosArray[G1]|BitPosArray[H1]|BitPosArray[H2];
  mask_qr_trapped_w[0]=BitPosArray[A2];
  mask_qr_trapped_w[1]=BitPosArray[A1]|BitPosArray[A2];
  mask_qr_trapped_w[2]=BitPosArray[A1]|BitPosArray[B1]|BitPosArray[A2];
  mask_kr_trapped_b[0]=BitPosArray[H7];
  mask_kr_trapped_b[1]=BitPosArray[H8]|BitPosArray[H7];
  mask_kr_trapped_b[2]=BitPosArray[H8]|BitPosArray[G8]|BitPosArray[H7];
  mask_qr_trapped_b[0]=BitPosArray[A7];
  mask_qr_trapped_b[1]=BitPosArray[A8]|BitPosArray[A7];
  mask_qr_trapped_b[2]=BitPosArray[A8]|BitPosArray[B8]|BitPosArray[A7];
}

void InitPassedPawnMask (void)
/**************************************************************************
 *
 *  The PassedPawnMask variable is used to determine if a pawn is passed.
 *  This mask is basically all 1's from the square in front of the pawn to
 *  the promotion square, also duplicated on both files besides the pawn
 *  file.  Other bits will be set to zero.
 *  E.g. PassedPawnMask[white][b3] = 1's in a4-c4-c8-a8 rect, 0 otherwise.
 *
 **************************************************************************/
{
   unsigned int sq;

   memset (PassedPawnMask, 0, sizeof (PassedPawnMask));

   /*  Do for white pawns first */
   for (sq = 0; sq < 64; sq++)
   {
      PassedPawnMask[white][sq] = Ray[sq][7];
      if (ROW(sq) != 0)
         PassedPawnMask[white][sq] |= Ray[sq-1][7];
      if (ROW(sq) != 7)
         PassedPawnMask[white][sq] |= Ray[sq+1][7];
   }

   /*  Do for black pawns */
   for (sq = 0; sq < 64; sq++)
   {
      PassedPawnMask[black][sq] = Ray[sq][4];
      if (ROW(sq) != 0)
         PassedPawnMask[black][sq] |= Ray[sq-1][4];
      if (ROW(sq) != 7)
         PassedPawnMask[black][sq] |= Ray[sq+1][4];
   }
}


void InitIsolaniMask (void)
/**************************************************************************
 *
 *  The IsolaniMask variable is used to determine if a pawn is an isolani.
 *  This mask is basically all 1's on files beside the file the pawn is on.
 *  Other bits will be set to zero.
 *  E.g. IsolaniMask[d-file] = 1's in c-file & e-file, 0 otherwise.
 *  IMPORTANT:!!!!
 *  Make sure this routine is called AFTER InitRankFileBit().
 *
 **************************************************************************/
{
   int i;

   IsolaniMask[0] = FileBit[1];
   IsolaniMask[7] = FileBit[6];
   for (i = 1; i <= 6; i++)
      IsolaniMask[i] = FileBit[i-1] | FileBit[i+1];
      
}


void InitSquarePawnMask (void)
/**************************************************************************
 *
 *  The SquarePawnMask is used to determine if a king is in the square of
 *  the passed pawn and is able to prevent it from queening.  
 *  Caveat:  Pawns on 2nd rank have the same mask as pawns on the 3rd rank
 *  as they can advance 2 squares.
 *
 **************************************************************************/
{
   unsigned int sq;
   int len, i, j;

   memset (SquarePawnMask, 0, sizeof (PassedPawnMask));
   for (sq = 0; sq < 64; sq++)
   {
      /*  White mask  */
      len = 7 - RANK (sq);
      i = MAX (sq & 56, sq - len);
      j = MIN (sq | 7, sq + len);
      while (i <= j)
      {
         SquarePawnMask[white][sq] |= (BitPosArray[i] | FromToRay[i][i|56]);
         i++;
      }

      /*  Black mask  */
      len = RANK (sq);

⌨️ 快捷键说明

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