1 /* init.c
2 
3    GNU Chess frontend
4 
5    Copyright (C) 2001-2011 Free Software Foundation, Inc.
6 
7    GNU Chess is based on the two research programs
8    Cobalt by Chua Kong-Sian and Gazebo by Stuart Cracraft.
9 
10    This program is free software: you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation, either version 3 of the License, or
13    (at your option) any later version.
14 
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19 
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22 
23    Contact Info:
24      bug-gnu-chess@gnu.org
25      cracraft@ai.mit.edu, cracraft@stanfordalumni.org, cracraft@earthlink.net
26 */
27 
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <unistd.h>
32 
33 #include "common.h"
34 #include "version.h"
35 #include "lexpgn.h"
36 
Initialize(void)37 void Initialize (void)
38 /**************************************************************************
39  *
40  *  The main initialization driver.
41  *
42  **************************************************************************/
43 {
44    InitLzArray ();
45    InitBitPosArray ();
46    InitMoveArray ();
47    InitRay ();
48    InitFromToRay ();
49    InitRankFileBit ();
50    InitBitCount ();
51    InitRotAtak ();
52    InitVars ();
53 }
54 
55 
56 #define NBITS 16
57 
InitLzArray(void)58 void InitLzArray (void)
59 /***************************************************************************
60  *
61  *  The lzArray is created.  This array is used when the position
62  *  of the leading non-zero bit is required.  The convention used
63  *  is that the leftmost bit is considered as position 0 and the
64  *  rightmost bit position 63.
65  *
66  ***************************************************************************/
67 {
68    int i, j, s, n;
69 
70    s = n = 1;
71    for (i = 0; i < NBITS; i++)
72    {
73       for (j = s; j < s + n; j++)
74          lzArray[j] = NBITS - 1 - i;
75       s += n;
76       n += n;
77    }
78 }
79 
80 
InitBitPosArray(void)81 void InitBitPosArray (void)
82 /***************************************************************************
83  *
84  *  BitPosArray[i] returns the bitboard whose ith bit is set to 1
85  *  and every other bits 0.  This ought to be faster than doing
86  *  shifting all the time (I think).
87  *  Also compute the NotBitPosArray = ~BitPosArray.
88  *
89  ***************************************************************************/
90 {
91    BitBoard b;
92    int i;
93 
94    b = (BitBoard) 1;
95    for (i = 63; i >= 0; i--, b <<= 1)
96    {
97       BitPosArray[i] = b;
98       NotBitPosArray[i] = ~b;
99    }
100 }
101 
102 
103 
104 /*  Data used for generating MoveArray  */
105 
106 static const int dir[8][8] =
107 {
108   { 0, 0, 0, 0, 0, 0, 0, 0 },
109   { 9, 11, 0, 0, 0, 0, 0, 0 },
110   { -21, -19, -12, -8, 8, 12, 19, 21 },
111   { -11, -9, 9, 11, 0, 0, 0, 0 },
112   { -10, -1, 1, 10, 0, 0, 0, 0 },
113   { -11, -10, -9, -1, 1, 9, 10, 11 },
114   { -11, -10, -9, -1, 1, 9, 10, 11 },
115   { -9, -11, 0, 0, 0, 0, 0, 0 }
116 };
117 static const int ndir[8] =
118 { 0, 2, 8, 4, 4, 8, 8, 2 };
119 
120 static const int map[120] =
121 {
122   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
123   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
124   -1,  0,  1,  2,  3,  4,  5,  6,  7, -1,
125   -1,  8,  9, 10, 11, 12, 13, 14, 15, -1,
126   -1, 16, 17, 18, 19, 20, 21, 22, 23, -1,
127   -1, 24, 25, 26, 27, 28, 29, 30, 31, -1,
128   -1, 32, 33, 34, 35, 36, 37, 38, 39, -1,
129   -1, 40, 41, 42, 43, 44, 45, 46, 47, -1,
130   -1, 48, 49, 50, 51, 52, 53, 54, 55, -1,
131   -1, 56, 57, 58, 59, 60, 61, 62, 63, -1,
132   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
133   -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
134 };
135 
136 
InitMoveArray(void)137 void InitMoveArray (void)
138 /***************************************************************************
139  *
140  *  Generate the move bitboards.  For e.g. the bitboard for all
141  *  the moves of a knight on f3 is given by MoveArray[knight][21].
142  *
143  ***************************************************************************/
144 {
145    int piece, fsq, tsq, f, t, n;
146    BitBoard *b;
147 
148    for (piece = pawn; piece <= bpawn; piece++)
149    {
150       for (fsq = 0; fsq < 120; fsq++)
151       {
152          if ((f = map[fsq]) == -1) continue;
153          b = &MoveArray[piece][f];
154          *b = NULLBITBOARD;
155          for (n = 0; n < ndir[piece]; n++)
156          {
157             tsq = fsq;
158             do
159             {
160                tsq += dir[piece][n];
161                if ((t = map[tsq]) != -1)
162                   SETBIT (*b, t);
163             } while (range[piece] && t != -1);
164          }
165       }
166    }
167 }
168 
169 
InitRay(void)170 void InitRay (void)
171 /**************************************************************************
172  *
173  *  For each square, there are 8 rays.  The first 4 rays are diagonals
174  *  for the bishops and the next 4  are file/rank for the rooks.
175  *  The queen uses all 8 rays.
176  *  These rays are used for move generation rather than MoveArray[].
177  *  Also initialize the directions[][] array.  directions[f][t] returns
178  *  the index into Ray[f] array allow us to find the ray in that direction.
179  *
180  **************************************************************************/
181 {
182    int piece, fsq, tsq, f, t, n, ray;
183    BitBoard *b;
184 
185    memset (directions, -1, sizeof (directions));
186    for (fsq = 0; fsq < 120; fsq++)
187    {
188       if ((f = map[fsq]) == -1) continue;
189       ray = -1;
190       for (piece = bishop; piece <= rook; piece++)
191       {
192          for (n = 0; n < ndir[piece]; n++)
193          {
194             b = &Ray[f][++ray];
195             *b = NULLBITBOARD;
196             tsq = fsq;
197             do
198             {
199                tsq += dir[piece][n];
200                if ((t = map[tsq]) != -1)
201 	       {
202                   SETBIT (*b, t);
203 	          directions[f][t] = ray;
204 	       }
205             } while (t != -1);
206          }
207       }
208    }
209 }
210 
211 
InitFromToRay(void)212 void InitFromToRay (void)
213 /***************************************************************************
214  *
215  *  The FromToRay[b2][f6] gives the diagonal ray from c3 to f6;
216  *  It also produces horizontal/vertical rays as well.   If no
217  *  ray is possible, then a 0 is returned.
218  *
219  ***************************************************************************/
220 {
221    int piece, fsq, tsq, f, t, n;
222    BitBoard *b;
223 
224    memset (FromToRay, 0, sizeof (FromToRay));
225    for (piece = bishop; piece <= rook; piece++)
226    {
227       for (fsq = 0; fsq < 120; fsq++)
228       {
229          if ((f = map[fsq]) == -1) continue;
230          for (n = 0; n < ndir[piece]; n++)
231          {
232             tsq = fsq;
233             t = map[tsq];
234             do
235             {
236                b = &FromToRay[f][t];
237                tsq += dir[piece][n];
238                if ((t = map[tsq]) != -1)
239                {
240                   SETBIT (FromToRay[f][t], t);
241                   FromToRay[f][t] |= *b;
242                }
243             } while (t != -1);
244          }
245       }
246    }
247 }
248 
249 
InitRankFileBit(void)250 void InitRankFileBit (void)
251 /***************************************************************************
252  *
253  *  RankBit[2] has all the bits on the 3rd rank 1 and others 0.
254  *  FileBit[2] has all the bits on the 3rd file 1 and others 0.
255  *
256  ***************************************************************************/
257 {
258    BitBoard b;
259    int i;
260 
261    i = 8;
262    b = (BitBoard) 255;
263    while (i--)
264    {
265       RankBit[i] = b;
266       b <<= 8;
267    }
268 
269    i = 8;
270    b = ULL(0x0101010101010101);
271    while (i--)
272    {
273       FileBit[i] = b;
274       b <<= 1;
275    }
276 }
277 
278 
InitBitCount(void)279 void InitBitCount (void)
280 /**************************************************************************
281  *
282  *  The BitCount array returns the no. of bits present in the 16 bit
283  *  input argument.  This is use for counting the number of bits set
284  *  in a BitBoard (e.g. for mobility count).
285  *
286  **************************************************************************/
287 {
288    int i, j, n;
289 
290    BitCount[0] = 0;
291    BitCount[1] = 1;
292    i = 1;
293    for (n = 2; n <= 16; n++)
294    {
295       i <<= 1;
296       for (j = i; j <= i + (i-1); j++)
297          BitCount[j] = 1 + BitCount[j - i];
298    }
299 }
300 
301 
InitRotAtak(void)302 void InitRotAtak (void)
303 /**************************************************************************
304  *
305  *  The attack tables for a normal chessboard and the rotated chess board
306  *  are calculated here.
307  *
308  **************************************************************************/
309 {
310    int sq, map, sq1, sq2;
311    int cmap[8] = { 128, 64, 32, 16, 8, 4, 2, 1 };
312    int rot1[8] = { A1, A2, A3, A4, A5, A6, A7, A8 };
313    int rot2[8] = { A1, B2, C3, D4, E5, F6, G7, H8 };
314    int rot3[8] = { A8, B7, C6, D5, E4, F3, G2, H1 };
315 
316    for (sq = A1; sq <= H1; sq++)
317    {
318       for (map = 0; map < 256; map++)
319       {
320 	 Rook00Atak[sq][map] = 0;
321 	 Rook90Atak[rot1[sq]][map] = 0;
322 	 Bishop45Atak[rot2[sq]][map] = 0;
323 	 Bishop315Atak[rot3[sq]][map] = 0;
324 	    sq1 = sq2 = sq;
325 	    while (sq1 > 0)
326 	    {
327 	       if (cmap[--sq1] & map)
328 	          break;
329 	    }
330 	    while (sq2 < 7)
331 	    {
332 	       if (cmap[++sq2] & map)
333 	          break;
334 	    }
335 	    Rook00Atak[sq][map] =
336 		FromToRay[sq][sq1] | FromToRay[sq][sq2];
337 	    Rook90Atak[rot1[sq]][map] =
338 		FromToRay[rot1[sq]][rot1[sq1]] |
339 		FromToRay[rot1[sq]][rot1[sq2]];
340 	    Bishop45Atak[rot2[sq]][map] =
341 		FromToRay[rot2[sq]][rot2[sq1]] |
342 		FromToRay[rot2[sq]][rot2[sq2]];
343 	    Bishop315Atak[rot3[sq]][map] =
344 		FromToRay[rot3[sq]][rot3[sq1]] |
345 		FromToRay[rot3[sq]][rot3[sq2]];
346       }
347    }
348 
349    for (map = 0; map < 256; map++)
350    {
351       for (sq = A2; sq <= H8; sq++)
352       {
353 	 Rook00Atak[sq][map] = Rook00Atak[sq-8][map] >> 8;
354       }
355 
356       for (sq1 = B_FILE; sq1 <= H_FILE; sq1++)
357       {
358 	 for (sq2 = 0; sq2 < 64; sq2+=8)
359 	 {
360 	    sq = sq2 + sq1;
361 	    Rook90Atak[sq][map] = Rook90Atak[sq-1][map] >> 1;
362 	 }
363       }
364 
365       for (sq1 = B1, sq2 = H7; sq1 <= H1; sq1++, sq2-=8)
366       {
367          for (sq = sq1; sq <= sq2; sq += 9)
368 	 {
369 	    Bishop45Atak[sq][map] = Bishop45Atak[sq+8][map] << 8;
370 	 }
371       }
372       for (sq1 = A2, sq2 = G8; sq1 <= A8; sq1+=8, sq2--)
373       {
374          for (sq = sq1; sq <= sq2; sq += 9)
375 	 {
376 	    Bishop45Atak[sq][map] =
377 		(Bishop45Atak[sq+1][map] & NotBitPosArray[sq1-8]) << 1;
378 	 }
379       }
380 
381       for (sq1 = H2, sq2 = B8; sq1 <= H8; sq1+=8, sq2++)
382       {
383          for (sq = sq1; sq <= sq2; sq += 7)
384 	 {
385 	    Bishop315Atak[sq][map] = Bishop315Atak[sq-8][map] >> 8;
386 	 }
387       }
388       for (sq1 = G1, sq2 = A7; sq1 >= A1; sq1--, sq2-=8)
389       {
390          for (sq = sq1; sq <= sq2; sq += 7)
391 	 {
392 	    Bishop315Atak[sq][map] =
393 		(Bishop315Atak[sq+1][map] & NotBitPosArray[sq2+8]) << 1;
394 	 }
395       }
396    }
397 }
398 
399 
InitVars(void)400 void InitVars (void)
401 /***************************************************************************
402  *
403  *  Initialize various variables, especially for new game.
404  *
405  ***************************************************************************/
406 {
407    int i;
408 
409    /* Initialize board */
410    memset (&board, 0, sizeof (board));
411    for (i = 8; i < 16; i++)
412       SETBIT (board.b[white][pawn], i);
413    SETBIT (board.b[white][rook], 0);
414    SETBIT (board.b[white][knight], 1);
415    SETBIT (board.b[white][bishop], 2);
416    SETBIT (board.b[white][queen], 3);
417    SETBIT (board.b[white][king], 4);
418    SETBIT (board.b[white][bishop], 5);
419    SETBIT (board.b[white][knight], 6);
420    SETBIT (board.b[white][rook], 7);
421    for (i = 48; i < 56; i++)
422       SETBIT (board.b[black][pawn], i);
423    SETBIT (board.b[black][rook], 56);
424    SETBIT (board.b[black][knight], 57);
425    SETBIT (board.b[black][bishop], 58);
426    SETBIT (board.b[black][queen], 59);
427    SETBIT (board.b[black][king], 60);
428    SETBIT (board.b[black][bishop], 61);
429    SETBIT (board.b[black][knight], 62);
430    SETBIT (board.b[black][rook], 63);
431 
432    board.flag |= (WCASTLE | BCASTLE);
433    RealSide = board.side = white;
434    board.ep = -1;
435    board.king[white] = E1;
436    board.king[black] = E8;
437    RealGameCnt = GameCnt = -1;
438    Game50 = 0;
439    computer = black;
440    Game[0].hashkey = HashKey;
441    board.pmaterial[white] = board.pmaterial[black] =
442       2*ValueR + 2*ValueN + 2*ValueB + ValueQ;
443    board.material[white] = board.material[black] =
444       board.pmaterial[white] + 8*ValueP;
445 
446    /* Initialize pgn values */
447    initial_comments = NULL;
448    /* Reset values; doing this again will cause a trivial memory leak
449     * when reloading PGN files as games, but it's not worth fixing. */
450    pgn_event = pgn_site =
451    pgn_date = pgn_round = pgn_white = pgn_black =
452    pgn_whiteELO = pgn_blackELO = pgn_result =
453    pgn_othertags = NULL;
454 
455 
456    UpdateFriends ();
457    UpdateCBoard ();
458    UpdateMvboard ();
459 
460    for (i = A1; i <= H8; i++)
461    {
462       if (cboard[i])
463       {
464          SETBIT (board.blockerr90, r90[i]);
465          SETBIT (board.blockerr45, r45[i]);
466          SETBIT (board.blockerr315, r315[i]);
467       }
468    }
469 
470    /* TreePtr[0] is practically unused.  TreePtr[1] points to the
471     * base of the tree.
472     */
473    TreePtr[0] = TreePtr[1] = Tree;
474 
475    /* Initialize some of the game flags */
476    SET (flags, USEHASH);
477    SET (flags, USENULL);
478    SearchTime = 5;
479    board.castled[white] = board.castled[black] = false;
480    phase = PHASE;
481 }
482 
483 
NewPosition(void)484 void NewPosition (void)
485 /****************************************************************************
486  *
487  *  Reset some flags for a new game/position.
488  *
489  ****************************************************************************/
490 {
491    CLEAR (flags, ENDED);
492    Game50 = 0;
493    RealGameCnt = GameCnt = -1;
494    Game[0].hashkey = HashKey;
495    ExchCnt[white] = ExchCnt[black] = 0;
496 }
497