File: chess.h

package info (click to toggle)
crafty 14.11-3
  • links: PTS
  • area: non-free
  • in suites: hamm
  • size: 1,468 kB
  • ctags: 2,479
  • sloc: ansic: 25,318; asm: 793; makefile: 72
file content (858 lines) | stat: -rw-r--r-- 35,955 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
/*
********************************************************************************
*                                                                              *
*   configuration information:  the following variables need to be set to      *
*   indicate the machine configuration/capabilities.                           *
*                                                                              *
*   there are pre-defined machine types for the following machines: (1) SUN    *
*   (2) DOS (3) ALPHA [DEC Alpha] (4) CRAY  (5) LINUX.  defining any of these  *
*   names will produce a runnable executable.  for other machines, the names   *
*   explained below must be individually DEFINED or UNDEFINED as needed.       *
*                                                                              *
*   HAS_64BITS:  define this for a machine that has true 64-bit hardware       *
*   including leading-zero hardware, population count, etc.  ie, a Cray-like   *
*   machine.                                                                   *
*                                                                              *
*   HAS_LONGLONG:  define this for a 32-bit machine with a compiler that       *
*   supports the long long (64-bit) integer data and allows bitwise operations *
*   on this data type.  this provides significantly faster execution time as   *
*   the bitwise operators are done by the compiler rather than by procedure    *
*   calls.                                                                     *
*                                                                              *
*   LITTLE_ENDIAN_ARCH:  define for a 32-bit machine that mangles the way data *
*   is stored within a word.  This is currently true for all PC class machines *
*   and false for other processors used in current workstations (SUN, etc.)    *
*                                                                              *
*   UNIX:  define this if the program is being run on a unix-based system,     *
*   which causes the executable to use unix-specific runtime utilities.        *
*                                                                              *
********************************************************************************
*/
#if !defined(TYPES_INCLUDED)
#  define TYPES_INCLUDED

#if defined(AIX)
#  undef  HAS_64BITS           /* machine has 64-bit integers / operators     */
#  define HAS_LONGLONG         /* machine has 32-bit/64-bit integers          */
#  undef  LITTLE_ENDIAN_ARCH   /* machine stores bytes in "PC" order          */
#  define UNIX                 /* system is unix-based                        */
#endif
#if defined(ALPHA)
#  define HAS_64BITS           /* machine has 64-bit integers / operators     */
#  undef  HAS_LONGLONG         /* machine has 32-bit/64-bit integers          */
#  define LITTLE_ENDIAN_ARCH   /* machine stores bytes in "PC" order          */
#  define UNIX                 /* system is unix-based                        */
#endif
#if defined(AMIGA)
#  undef  HAS_64BITS           /* machine has 64-bit integers / operators     */
#  define HAS_LONGLONG         /* machine has 32-bit/64-bit integers          */
#  undef  LITTLE_ENDIAN_ARCH   /* machine stores bytes in "PC" order          */
#  undef  UNIX                 /* system is unix-based                        */
#endif
#if defined(CRAY1)
#  define HAS_64BITS           /* machine has 64-bit integers / operators     */
#  undef  HAS_LONGLONG         /* machine has 32-bit/64-bit integers          */
#  undef  LITTLE_ENDIAN_ARCH   /* machine stores bytes in "PC" order          */
#  define UNIX                 /* system is unix-based                        */
#endif
#if defined(DOS)
#  undef  HAS_64BITS           /* machine has 64-bit integers / operators     */
#  define HAS_LONGLONG         /* machine has 32-bit/64-bit integers          */
#  define LITTLE_ENDIAN_ARCH   /* machine stores bytes in "PC" order          */
#  undef  UNIX                 /* system is unix-based                        */
#endif
#if defined(FreeBSD)
#  undef  HAS_64BITS           /* machine has 64-bit integers / operators     */
#  define HAS_LONGLONG         /* machine has 32-bit/64-bit integers          */
#  define LITTLE_ENDIAN_ARCH   /* machine stores bytes in "PC" order          */
#  define UNIX                 /* system is unix-based                        */
#endif
#if defined(HP)
#  undef  HAS_64BITS           /* machine has 64-bit integers / operators     */
#  define HAS_LONGLONG         /* machine has 32-bit/64-bit integers          */
#  undef  LITTLE_ENDIAN_ARCH   /* machine stores bytes in "PC" order          */
#  define UNIX                 /* system is unix-based                        */
#endif
#if defined(LINUX)
#  undef  HAS_64BITS           /* machine has 64-bit integers / operators     */
#  define HAS_LONGLONG         /* machine has 32-bit/64-bit integers          */
#  define LITTLE_ENDIAN_ARCH   /* machine stores bytes in "PC" order          */
#  define UNIX                 /* system is unix-based                        */
#endif
#if defined(MIPS)
#  undef  HAS_64BITS           /* machine has 64-bit integers / operators     */
#  define HAS_LONGLONG         /* machine has 32-bit/64-bit integers          */
#  undef  LITTLE_ENDIAN_ARCH   /* machine stores bytes in "PC" order          */
#  define UNIX                 /* system is unix-based                        */
#endif
#if defined(NEXT)
#  undef  HAS_64BITS          /* machine has 64-bit integers / operators     */
#  define HAS_LONGLONG        /* machine has 32-bit/64-bit integers          */
#  undef  LITTLE_ENDIAN_ARCH  /* machine stores bytes in "PC" order          */
#  define UNIX                /* system is unix-based                        */
#endif
#if defined(NT_AXP)
#  undef  HAS_64BITS           /* machine has 64-bit integers / operators     */
#  define HAS_LONGLONG         /* machine has 32-bit/64-bit integers          */
#  define LITTLE_ENDIAN_ARCH   /* machine stores bytes in "PC" order          */
#  undef  UNIX                 /* system is unix-based                        */
#endif
#if defined(NT_i386)
#  undef  HAS_64BITS           /* machine has 64-bit integers / operators     */
#  define HAS_LONGLONG         /* machine has 32-bit/64-bit integers          */
#  define LITTLE_ENDIAN_ARCH   /* machine stores bytes in "PC" order          */
#  undef  UNIX                 /* system is unix-based                        */
#endif
#if defined(OS2)
#  undef  HAS_64BITS           /* machine has 64-bit integers / operators     */
#  define HAS_LONGLONG         /* machine has 32-bit/64-bit integers          */
#  define LITTLE_ENDIAN_ARCH   /* machine stores bytes in "PC" order          */
#  define UNIX                 /* system is unix-based                        */
#endif
#if defined(SGI)
#  undef  HAS_64BITS           /* machine has 64-bit integers / operators     */
#  define HAS_LONGLONG         /* machine has 32-bit/64-bit integers          */
#  undef  LITTLE_ENDIAN_ARCH   /* machine stores bytes in "PC" order          */
#  define UNIX                 /* system is unix-based                        */
#endif
#if defined(SUN)
#  undef  HAS_64BITS           /* machine has 64-bit integers / operators     */
#  define HAS_LONGLONG         /* machine has 32-bit/64-bit integers          */
#  undef  LITTLE_ENDIAN_ARCH   /* machine stores bytes in "PC" order          */
#  define UNIX                 /* system is unix-based                        */
#endif
#if defined(SUN_BSD)
#  undef  HAS_64BITS           /* machine has 64-bit integers / operators     */
#  define HAS_LONGLONG         /* machine has 32-bit/64-bit integers          */
#  undef  LITTLE_ENDIAN_ARCH   /* machine stores bytes in "PC" order          */
#  define UNIX                 /* system is unix-based                        */
#endif

#if defined(__MWERKS__)
#  define MACOS
#endif

#if defined(MACOS)
#  undef  HAS_64BITS           /* machine has 64-bit integers / operators     */
#  define HAS_LONGLONG         /* machine has 32-bit/64-bit integers          */
#  undef  LITTLE_ENDIAN_ARCH   /* machine stores bytes in "PC" order          */
#  undef  UNIX                 /* system is unix-based                        */

#  define COMPACT_ATTACKS
#  define USE_ATTACK_FUNCTIONS  

#  define     BOOKDIR "Books"
#  define      LOGDIR "Logs"
#  define       TBDIR "TB"
#else
#  define     BOOKDIR "."
#  define      LOGDIR "."
#  define       TBDIR "./TB"
#endif

#  define      BOOK_CLUSTER_SIZE            600
#  define        MERGE_BLOCKSIZE           1000
#  define         SORT_BLOCKSIZE         200000
#  define         LEARN_INTERVAL             10
#  define        LEARN_WINDOW_LB            -40
#  define        LEARN_WINDOW_UB            +40
#  define      LEARN_COUNTER_BAD            -80
#  define     LEARN_COUNTER_GOOD           +100


/*
  fractional ply extensions.  these should be in units based on the
  value of INCREMENT_PLY (default is 60).  a value of 60 means this
  extension is exactly one ply.
*/

#  define INCREMENT_PLY            60  /* 1.00 */
#  define NULL_MOVE_DEPTH         120  /* 2.00 */
#  define RAZORING_DEPTH           60  /* 1.00 */
#  define IN_CHECK                 45  /* 0.75 */
#  define ONE_REPLY_TO_CHECK       45  /* 0.75 */
#  define RECAPTURE                45  /* 0.75 */
#  define PUSH_PASSED_PAWN         45  /* 0.75 */
#  define MATE_THREAT              45  /* 0.75 */
#  define SINGULAR                 45  /* 0.75 */

#  define MATE                  32768
#  define PAWN_VALUE              100
#  define KNIGHT_VALUE            350
#  define BISHOP_VALUE            350
#  define ROOK_VALUE              550
#  define QUEEN_VALUE            1100
#  define KING_VALUE            40000

#  define MAXPLY 65
  
#  if defined(HAS_64BITS)
     typedef unsigned long BITBOARD;
#  else
#    if defined(NT_i386) || defined(NT_AXP)
       typedef unsigned _int64 BITBOARD;
#    else
       typedef unsigned long long BITBOARD;
#    endif
#  endif

#include <time.h>
#if !defined(CLOCKS_PER_SEC)
#  define CLOCKS_PER_SEC 1000000
#endif
  typedef enum { A1,B1,C1,D1,E1,F1,G1,H1,
                 A2,B2,C2,D2,E2,F2,G2,H2,
                 A3,B3,C3,D3,E3,F3,G3,H3,
                 A4,B4,C4,D4,E4,F4,G4,H4,
                 A5,B5,C5,D5,E5,F5,G5,H5,
                 A6,B6,C6,D6,E6,F6,G6,H6,
                 A7,B7,C7,D7,E7,F7,G7,H7,
                 A8,B8,C8,D8,E8,F8,G8,H8,
                 BAD_SQUARE } squares;

  typedef enum {FILEA, FILEB, FILEC, FILED, FILEE, FILEF, FILEG, FILEH} files;

  typedef enum {RANK1, RANK2, RANK3, RANK4, RANK5, RANK6, RANK7, RANK8} ranks;

  typedef enum {empty=0, pawn=1, knight=2, king=3, 
                bishop=5, rook=6, queen=7} PIECE;
  
  typedef enum {empty_v=0, pawn_v=1, knight_v=2, 
                bishop_v=3, rook_v=5, queen_v=9} PIECE_V;
  
  typedef enum {no_extension=0, check_extension=1, recapture_extension=2,
                passed_pawn_extension=4, one_reply_extension=8} EXTENSIONS;
  
  typedef enum {cpu, elapsed, microseconds} TIME_TYPE;

  typedef enum {think=1, puzzle=2, book=3, annotate=4} SEARCH_TYPE;

  typedef enum {normal_mode, tournament_mode} PLAYING_MODE;

  typedef enum {crafty, opponent} PLAYER;

  typedef enum {book_learning=1, position_learning=2} LEARNING_MODE;
  
  typedef struct {
    unsigned char enpassant_target;
    signed   char w_castle;
    signed   char b_castle;
    unsigned char rule_50_moves;
  } SEARCH_POSITION;

  typedef  struct {
    BITBOARD       w_occupied;
    BITBOARD       b_occupied;
    BITBOARD       occupied_rl90;
    BITBOARD       occupied_rl45;
    BITBOARD       occupied_rr45;
    BITBOARD       rooks_queens;
    BITBOARD       bishops_queens;
    BITBOARD       w_pawn;
    BITBOARD       w_knight;
    BITBOARD       w_bishop;
    BITBOARD       w_rook;
    BITBOARD       w_queen;
    BITBOARD       b_pawn;
    BITBOARD       b_knight;
    BITBOARD       b_bishop;
    BITBOARD       b_rook;
    BITBOARD       b_queen;
    BITBOARD       hash_key;
    unsigned int   pawn_hash_key;
    int            material_evaluation;
    signed char    white_king;
    signed char    black_king;
    signed char    board[64];
    signed char    white_pieces;
    signed char    white_pawns;
    signed char    black_pieces;
    signed char    black_pawns;
    signed char    total_pieces;
  } CHESS_POSITION;
  
  typedef struct {
    BITBOARD word1;
    BITBOARD word2;
  } HASH_ENTRY;

  typedef struct {
    unsigned int key;
    short    p_score;
    unsigned char black_protected;
    unsigned char black_pof;
    unsigned char weak_b;
    unsigned char passed_b;
    unsigned char black_defects_k;
    unsigned char black_defects_q;
    unsigned char white_protected;
    unsigned char white_pof;
    unsigned char weak_w;
    unsigned char passed_w;
    unsigned char white_defects_k;
    unsigned char white_defects_q;
    unsigned char outside;
  } PAWN_HASH_ENTRY;
  
  typedef struct {
    int path[MAXPLY];
    unsigned char path_hashed;
    unsigned char path_length;
    unsigned char path_iteration_depth;
  } CHESS_PATH;
  
  typedef struct {
    int phase;
    int remaining;
    int *last;
  } NEXT_MOVE;

  typedef struct {
    BITBOARD position;
    BITBOARD status;
    float learn;
  } BOOK_POSITION;

#  if defined(COMPACT_ATTACKS)
#    define NDIAG_ATTACKS	   296
#    define NRANK_ATTACKS	    70
#    define NFILE_ATTACKS	    70

#    define NSHORT_MOBILITY  116

#    define MAX_ATTACKS_FROM_SQUARE 12

     typedef struct {
/* Fields for the diagonal */
       BITBOARD *d_attacks;
       unsigned char *d_mobility;
       unsigned char *d_which_attack;
       unsigned char d_shift;
       unsigned char d_mask;

/* Fields for the anti diagonal */
       unsigned char ad_shift;
       unsigned char ad_mask;
       unsigned char *ad_which_attack;
       unsigned char *ad_mobility;
       BITBOARD *ad_attacks;
     } DIAG_INFO;
#  endif  

/*  
    DO NOT modify these.  these are constants, used in multiple modules.
    modification may corrupt the search in any number of ways, all bad.
*/

#  define WORTHLESS                 0
#  define LOWER_BOUND               1
#  define UPPER_BOUND               2
#  define EXACT_SCORE               3
#  define AVOID_NULL_MOVE           4

#  define NULL_MOVE                 0
#  define DO_NULL                   1
#  define NO_NULL                   0

#  define NONE                      0
#  define FIRST_PHASE               1
#  define HASH_MOVE                 1
#  define GENERATE_CAPTURE_MOVES    2
#  define CAPTURE_MOVES             3
#  define KILLER_MOVE_1             4
#  define KILLER_MOVE_2             5
#  define GENERATE_ALL_MOVES        6
#  define SORT_ALL_MOVES            7  
#  define HISTORY_MOVES_1           8
#  define HISTORY_MOVES_2           9
#  define REMAINING_MOVES          10
#  define ROOT_MOVES               11
 
#  if !defined(CRAY1)
    BITBOARD     Mask(int);
    int          PopCnt(BITBOARD);
    int          FirstOne(BITBOARD);
    int          LastOne(BITBOARD);
#  endif
  
  void           Analyze();
  void           Annotate();
  int            Attacked(int, int);
  BITBOARD       AttacksFrom(int, int);
  BITBOARD       AttacksTo(int);
  void           Bench();
  int            Book(int,int);
  int            BookMask(char*);
  void           BookUp(char*,int,char**);
#  if defined(NT_i386) || defined(NT_AXP)
    int _cdecl     BookUpCompare(const void *, const void *);
#  else
    int            BookUpCompare(const void *, const void *);
#  endif
  BOOK_POSITION  BookUpNextPosition(int,int);
  int            CheckInput(void);
  void           ClearHashTables(void);
  void           ComputeAttacksAndMobility(void);
  void           Delay232(int);
  void           DisplayBitBoard(BITBOARD);
  void           DisplayChessBoard(FILE*, CHESS_POSITION);
  char*          DisplayEvaluation(int);
  char*          DisplayEvaluationWhisper(int);
  void           DisplayFT(int, int, int);
  char*          DisplayHHMM(unsigned int);
  void           DisplayPieceBoards(int*, int*);
  void           DisplayPV(int,int,int,int,CHESS_PATH);
  char*          DisplayTime(unsigned int);
  char*          DisplayTimeWhisper(unsigned int);
  void           Display2BitBoards(BITBOARD, BITBOARD);
  void           DisplayChessMove(char*, int);
  int            DrawScore(void);
  int            Drawn(int);
  void           Edit(void);
  int            EnPrise(int, int);
  int            Evaluate(int, int, int, int);
  int            EvaluateDevelopment(int);
  int            EvaluateDraws();
  int            EvaluateMate(void);
  int            EvaluatePassedPawns(void);
  int            EvaluatePassedPawnRaces(int);
  int            EvaluatePawns(void);
  int*           GenerateCaptures(int, int, int*);
  int*           GenerateCheckEvasions(int, int, int*);
  int*           GenerateNonCaptures(int, int, int*);
  unsigned int   ReadClock(TIME_TYPE);
  int            HasOpposition(int, int, int);
  void           HistoryBest(int, int, int);
  void           HistoryRefutation(int, int, int);
  void           Initialize(int);
  void           InitializeAttackBoards(void);
  void           InitializeChessBoard(SEARCH_POSITION*);
  int            InitializeFindAttacks(int, int, int);
  void           InitializeHashTables(void);
  void           InitializeMasks(void);
  void           InitializePawnMasks(void);
  void           InitializePieceMasks(void);
  void           InitializeRandomHash(void);
  void           InitializeZeroMasks(void);
  int            InputMove(char*, int, int, int, int);
  int            InputMoveICS(char*, int, int, int, int);
  BITBOARD       InterposeSquares(int, int, int);
  void           Interrupt(int);
  int            Iterate(int, int, int);
  int            KingPawnSquare(int, int, int, int);
  void           LearnBook(int,int,int,int,int);
  void           LearnBookUpdate(int,int,float);
  int            LearnFunction(int,int,int,int);
  void           LearnImport(int,char**);
  void           LearnImportBook(int,char**);
  void           LearnImportPosition(int,char**);
  void           LearnPosition(int,int,int);
  void           LearnPositionLoad(void);
  int            LookUp(int, int, int, int*, int*, int*);
  void           MakeMove(int, int, int);
  void           MakeMoveRoot(int, int);
  void           NewGame(int);
  int            NextEvasion(int, int);
  int            NextMove(int, int);
  int            NextRootMove(int);
  char*          Normal(void);
  int            Option(void);
  int            OptionMatch(char*, char*);
  void           OptionPerft(int,int,int);
  char*          OutputMove(int*, int, int);
  char*          OutputMoveICS(int*);
  int            OutputGood(char*, int, int);
  int            ParseTime(char*);
  void           Phase(void);
  int            PinnedOnKing(int,int);
  int            Ponder(int);
  void           PreEvaluate(int);
  void           Print(int, char*, ...);
  int            Quiesce(int, int, int, int);
  unsigned int   Random32(void);
  BITBOARD       Random64(void);
  int            Read(int, char*);
  int            ReadChessMove(FILE*, int, int);
  void           ReadClear();
  int            ReadPGN(FILE*,int);
  int            ReadNextMove(char*, int, int);
  int            ReadParse(char*, char *args[], char*);
  int            ReadRaw();
  int            RepetitionCheck(int,int);
  int            RepetitionDraw(int);
  void           ResignOrDraw(int,int);
  char*          Reverse(void);
  void           RootMoveList(int);
  int            Search(int, int, int, int, int, int);
  void           SearchOutput(int,int);
  int            SearchRoot(int, int, int, int);
  void           SearchTrace(int,int,int,int,int,char*,int);
  void           SetBoard(int,char**,int);
  void           SetChessBitBoards(SEARCH_POSITION*);
  int            Singular(int, int, int, int);
  void           StoreBest(int,int,int,int,int,int);
  void           StorePV(int,int);
  void           StoreRefutation(int,int,int,int,int);
  int            Swap(int, int, int);
  BITBOARD       SwapXray(BITBOARD, int, int);
  void           EVTest(char *);
  void           Test(char *);
  int            Threat(int, int, int, int, int, int);
  void           TimeAdjust(int,PLAYER);
  int            TimeCheck(int);
  void           TimeSet(int);
  void           UnMakeMove(int, int, int);
  int            ValidMove(int, int, int);
  void           ValidatePosition(int,int,char*);
  BITBOARD       ValidateComputeBishopAttacks(int);
  BITBOARD       ValidateComputeRookAttacks(int);
  void           Whisper(int, int, int, int, unsigned int, int, char*);
  
#  if defined(HAS_64BITS) || defined(HAS_LONGLONG)
#    define And(a,b)    ((a) & (b))
#    define Or(a,b)     ((a) | (b))
#    define Xor(a,b)    ((a) ^ (b))
#    define Compl(a)    (~(a))
#    define Shiftl(a,b) ((a) << (b))
#    define Shiftr(a,b) ((a) >> (b))
#    if defined(CRAY1)
#      define PopCnt(a)     _popcnt(a)
#      define FirstOne(a)   _leadz(a)
#      define LastOne(a)    _leadz((a)^(a-1))
#      define Mask(a)       _mask(a)
#      define mask_1        _mask(1)
#      define mask_2        _mask(2)
#      define mask_3        _mask(3)
#      define mask_4        _mask(4)
#      define mask_8        _mask(8)
#      define mask_16       _mask(16)
#      define mask_32       _mask(32)
#      define mask_72       _mask(72)
#      define mask_80       _mask(80)
#      define mask_85       _mask(85)
#      define mask_96       _mask(96)
#      define mask_107      _mask(107)
#      define mask_108      _mask(108)
#      define mask_112      _mask(112)
#      define mask_118      _mask(118)
#      define mask_120      _mask(120)
#      define mask_121      _mask(121)
#      define mask_127      _mask(127)
#    endif
#  endif

#  define ABSearch(alpha,beta,wtm,depth,ply,donull)              \
   (((depth) >= INCREMENT_PLY) ?                                 \
      Search(alpha,beta,wtm,depth,ply,donull) :                  \
      Quiesce(alpha,beta,wtm,ply))

#  define Max(a,b)  (((a) > (b)) ? (a) : (b))
#  define Min(a,b)  (((a) < (b)) ? (a) : (b))
#  define FileDistance(a,b) abs(((a)&7) - ((b)&7))
#  define RankDistance(a,b) abs(((a)>>3) - ((b)>>3))
#  define Distance(a,b) Max(FileDistance(a,b),RankDistance(a,b))

/*  
    the following macro is used to determine if one side is in check.  it
    simply returns the result of Attacked().
*/
#  define Check(wtm)                                                     \
    Attacked((wtm)?WhiteKingSQ:BlackKingSQ,ChangeSide(wtm))
/*  
    Attack() is used to determine if a newly promoted pawn (queen)
    attacks <square>.  normally <square> will be the location of the opposing
    king, but it can also be the location of the opposing side's queening
    square in case this pawn prevents the other pawn from safely queening on
    the next move.
*/
#  define Attack(square,queen,ply) !And(obstructed[square][queen],Occupied)
/*  
    the following macros are used to construct the attacks from a square.
    the attacks are computed as four separate bit vectors, one for each of the
    two diagonals, and one for the ranks and one for the files.  these can be
    Or'ed together to produce the attack bitmaps for bishops, rooks and queens.
*/
#  if defined(COMPACT_ATTACKS) && defined(USE_ATTACK_FUNCTIONS)
     extern BITBOARD AttacksRookFunc(int, CHESS_POSITION *);
     extern BITBOARD AttacksBishopFunc(DIAG_INFO *, CHESS_POSITION *);
#    define AttacksRook(a) AttacksRookFunc(a,&search)
#    define AttacksBishop(a) AttacksBishopFunc(&diag_info[a],&search)
#  else
#    define AttacksRook(a)    Or(AttacksRank(a),AttacksFile(a))
#    define AttacksBishop(a)  Or(AttacksDiaga1(a),AttacksDiagh1(a))
#  endif

#  define AttacksQueen(a)   Or(AttacksBishop(a),AttacksRook(a))
#  define Rank(x)       (((x)>>3)&7)
#  define File(x)       ((x)&7)
#  define ChangeSide(x) ((x)^1)

#  if defined(COMPACT_ATTACKS)
/*
  On a 32 bit machine optimizes the right shift of a long long
  where it is known that desired piece lies completely in one of
  the 32 bit words.
*/
#  if defined(USE_SPLIT_SHIFTS)
#    define SplitShiftr(value,shift) ((shift) >= 32 ?      \
       Shiftr ((unsigned long) Shiftr((value), 32), (shift)-32) : \
       Shiftr ((unsigned long) (value), (shift)))
#  else
#    define SplitShiftr(value,shift) Shiftr(value,shift)
#  endif

#  define AttacksDiaga1Int(diagp,boardp) \
     (diagp)->ad_attacks[(diagp)->ad_which_attack[ \
      And (SplitShiftr((boardp)->occupied_rl45,(diagp)->ad_shift),\
      (diagp)->ad_mask)]]

#  define AttacksDiagh1Int(diagp,boardp)\
     (diagp)->d_attacks[(diagp)->d_which_attack[ \
      And (SplitShiftr((boardp)->occupied_rr45,(diagp)->d_shift), \
      (diagp)->d_mask)]]

/*
  On a 32 bit machine optimizes promoting a smaller value to a long
  long where it is known that the smaller piece will be completely
  in one of the 32 bit words.
*/
#  if defined(USE_SPLIT_SHIFTS)
#    define SplitShiftl(value,shift)     \
       ((shift) >= 32 ? Shiftl((BITBOARD)     \
        Shiftl((unsigned long) (value), (shift)-32), 32) :  \
       (BITBOARD) Shiftl((unsigned long) (value), (shift)))
#  else
#    define SplitShiftl(value,shift) Shiftl((BITBOARD) value,shift)
#  endif

/*
  The length of the following macro is a little excessive as the
  rank_attacks lookup is duplicated.  Making it a function, or passing
  in a temporary variable would simplify it significantly, although
  hopefully the compiler recognizes the common subexpression.
*/
#  define AttacksRankInt(a,boardp)  \
     SplitShiftl(at.rank_attack_bitboards[File(a)][ \
     at.which_attack[File(a)][And(SplitShiftr(   \
     Or((boardp)->w_occupied,(boardp)->b_occupied), \
     (Rank(~(a))<<3)+1),0x3f)]],Rank(~(a))<<3)

/* 
  The final left shift in this is optimizable, but the optimization is
  a little ugly to express.  There is no information that crosses the
  word boundary in the shift so it can be implemented as two separate
  word shifts that are joined together in a long long.
*/
#  define AttacksFileInt(a,boardp)   \
     Shiftl(at.file_attack_bitboards[Rank(a)] [  \
     at.which_attack[Rank(a)] [   \
     And(SplitShiftr((boardp)->occupied_rl90, \
     (File(~(a))<<3)+1),0x3f)]],File(~(a)) )

# if defined(USE_ATTACK_FUNCTIONS)
   extern BITBOARD AttacksRankFunc(int, CHESS_POSITION *);
   extern BITBOARD AttacksFileFunc(int, CHESS_POSITION *);
   extern BITBOARD AttacksDiaga1Func(DIAG_INFO *, CHESS_POSITION *);
   extern BITBOARD AttacksDiagh1Func(DIAG_INFO *, CHESS_POSITION *);

#  define AttacksRank(a) AttacksRankFunc(a,&search)
#  define AttacksFile(a) AttacksFileFunc(a,&search)
#  define AttacksDiaga1(a) AttacksDiaga1Func(&diag_info[a],&search)
#  define AttacksDiagh1(a) AttacksDiagh1Func(&diag_info[a],&search)
# else
#   define AttacksRank(a) AttacksRankInt(a,&search)
#   define AttacksFile(a) AttacksFileInt(a,&search)
#   define AttacksDiaga1(a) AttacksDiaga1Int(&diag_info[a],&search)
#   define AttacksDiagh1(a) AttacksDiagh1Int(&diag_info[a],&search)
# endif

#else

#  define AttacksRank(a)                                               \
      rook_attacks_r0[(a)][And(Shiftr(Or(search.w_occupied,search.b_occupied),\
                                      56-((a)&56)),255)]
#  define AttacksFile(a)                                               \
      rook_attacks_rl90[(a)][And(Shiftr(search.occupied_rl90,   \
                                        56-(((a)&7)<<3)),255)]
#  define AttacksDiaga1(a)                                             \
      bishop_attacks_rl45[(a)][And(Shiftr(search.occupied_rl45, \
                                          bishop_shift_rl45[(a)]),255)]
#  define AttacksDiagh1(a)                                             \
      bishop_attacks_rr45[(a)][And(Shiftr(search.occupied_rr45, \
                                          bishop_shift_rr45[(a)]),255)]
#endif
/*  
    the following macros are used to compute the mobility for a sliding piece.
    The basic idea is the same as the attack vectors above, but the result is 
    an integer mobility factor rather than a bitboard.  this saves having to 
    do a PopCnt() on the attack bit vector, which is much slower.
*/
#  define MobilityRook(a)   (MobilityRank(a)+MobilityFile(a))

#  define MobilityBishop(a) (MobilityDiaga1(a)+MobilityDiagh1(a))

#  define MobilityQueen(a)  (MobilityBishop(a)+MobilityRook(a))

#if defined(COMPACT_ATTACKS)

#  define MobilityDiaga1Int(diagp,boardp)  \
     (diagp)->ad_mobility[(diagp)->ad_which_attack[\
     And (SplitShiftr ((boardp)->occupied_rl45, \
     (diagp)->ad_shift),(diagp)->ad_mask)]]

#  define MobilityDiagh1Int(diagp,boardp)  \
     (diagp)->d_mobility[(diagp)->d_which_attack [    \
     And (SplitShiftr ((boardp)->occupied_rr45, \
     (diagp)->d_shift),(diagp)->d_mask)]]

#  define MobilityRankInt(a,boardp)   \
     at.length8_mobility[File(a)][   \
     at.which_attack[File(a)][   \
     And(SplitShiftr(Or((boardp)->w_occupied, \
     (boardp)->b_occupied),(Rank(~(a))<<3)+1),0x3f)]]

#  define MobilityFileInt(a,boardp)   \
     at.length8_mobility[Rank(a)][   \
     at.which_attack[Rank(a)] [   \
     And(SplitShiftr((boardp)->occupied_rl90,(File(~(a))<<3)+1),0x3f)]]

# if defined(USE_ATTACK_FUNCTIONS)
     extern unsigned MobilityRankFunc(int, CHESS_POSITION *);
     extern unsigned MobilityFileFunc(int, CHESS_POSITION *);
     extern unsigned MobilityDiaga1Func(DIAG_INFO *, CHESS_POSITION *);
     extern unsigned MobilityDiagh1Func(DIAG_INFO *, CHESS_POSITION *);

#    define MobilityRank(a) MobilityRankFunc(a,&search)
#    define MobilityFile(a) MobilityFileFunc(a,&search)
#    define MobilityDiaga1(a) MobilityDiaga1Func(&diag_info[a],&search)
#    define MobilityDiagh1(a) MobilityDiagh1Func(&diag_info[a],&search)
#  else
#    define MobilityRank(a) MobilityRankInt(a,&search)
#    define MobilityFile(a) MobilityFileInt(a,&search)
#    define MobilityDiaga1(a) MobilityDiaga1Int(&diag_info[a],&search)
#    define MobilityDiagh1(a) MobilityDiagh1Int(&diag_info[a],&search)
#  endif

#else
#  define MobilityRank(a)                                                   \
     rook_mobility_r0[(a)][And(Shiftr(Or(search.w_occupied,search.b_occupied),            \
                                      56-((a)&56)),255)]
#  define MobilityFile(a)                                                   \
     rook_mobility_rl90[(a)][And(Shiftr(search.occupied_rl90,   \
                                        56-(((a)&7)<<3)),255)]
#  define MobilityDiaga1(a)                                                 \
     bishop_mobility_rl45[(a)][And(Shiftr(search.occupied_rl45, \
                                          bishop_shift_rl45[(a)]),255)]
#  define MobilityDiagh1(a)                                                 \
     bishop_mobility_rr45[(a)][And(Shiftr(search.occupied_rr45, \
                                          bishop_shift_rr45[(a)]),255)]
#endif

/*  
    the following macros are used to extract the pieces of a move that are
    kept compressed into the rightmost 21 bits of a simple integer.
*/

#  define From(a)             ((a)&63)
#  define To(a)               (((a)>>6)&63)
#  define Piece(a)            (((a)>>12)&7)
#  define Captured(a)         (((a)>>15)&7)
#  define Promote(a)          (((a)>>18)&7)
#  define CaptureOrPromote(a) (((a)>>15)&63)
#  define SetMask(a)          (set_mask[a])
#  define ClearMask(a)        (clear_mask[a])

/*  
    the following macros are used to extract the correct bits for the piece
    type desired.
*/

#  define BlackPawns            search.b_pawn
#  define BlackKnights          search.b_knight
#  define BlackBishops          search.b_bishop
#  define BlackRooks            search.b_rook
#  define BlackQueens           search.b_queen
#  define BlackKing             set_mask[search.black_king]
#  define BlackKingSQ           search.black_king
#  define BlackCastle(ply)      position[ply].b_castle
#  define TotalBlackPawns       search.black_pawns
#  define TotalBlackPieces      search.black_pieces
#  define TotalBlackMaterial    search.black_pieces+search.black_pawns
#  define BlackPieces           search.b_occupied

#  define WhitePawns            search.w_pawn
#  define WhiteKnights          search.w_knight
#  define WhiteBishops          search.w_bishop
#  define WhiteRooks            search.w_rook
#  define WhiteQueens           search.w_queen
#  define WhiteKing             set_mask[search.white_king]
#  define WhiteKingSQ           search.white_king
#  define WhiteCastle(ply)      position[ply].w_castle
#  define TotalWhitePawns       search.white_pawns
#  define TotalWhitePieces      search.white_pieces
#  define TotalWhiteMaterial    search.white_pieces+search.white_pawns
#  define WhitePieces           search.w_occupied

#  define TotalPieces           search.total_pieces

#  define Material              search.material_evaluation
#  define Rule50Moves(ply)      position[ply].rule_50_moves
#  define HashKey               search.hash_key
#  define PawnHashKey           search.pawn_hash_key
#  define EnPassant(ply)        position[ply].enpassant_target
#  define EnPassantTarget(ply)  (EnPassant(ply) ? set_mask[EnPassant(ply)] : 0)
#  define PieceOnSquare(sq)     search.board[sq]
#  define BishopsQueens         search.bishops_queens
#  define RooksQueens           search.rooks_queens
#  define Occupied              Or(search.w_occupied,search.b_occupied)
#  define OccupiedRL90          search.occupied_rl90
#  define OccupiedRL45          search.occupied_rl45
#  define OccupiedRR45          search.occupied_rr45

#  define Sliding(piece)        ((piece) & 4)
#  define SlidingDiag(piece)    (((piece) & 5) == 5)
#  define SlidingRow(piece)     (((piece) & 6) == 6)
/*  
    the following macros are used to Set and Clear a specific bit in the
    second argument.  this is done to make the code more readable, rather
    than to make it faster.
*/
#  define ClearSet(a,b)  b=Xor(a,b)
#  define Clear(a,b)     b=And(clear_mask[a],b)
#  define ClearRL90(a,b) b=And(clear_mask_rl90[a],b)
#  define ClearRL45(a,b) b=And(clear_mask_rl45[a],b)
#  define ClearRR45(a,b) b=And(clear_mask_rr45[a],b)
#  define Set(a,b)       b=Or(set_mask[a],b)
#  define SetRL90(a,b)   b=Or(set_mask_rl90[a],b)
#  define SetRL45(a,b)   b=Or(set_mask_rl45[a],b)
#  define SetRR45(a,b)   b=Or(set_mask_rr45[a],b)

#  define HashPB32(a,b)       b=b_pawn_random32[a]^(b)
#  define HashPW32(a,b)       b=w_pawn_random32[a]^(b)
#  define HashPB(a,b)         b=Xor(b_pawn_random[a],b)
#  define HashPW(a,b)         b=Xor(w_pawn_random[a],b)
#  define HashNB(a,b)         b=Xor(b_knight_random[a],b)
#  define HashNW(a,b)         b=Xor(w_knight_random[a],b)
#  define HashBB(a,b)         b=Xor(b_bishop_random[a],b)
#  define HashBW(a,b)         b=Xor(w_bishop_random[a],b)
#  define HashRB(a,b)         b=Xor(b_rook_random[a],b)
#  define HashRW(a,b)         b=Xor(w_rook_random[a],b)
#  define HashQB(a,b)         b=Xor(b_queen_random[a],b)
#  define HashQW(a,b)         b=Xor(w_queen_random[a],b)
#  define HashKB(a,b)         b=Xor(b_king_random[a],b)
#  define HashKW(a,b)         b=Xor(w_king_random[a],b)
#  define HashEP(a,b)         b=Xor(enpassant_random[a],b)
#  define HashCastleW(a,b)    b=Xor(castle_random_w[a],b);
#  define HashCastleB(a,b)    b=Xor(castle_random_b[a],b);
#  define SavePV(ply,value,ph) do {\
      pv[ply-1].path[ply-1]=current_move[ply-1];\
      pv[ply-1].path_length=ply-1; \
      pv[ply-1].path_hashed=ph; \
      pv[ply-1].path_iteration_depth=iteration_depth;} while(0)
#  define SavePVS(ply,value,ph) do {\
      pv[ply-1].path[ply-1]=current_move[ply-1];\
      pv[ply-1].path_length=ply-1; \
      pv[ply-1].path_hashed=ph; \
      pv[ply-1].path_iteration_depth=iteration_depth; \
      SearchOutput(value,beta);} while(0)
#endif