📄 init.c
字号:
/* 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 16void 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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -