Line data Source code
1 : //////////////////////////////////////////////////////////////////////
2 : //
3 : // FILE: common.h
4 : // Common macros, structures and constants.
5 : //
6 : // Part of: Scid (Shane's Chess Information Database)
7 : // Version: 3.6.6
8 : //
9 : // Notice: Copyright (c) 2000-2004 Shane Hudson. All rights reserved.
10 : //
11 : // Author: Shane Hudson (sgh@users.sourceforge.net)
12 : // Copyright (c) 2006-2007 Pascal Georges
13 : //
14 : //////////////////////////////////////////////////////////////////////
15 :
16 : #ifndef SCID_COMMON_H
17 : #define SCID_COMMON_H
18 :
19 : #include <cstddef>
20 : #if defined(_MSC_VER) && _MSC_VER <= 1600
21 : typedef unsigned __int8 uint8_t;
22 : typedef unsigned __int16 uint16_t;
23 : typedef unsigned __int32 uint32_t;
24 : typedef unsigned __int64 uint64_t;
25 : typedef __int32 int32_t;
26 : #else
27 : #include <stdint.h>
28 : #endif // _MSC_VER <= 1600
29 :
30 : #include "error.h"
31 :
32 : //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
33 : // CONSTANTS:
34 :
35 : // Buffer sizes
36 : #define BBUF_SIZE 256000 //120000
37 :
38 : typedef unsigned short versionT;
39 :
40 : // Version: div by 100 for major number, modulo 100 for minor number
41 : // so 109 = 1.9, 110 = 1.10, etc.
42 :
43 : const versionT SCID_VERSION = 400; // Current file format version = 4.0
44 : const versionT SCID_OLDEST_VERSION = 300; // Oldest readable file format: 3.0
45 :
46 : const char SCID_VERSION_STRING[] = "4.7.0"; // Current Scid version
47 : const char SCID_WEBSITE[] = "http://scid.sourceforge.net/";
48 :
49 : const char PGN_SUFFIX[] = ".pgn";
50 :
51 :
52 : //////////////////////////////////////////////////////////////////////
53 : // ASSERT macro: asserts an expression. Differs from the standard
54 : // assert in that it does NOT print the expression (this is a waste,
55 : // if an assert fails you can go to the code to see why) and that
56 : // it MUST be a statement, not part of a larger expression.
57 : // Adapted from the book "Writing Solid Code".
58 : #include <assert.h>
59 : #define ASSERT(f) assert(f)
60 :
61 :
62 : // Bit Manipulations
63 :
64 : #define BIT_7(x) ((x) & 128)
65 : #define BIT_6(x) ((x) & 64)
66 : #define BIT_5(x) ((x) & 32)
67 : #define BIT_4(x) ((x) & 16)
68 : #define BIT_3(x) ((x) & 8)
69 : #define BIT_2(x) ((x) & 4)
70 : #define BIT_1(x) ((x) & 2)
71 : #define BIT_0(x) ((x) & 1)
72 :
73 : // Upper or lower 4 bits of a byte, in the range 0..15
74 :
75 : #define UPPER_4_BITS(x) (((x) & 240) >> 4) // 240 is (15 * 16)
76 : #define LOWER_4_BITS(x) ((x) & 15)
77 :
78 : // Upper or lower 12 bits of an integer, in the range 0..4095
79 : //
80 : #define UPPER_12_BITS(x) (((x) & (4096 * 4095)) >> 12)
81 : #define LOWER_12_BITS(x) ((x) & 4095)
82 :
83 :
84 : //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
85 : // TYPE DEFINITIONS
86 :
87 : // General types
88 :
89 : typedef unsigned char byte; // 8 bit unsigned
90 : typedef uint16_t ushort; // 16 bit unsigned
91 : typedef uint32_t uint; // 32 bit unsigned
92 : typedef int32_t sint; // 32 bit signed
93 :
94 :
95 : // compareT: comparison type
96 :
97 : typedef signed int compareT;
98 : const compareT
99 : LESS_THAN = -1, EQUAL_TO = 0, GREATER_THAN = 1;
100 :
101 : // Chess Types
102 :
103 : typedef byte pieceT; // e.g ROOK or WK
104 : typedef byte colorT; // WHITE or BLACK
105 : typedef byte squareT; // e.g. A3
106 : typedef byte directionT; // e.g. UP_LEFT
107 : typedef byte rankT; // Chess board rank
108 : typedef byte fyleT; // Chess board file
109 : typedef byte leftDiagT; // Up-left diagonals
110 : typedef byte rightDiagT; // Up-right diagonals
111 :
112 : // boardT: 64 squares plus two extra squares: one for storing the side
113 : // to move as a byte and one for the string terminator, so boards can
114 : // be compared using regular string functions:
115 : typedef pieceT boardT [66];
116 :
117 : typedef byte smallBoardT [32];
118 : // A more densely packed board, 2 squares
119 : // per byte.
120 :
121 : typedef byte castleDirT; // LEFT or RIGHT
122 :
123 : // Other Small Types
124 :
125 : typedef ushort statusT;
126 :
127 : // Fixed String Types
128 :
129 : typedef char sanStringT [ 10]; // SAN Move Notation
130 :
131 : // File-related Types
132 :
133 : typedef char fileNameT [512];
134 : typedef uint fileLengthT;
135 :
136 : enum fileModeT {
137 : FMODE_None = 0,
138 : FMODE_ReadOnly,
139 : FMODE_WriteOnly,
140 : FMODE_Both,
141 : FMODE_Create,
142 : FMODE_Memory
143 : };
144 :
145 : // Date type: see date.h and date.cpp
146 :
147 : typedef uint dateT;
148 :
149 :
150 : // There are four name types: PLAYER, EVENT, SITE and ROUND tags.
151 : // Names are accessed through IDs.
152 : typedef uint32_t idNumberT; // Should be idNameT
153 : typedef unsigned nameT;
154 : enum {
155 : NAME_PLAYER, NAME_EVENT, NAME_SITE, NAME_ROUND,
156 : NUM_NAME_TYPES,
157 : NAME_INVALID = 99
158 : };
159 :
160 :
161 : // Game Information types
162 :
163 : typedef uint gamenumT;
164 : typedef ushort eloT;
165 : typedef ushort ecoT;
166 : typedef char ecoStringT [6]; /* "A00j1" */
167 :
168 : const ecoT ECO_None = 0;
169 :
170 : // Rating types:
171 :
172 : const byte RATING_Elo = 0;
173 : const byte RATING_Rating = 1;
174 : const byte RATING_Rapid = 2;
175 : const byte RATING_ICCF = 3;
176 : const byte RATING_USCF = 4;
177 : const byte RATING_DWZ = 5;
178 : const byte RATING_BCF = 6;
179 :
180 : extern const char * ratingTypeNames [17]; // Defined in game.cpp
181 :
182 :
183 :
184 : // Result Type
185 :
186 : const uint NUM_RESULT_TYPES = 4;
187 : typedef byte resultT;
188 : const resultT
189 : RESULT_None = 0,
190 : RESULT_White = 1,
191 : RESULT_Black = 2,
192 : RESULT_Draw = 3;
193 :
194 : const uint RESULT_SCORE[4] = { 1, 2, 0, 1 };
195 : const char RESULT_CHAR [4] = { '*', '1', '0', '=' };
196 : const char RESULT_STR [4][4] = { "*", "1-0", "0-1", "=-=" };
197 : const char RESULT_LONGSTR [4][8] = { "*", "1-0", "0-1", "1/2-1/2" };
198 : const resultT RESULT_OPPOSITE [4] = {
199 : RESULT_None, RESULT_Black, RESULT_White, RESULT_Draw
200 : };
201 :
202 : //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
203 : // CHESS PIECES, COLORS AND THEIR MACROS
204 :
205 : const uint NUM_COLOR_TYPES = 2;
206 : const colorT
207 : WHITE = 0,
208 : BLACK = 1,
209 : NOCOLOR = 2;
210 :
211 : const char COLOR_CHAR [3] = {'W', 'B', '_' };
212 :
213 : inline colorT
214 23653468 : color_Flip (colorT c) { return 1 - c; }
215 :
216 : inline char
217 : color_Char(colorT c) { return COLOR_CHAR[c]; }
218 :
219 : const castleDirT QSIDE = 0, KSIDE = 1;
220 :
221 :
222 : // PIECE TYPES (without color; same value as a white piece)
223 :
224 : const pieceT
225 : INVALID_PIECE = 0,
226 : KING = 1,
227 : QUEEN = 2,
228 : ROOK = 3,
229 : BISHOP = 4,
230 : KNIGHT = 5,
231 : PAWN = 6;
232 :
233 : // PIECES:
234 : // Note that color(x) == ((x & 0x8) >> 3) and type(x) == (x & 0x7)
235 : // EMPTY is deliberately nonzero, and END_OF_BOARD is zero, so that
236 : // a board can be used as a regular 0-terminated string, provided
237 : // that board[NULL_SQUARE] == END_OF_BOARD, as it always should be.
238 :
239 : const pieceT EMPTY = 7;
240 : const pieceT END_OF_BOARD = 0;
241 : const pieceT WK = 1, WQ = 2, WR = 3, WB = 4, WN = 5, WP = 6;
242 : const pieceT BK = 9, BQ = 10, BR = 11, BB = 12, BN = 13, BP = 14;
243 :
244 : // Minor piece definitions, used for searching by material only:
245 : const pieceT WM = 16, BM = 17;
246 :
247 : const uint MAX_PIECE_TYPES = 18;
248 :
249 :
250 : // PIECE_CHAR[]: array of piece characters, capitals for White pieces.
251 :
252 : const char PIECE_CHAR [] = "xKQRBNP.xkqrbnpxMm";
253 :
254 : // PIECE_FLIP[]: array of pieces, with colors reversed.
255 :
256 : const pieceT PIECE_FLIP [MAX_PIECE_TYPES] = {
257 : END_OF_BOARD,
258 : BK, BQ, BR, BB, BN, BP,
259 : EMPTY, EMPTY,
260 : WK, WQ, WR, WB, WN, WP,
261 : EMPTY, BM, WM
262 : };
263 :
264 : const bool PIECE_IS_SLIDER [8] = {
265 : false,
266 : false, true, true, true, false, false,
267 : false,
268 : };
269 :
270 : // PIECE_VALUE: Piece values, K=1000, Q=9, R=5, B=N=3, P=1
271 :
272 : const int PIECE_VALUE [MAX_PIECE_TYPES] = {
273 : 0,
274 : 100, 9, 5, 3, 3, 1,
275 : 0, 0,
276 : -100, -9, -5, -3, -3, -1,
277 : 0, 3, -3
278 : };
279 :
280 : //
281 : // INLINE FUNCTIONS for pieces
282 : //
283 :
284 : inline colorT
285 8861007 : piece_Color(pieceT p) { return (p == EMPTY) ? NOCOLOR : ((p & 8) >> 3); }
286 :
287 : // Slightly faster piece_Color when we are sure the piece is not empty:
288 : inline colorT
289 4297095 : piece_Color_NotEmpty(pieceT p) { return (p & 8) >> 3; }
290 :
291 : inline pieceT
292 63465404 : piece_Type(pieceT p) { return (p & 7); }
293 :
294 : inline pieceT
295 7319497 : piece_Make(colorT c, pieceT p) { return ((c << 3) | (p & 7)); }
296 :
297 : inline bool
298 : piece_IsWhite(pieceT p) { return (p>=WK && p<=WP); }
299 :
300 : inline bool
301 : piece_IsBlack(pieceT p) { return (p>=BK && p<=BP); }
302 :
303 : inline bool
304 0 : piece_IsKing(pieceT p) { return (piece_Type(p) == KING); }
305 :
306 : inline bool
307 : piece_IsQueen(pieceT p) { return (piece_Type(p) == QUEEN); }
308 :
309 : inline bool
310 : piece_IsRook(pieceT p) { return (piece_Type(p) == ROOK); }
311 :
312 : inline bool
313 : piece_IsBishop(pieceT p) { return (piece_Type(p) == BISHOP); }
314 :
315 : inline bool
316 : piece_IsKnight(pieceT p) { return (piece_Type(p) == KNIGHT); }
317 :
318 : inline bool
319 : piece_IsPawn(pieceT p) { return (piece_Type(p) == PAWN); }
320 :
321 : inline bool
322 0 : piece_IsSlider(pieceT p) { return PIECE_IS_SLIDER[piece_Type(p)]; }
323 :
324 : inline char
325 865584 : piece_Char(pieceT p) { return PIECE_CHAR[piece_Type(p)]; }
326 :
327 : inline pieceT
328 9891 : piece_FromChar(int x)
329 : {
330 9891 : switch (x) {
331 0 : case 'K': return KING;
332 2489 : case 'Q': return QUEEN;
333 2479 : case 'R': return ROOK;
334 2388 : case 'N': return KNIGHT;
335 2535 : case 'B': return BISHOP;
336 0 : default: return EMPTY;
337 : }
338 : }
339 :
340 : inline int
341 : piece_Value (pieceT p) { return PIECE_VALUE[p]; }
342 :
343 :
344 : //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
345 : // SQUARES AND SQUARE MACROS
346 :
347 : const squareT
348 : A1 = 0, B1 = 1, C1 = 2, D1 = 3, E1 = 4, F1 = 5, G1 = 6, H1 = 7,
349 : A2 = 8, B2 = 9, C2 =10, D2 =11, E2 =12, F2 =13, G2 =14, H2 =15,
350 : A3 =16, B3 =17, C3 =18, D3 =19, E3 =20, F3 =21, G3 =22, H3 =23,
351 : A4 =24, B4 =25, C4 =26, D4 =27, E4 =28, F4 =29, G4 =30, H4 =31,
352 : A5 =32, B5 =33, C5 =34, D5 =35, E5 =36, F5 =37, G5 =38, H5 =39,
353 : A6 =40, B6 =41, C6 =42, D6 =43, E6 =44, F6 =45, G6 =46, H6 =47,
354 : A7 =48, B7 =49, C7 =50, D7 =51, E7 =52, F7 =53, G7 =54, H7 =55,
355 : A8 =56, B8 =57, C8 =58, D8 =59, E8 =60, F8 =61, G8 =62, H8 =63,
356 : COLOR_SQUARE = 64,
357 : NULL_SQUARE = 65, NS = 65; // NS is abbreviation for NULL_SQUARE.
358 :
359 : const rankT
360 : RANK_1 = 0, RANK_2 = 1, RANK_3 = 2, RANK_4 = 3, RANK_5 = 4, RANK_6 = 5,
361 : RANK_7 = 6, RANK_8 = 7, NO_RANK = 64;
362 :
363 : const fyleT
364 : // we use "fyle" instead of "file" to avoid confusion with disk files.
365 : A_FYLE = 0, B_FYLE = 1, C_FYLE = 2, D_FYLE = 3, E_FYLE = 4, F_FYLE = 5,
366 : G_FYLE = 6, H_FYLE = 7, NO_FYLE = 64;
367 :
368 : inline rankT
369 1667856 : rank_FromChar(char c)
370 1667856 : { if (c < '1' || c > '8') { return NO_RANK; } else return (c - '1'); }
371 :
372 : inline fyleT
373 1666480 : fyle_FromChar(char c)
374 1666480 : { if (c < 'a' || c > 'h') { return NO_FYLE; } else return (c - 'a'); }
375 :
376 : inline squareT
377 1945610 : square_Make(fyleT f, rankT r)
378 : {
379 1945610 : ASSERT (f <= H_FYLE && r <= RANK_8);
380 1945610 : return ((r << 3) | f);
381 : }
382 :
383 : inline fyleT
384 149241461 : square_Fyle(squareT sq)
385 : {
386 149241461 : return (sq & 0x7);
387 : }
388 :
389 : inline rankT
390 162315878 : square_Rank(squareT sq)
391 : {
392 162315878 : return ((sq >> 3) & 0x7);
393 : }
394 :
395 : inline leftDiagT
396 63977566 : square_LeftDiag (squareT sq)
397 : {
398 63977566 : return square_Rank(sq) + square_Fyle(sq);
399 : }
400 :
401 : inline rightDiagT
402 32633457 : square_RightDiag (squareT sq)
403 : {
404 32633457 : return (7 + square_Rank(sq) - square_Fyle(sq));
405 : }
406 :
407 : // square_Color:
408 : // Return WHITE for a light square, BLACK for a dark square.
409 : inline colorT
410 31344109 : square_Color (squareT sq)
411 : {
412 31344109 : return 1 - (square_LeftDiag(sq) & 1);
413 : }
414 :
415 : // square_FlipFyle:
416 : // Return the square with its file flipped: a1 <-> h1, b1 <-> g1, etc.
417 : inline squareT
418 : square_FlipFyle (squareT sq)
419 : {
420 : return square_Make (A_FYLE + H_FYLE - square_Fyle(sq), square_Rank(sq));
421 : }
422 :
423 : // square_FlipRank:
424 : // Return the square with its rank flipped: a1 <-> a8, a2 <-> a7, etc.
425 : inline squareT
426 : square_FlipRank (squareT sq)
427 : {
428 : return square_Make (square_Fyle(sq), RANK_1 + RANK_8 - square_Rank(sq));
429 : }
430 :
431 : // square_FlipDiag:
432 : // Return the square flipped along the a1-h8 diagonal.
433 : inline squareT
434 : square_FlipDiag (squareT sq)
435 : {
436 : return square_Make (square_Rank(sq), square_Fyle(sq));
437 : }
438 :
439 : const uint
440 : rankFyleDist[64] = {
441 : 0, 1, 2, 3, 4, 5, 6, 7,
442 : 1, 0, 1, 2, 3, 4, 5, 6,
443 : 2, 1, 0, 1, 2, 3, 4, 5,
444 : 3, 2, 1, 0, 1, 2, 3, 4,
445 : 4, 3, 2, 1, 0, 1, 2, 3,
446 : 5, 4, 3, 2, 1, 0, 1, 2,
447 : 6, 5, 4, 3, 2, 1, 0, 1,
448 : 7, 6, 5, 4, 3, 2, 1, 0
449 : };
450 :
451 : // square_Distance:
452 : // Return the distance in king moves between two squares.
453 : inline uint
454 : square_Distance (squareT from, squareT to)
455 : {
456 : ASSERT (from <= H8 && to <= H8);
457 : uint rankd = rankFyleDist[(square_Rank(from) << 3) | square_Rank(to)];
458 : uint fyled = rankFyleDist[(square_Fyle(from) << 3) | square_Fyle(to)];
459 : return (rankd > fyled) ? rankd : fyled;
460 : }
461 :
462 : // square_NearestCorner:
463 : // Return the corner (A1/H1/A8/H8) closest to the specified square.
464 : inline squareT
465 : square_NearestCorner (squareT sq)
466 : {
467 : if (square_Rank(sq) <= RANK_4) {
468 : return (square_Fyle(sq) <= D_FYLE)? A1 : H1;
469 : } else {
470 : return (square_Fyle(sq) <= D_FYLE)? A8 : H8;
471 : }
472 : }
473 :
474 : inline bool
475 : square_IsCornerSquare (squareT sq)
476 : {
477 : return (sq == A1 || sq == H1 || sq == A8 || sq == H8);
478 : }
479 :
480 : inline bool
481 : square_IsEdgeSquare (squareT sq)
482 : {
483 : rankT rank = square_Rank(sq);
484 : if (rank == RANK_1 || rank == RANK_8) { return true; }
485 : fyleT fyle = square_Fyle(sq);
486 : if (fyle == A_FYLE || fyle == H_FYLE) { return true; }
487 : return false;
488 : }
489 :
490 : const int edgeDist[66] = {
491 : 0, 0, 0, 0, 0, 0, 0, 0,
492 : 0, 1, 1, 1, 1, 1, 1, 0,
493 : 0, 1, 2, 2, 2, 2, 1, 0,
494 : 0, 1, 2, 3, 3, 2, 1, 0,
495 : 0, 1, 2, 3, 3, 2, 1, 0,
496 : 0, 1, 2, 2, 2, 2, 1, 0,
497 : 0, 1, 1, 1, 1, 1, 1, 0,
498 : 0, 0, 0, 0, 0, 0, 0, 0,
499 : -1, -1
500 : };
501 :
502 : inline int
503 : square_EdgeDistance (squareT sq)
504 : {
505 : return edgeDist[sq];
506 : }
507 :
508 : inline bool
509 0 : square_IsKnightHop (squareT from, squareT to)
510 : {
511 0 : ASSERT (from <= H8 && to <= H8);
512 0 : uint rdist = rankFyleDist [(square_Rank(from) << 3) | square_Rank(to)];
513 0 : uint fdist = rankFyleDist [(square_Fyle(from) << 3) | square_Fyle(to)];
514 : // It is a knight hop only if one distance is two squares and the
515 : // other is one square -- that is, only if their product equals two.
516 0 : return ((rdist * fdist) == 2);
517 : }
518 :
519 : inline char
520 1614917 : square_FyleChar (squareT sq)
521 : {
522 1614917 : return square_Fyle(sq) + 'a';
523 : }
524 :
525 : inline char
526 1565956 : square_RankChar (squareT sq)
527 : {
528 1565956 : return square_Rank(sq) + '1';
529 : }
530 :
531 : inline void
532 : square_Print (squareT sq, char * str)
533 : {
534 : if (sq <= H8) {
535 : str[0] = square_FyleChar(sq);
536 : str[1] = square_RankChar(sq);
537 : str[2] = 0;
538 : } else if (sq == NULL_SQUARE) {
539 : str[0] = 'N'; str[1] = 'S'; str[2] = 0;
540 : } else {
541 : str[0] = 'X'; str[1] = 'X'; str[2] = 0;
542 : }
543 : return;
544 : }
545 :
546 : // Directions:
547 : // Up = 1, Down = 2, Left = 4, Right = 8, UpLeft = 5, UpRight = 9,
548 : // DownLeft = 6, DownRight = 10
549 :
550 : const directionT
551 : NULL_DIR = 0,
552 : UP = 1,
553 : DOWN = 2,
554 : LEFT = 4,
555 : RIGHT = 8,
556 : UP_LEFT = (UP | LEFT),
557 : UP_RIGHT = (UP | RIGHT),
558 : DOWN_LEFT = (DOWN | LEFT),
559 : DOWN_RIGHT = (DOWN | RIGHT);
560 :
561 : const directionT dirOpposite[11] = {
562 : NULL_DIR,
563 : DOWN, // opposite of UP (1)
564 : UP, // opposite of DOWN (2)
565 : NULL_DIR,
566 : RIGHT, // opposite of LEFT (4)
567 : DOWN_RIGHT, // opposite of UP_LEFT (5)
568 : UP_RIGHT, // opposite of DOWN_LEFT (6)
569 : NULL_DIR,
570 : LEFT, // opposite of RIGHT (8)
571 : DOWN_LEFT, // opposite of UP_RIGHT (9)
572 : UP_LEFT // opposite of DOWN_RIGHT (10)
573 : };
574 :
575 : // direction_Opposite(): return the opposite direction to d
576 : inline directionT
577 2593165 : direction_Opposite (directionT d)
578 : {
579 2593165 : return dirOpposite[d];
580 : }
581 :
582 : // dirIsDiagonal[]: array listing the diagonal directions, for fast
583 : // lookup of whether a direction is a diagonal.
584 : const bool
585 : dirIsDiagonal [11] = {
586 : false, // 0 = NULL_DIR
587 : false, // 1 = UP
588 : false, // 2 = DOWN
589 : false, // 3 = Invalid
590 : false, // 4 = LEFT
591 : true, // 5 = UP_LEFT
592 : true, // 6 = DOWN_LEFT
593 : false, // 7 = Invalid
594 : false, // 8 = RIGHT
595 : true, // 9 = UP_RIGHT
596 : true // 10 = DOWN_RIGHT
597 : };
598 :
599 : inline bool
600 9641 : direction_IsDiagonal (directionT dir)
601 : {
602 9641 : return dirIsDiagonal[dir];
603 : }
604 :
605 : // dirDelta:
606 : // Array giving the board delta of moving to the next square
607 : // in that direction.
608 : const int
609 : dirDelta[11] = {
610 : 0, // NULL_DIR
611 : 8, // UP
612 : -8, // DOWN
613 : 0, // Invalid
614 : -1, // LEFT
615 : 7, // UP_LEFT
616 : -9, // DOWN_LEFT
617 : 0, // Invalid
618 : 1, // RIGHT
619 : 9, // UP_RIGHT
620 : -7 // DOWN_RIGHT
621 : };
622 :
623 : inline int
624 11768450 : direction_Delta (directionT dir)
625 : {
626 11768450 : return dirDelta[dir];
627 : }
628 :
629 : // The starting Board
630 : //
631 : const boardT
632 : START_BOARD =
633 : {
634 : WR, WN, WB, WQ, WK, WB, WN, WR, // A1--H1
635 : WP, WP, WP, WP, WP, WP, WP, WP, // A2--H2
636 : EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
637 : EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
638 : EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
639 : EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY, EMPTY,
640 : BP, BP, BP, BP, BP, BP, BP, BP,
641 : BR, BN, BB, BQ, BK, BB, BN, BR,
642 : EMPTY, // COLOR_SQUARE
643 : END_OF_BOARD // NULL_SQUARE
644 : };
645 :
646 :
647 : // Square colors for the standard chess board:
648 : //
649 : const colorT
650 : BOARD_SQUARECOLOR[66] = {
651 : BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, // a1-h1
652 : WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, // a2-h2
653 : BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, // a3-h3
654 : WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, // a4-h4
655 : BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, // a5-h5
656 : WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, // a6-h6
657 : BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, // a7-h7
658 : WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, WHITE, BLACK, // a8-h8
659 : NOCOLOR, NOCOLOR // Color square and Null square
660 : };
661 :
662 : inline int
663 : board_Compare (const pieceT * b1, const pieceT * b2)
664 : {
665 : for (uint i=0; i < 64; i++) {
666 : if (*b1 < *b2) { return -1; }
667 : if (*b1 > *b2) { return 1; }
668 : b1++; b2++;
669 : }
670 : return 0;
671 : }
672 :
673 : // square_Adjacent: returns 1 if the two squares are adjacent. Note that
674 : // diagonal adjacency is included: a1 and b2 are adjacent.
675 : // Also note that a square is adjacent to itself.
676 : inline bool
677 4208870 : square_Adjacent (squareT from, squareT to)
678 : {
679 4208870 : ASSERT (from <= H8 && to <= H8);
680 4208870 : rankT fromRank = square_Rank(from);
681 4208870 : rankT toRank = square_Rank(to);
682 4208870 : int rdist = (int)fromRank - (int)toRank;
683 4208870 : if (rdist < -1 || rdist > 1) { return false; }
684 596059 : fyleT fromFyle = square_Fyle(from);
685 596059 : fyleT toFyle = square_Fyle(to);
686 596059 : int fdist = (int)fromFyle - (int)toFyle;
687 596059 : if (fdist < -1 || fdist > 1) { return false; }
688 115534 : return true;
689 : }
690 :
691 : #endif // #ifdef SCID_COMMON_H
692 :
693 : //////////////////////////////////////////////////////////////////////
694 : // EOF: common.h
695 : //////////////////////////////////////////////////////////////////////
696 :
|