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