Force iteration to start at 1 in analyze mode
[bonanza.git] / debug.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include "shogi.h"
4
5 #if !defined(NDEBUG)
6
7 #  define DOut(str)                                                          \
8   out_error( "invalid %s: node= %" PRIu64 "\n", str, ptree->node_searched ); \
9   return 0;
10
11 #  define CheckNum( piece )                                      \
12   if ( n ## piece ## _max - n ## piece ## _box != n ## piece ) { \
13     DOut( "number of " # piece );                                \
14   }
15
16 #  define CheckBoard( PIECE, piece )                           \
17   bb = BB_B ## PIECE;                                          \
18   while( BBToU( bb ) ) {                                       \
19     sq = FirstOne( bb );                                       \
20     Xor( sq, bb );                                             \
21     if ( BOARD[sq] != piece ) { DOut( "BB_B" # PIECE  ); }     \
22   }                                                            \
23   bb = BB_W ## PIECE;                                          \
24   while( BBToU( bb ) ) {                                       \
25     sq = FirstOne( bb );                                       \
26     Xor( sq, bb );                                             \
27     if ( BOARD[sq] != -piece ) { DOut( "BB_W" # PIECE  ); }  \
28   }
29
30 int
31 exam_bb( const tree_t *ptree )
32 {
33   bitboard_t bb;
34   uint64_t hk;
35   int npawn, nlance, nknight, nsilver, ngold, nbishop, nrook, npiece;
36   int sq, mate;
37
38   /* leading zero-bits */
39   if ( root_turn               & ~0x0000001U ) { DOut( "root_turn" ); }
40   if ( HAND_B                  & ~0x01fffffU ) { DOut( "HAND_B" ); }
41   if ( HAND_W                  & ~0x01fffffU ) { DOut( "HAND_W" ); }
42   if ( BBToU(OCCUPIED_FILE)    & ~0x7ffffffU ) { DOut( "OCCUPIED_FILE" ); }
43   if ( BBToU(OCCUPIED_DIAG2)   & ~0x7ffffffU ) { DOut( "OCCUPIED_DIAG2" ); }
44   if ( BBToU(OCCUPIED_DIAG1)   & ~0x7ffffffU ) { DOut( "OCCUPIED_DIAG1" ); }
45
46   if ( BBToU(BB_BOCCUPY)       & ~0x7ffffffU ) { DOut( "BB_BOCCUPY" ); }
47   if ( BBToU(BB_BPAWN_ATK)     & ~0x7ffffffU ) { DOut( "BB_BPAWN_ATK" ); }
48   if ( BBToU(BB_BTGOLD)        & ~0x7ffffffU ) { DOut( "BB_BTGOLD" ); }
49   if ( BBToU(BB_B_HDK)         & ~0x7ffffffU ) { DOut( "BB_B_HDK" ); }
50   if ( BBToU(BB_B_BH)          & ~0x7ffffffU ) { DOut( "BB_B_BH" ); }
51   if ( BBToU(BB_B_RD)          & ~0x7ffffffU ) { DOut( "BB_B_RD" ); }
52   if ( BBToU(BB_BPAWN)         & ~0x7ffffffU ) { DOut( "BB_BPAWN" ); }
53   if ( BBToU(BB_BLANCE)        & ~0x7ffffffU ) { DOut( "BB_BLANCE" ); }
54   if ( BBToU(BB_BKNIGHT)       & ~0x7ffffffU ) { DOut( "BB_BKNIGHT" ); }
55   if ( BBToU(BB_BSILVER)       & ~0x7ffffffU ) { DOut( "BB_BSILVER" ); }
56   if ( BBToU(BB_BGOLD)         & ~0x7ffffffU ) { DOut( "BB_BGOLD" ); }
57   if ( BBToU(BB_BBISHOP)       & ~0x7ffffffU ) { DOut( "BB_BBISHOP" ); }
58   if ( BBToU(BB_BROOK)         & ~0x7ffffffU ) { DOut( "BB_BROOK" ); }
59   if ( BBToU(BB_BPRO_PAWN)     & ~0x7ffffffU ) { DOut( "BB_BPRO_PAWN" ); }
60   if ( BBToU(BB_BPRO_LANCE)    & ~0x7ffffffU ) { DOut( "BB_BPRO_LANCE" ); }
61   if ( BBToU(BB_BPRO_KNIGHT)   & ~0x7ffffffU ) { DOut( "BB_BPRO_KNIGHT" ); }
62   if ( BBToU(BB_BPRO_SILVER)   & ~0x7ffffffU ) { DOut( "BB_BPRO_SILVER" ); }
63   if ( BBToU(BB_BHORSE)        & ~0x7ffffffU ) { DOut( "BB_BHORSE" ); }
64   if ( BBToU(BB_BDRAGON)       & ~0x7ffffffU ) { DOut( "BB_BDRAGON" ); }
65
66   if ( BBToU(BB_WOCCUPY)       & ~0x7ffffffU ) { DOut( "BB_WOCCUPY" ); }
67   if ( BBToU(BB_WPAWN_ATK)     & ~0x7ffffffU ) { DOut( "BB_WPAWN_ATK" ); }
68   if ( BBToU(BB_WTGOLD)        & ~0x7ffffffU ) { DOut( "BB_WTGOLD" ); }
69   if ( BBToU(BB_W_HDK)         & ~0x7ffffffU ) { DOut( "BB_W_HDK" ); }
70   if ( BBToU(BB_W_BH)          & ~0x7ffffffU ) { DOut( "BB_W_BH" ); }
71   if ( BBToU(BB_W_RD)          & ~0x7ffffffU ) { DOut( "BB_W_RD" ); }
72   if ( BBToU(BB_WPAWN)         & ~0x7ffffffU ) { DOut( "BB_WPAWN" ); }
73   if ( BBToU(BB_WLANCE)        & ~0x7ffffffU ) { DOut( "BB_WLANCE" ); }
74   if ( BBToU(BB_WKNIGHT)       & ~0x7ffffffU ) { DOut( "BB_WKNIGHT" ); }
75   if ( BBToU(BB_WSILVER)       & ~0x7ffffffU ) { DOut( "BB_WSILVER" ); }
76   if ( BBToU(BB_WGOLD)         & ~0x7ffffffU ) { DOut( "BB_WGOLD" ); }
77   if ( BBToU(BB_WBISHOP)       & ~0x7ffffffU ) { DOut( "BB_WBISHOP" ); }
78   if ( BBToU(BB_WROOK)         & ~0x7ffffffU ) { DOut( "BB_WROOK" ); }
79   if ( BBToU(BB_WPRO_PAWN)     & ~0x7ffffffU ) { DOut( "BB_WPRO_PAWN" ); }
80   if ( BBToU(BB_WPRO_LANCE)    & ~0x7ffffffU ) { DOut( "BB_WPRO_LANCE" ); }
81   if ( BBToU(BB_WPRO_KNIGHT)   & ~0x7ffffffU ) { DOut( "BB_WPRO_KNIGHT" ); }
82   if ( BBToU(BB_WPRO_SILVER)   & ~0x7ffffffU ) { DOut( "BB_WPRO_SILVER" ); }
83   if ( BBToU(BB_WHORSE)        & ~0x7ffffffU ) { DOut( "BB_WHORSE" ); }
84   if ( BBToU(BB_WDRAGON)       & ~0x7ffffffU ) { DOut( "BB_WDRAGON" ); }
85
86   if ( BB_BPAWN.p[0]           &  0x7fc0000U ) { DOut( "pawn at rank1" ); }
87   if ( BB_BKNIGHT.p[0]         &  0x7fffe00U ) { DOut( "knight at rank1-2" ); }
88
89   if ( BB_WPAWN.p[2]           &  0x00001ffU ) { DOut( "pawn at rank9" ); }
90   if ( BB_WKNIGHT.p[2]         &  0x003ffffU ) { DOut( "knight at rank8-9" ); }
91
92
93   /* number of pieces */
94   BBOr( bb, BB_BPAWN, BB_WPAWN );
95   BBOr( bb, BB_BPRO_PAWN, bb );
96   BBOr( bb, BB_WPRO_PAWN, bb );
97   npawn = I2HandPawn(HAND_B) + I2HandPawn(HAND_W) + PopuCount(bb);
98   CheckNum( pawn );
99     
100   BBOr( bb, BB_BLANCE, BB_WLANCE );
101   BBOr( bb, BB_BPRO_LANCE, bb );
102   BBOr( bb, BB_WPRO_LANCE, bb );
103   nlance = I2HandLance(HAND_B) + I2HandLance(HAND_W) + PopuCount(bb);
104   CheckNum( lance );
105
106   BBOr( bb, BB_BKNIGHT, BB_WKNIGHT );
107   BBOr( bb, BB_BPRO_KNIGHT, bb );
108   BBOr( bb, BB_WPRO_KNIGHT, bb );
109   nknight = I2HandKnight(HAND_B) + I2HandKnight(HAND_W) + PopuCount(bb);
110   CheckNum( knight );
111
112   BBOr( bb, BB_BSILVER, BB_WSILVER );
113   BBOr( bb, BB_BPRO_SILVER, bb );
114   BBOr( bb, BB_WPRO_SILVER, bb );
115   nsilver = I2HandSilver(HAND_B) + I2HandSilver(HAND_W) + PopuCount(bb);
116   CheckNum( silver );
117
118   BBOr( bb, BB_BGOLD, BB_WGOLD );
119   ngold = I2HandGold(HAND_B) + I2HandGold(HAND_W) + PopuCount(bb);
120   CheckNum( gold );
121
122   BBOr( bb, BB_BBISHOP, BB_WBISHOP );
123   BBOr( bb, bb, BB_BHORSE );
124   BBOr( bb, bb, BB_WHORSE );
125   nbishop = I2HandBishop(HAND_B) + I2HandBishop(HAND_W) + PopuCount(bb);
126   CheckNum( bishop );
127
128   BBOr( bb, BB_BROOK, BB_WROOK );
129   BBOr( bb, bb, BB_BDRAGON );
130   BBOr( bb, bb, BB_WDRAGON );
131   nrook = I2HandRook(HAND_B) + I2HandRook(HAND_W) + PopuCount(bb);
132   CheckNum( rook );
133
134
135   /* consistency of redundant bitboards */
136   BBOr( bb, BB_BGOLD, BB_BPRO_PAWN );
137   BBOr( bb, bb, BB_BPRO_LANCE );
138   BBOr( bb, bb, BB_BPRO_KNIGHT );
139   BBOr( bb, bb, BB_BPRO_SILVER );
140   if ( BBCmp( bb, BB_BTGOLD ) ) { DOut( "BB_BTGOLD" ); }
141
142   BBOr( bb, BB_BBISHOP, BB_BHORSE );
143   if ( BBCmp( bb, BB_B_BH ) ) { DOut( "BB_B_BH" ); }
144
145   BBOr( bb, BB_BROOK, BB_BDRAGON );
146   if ( BBCmp( bb, BB_B_RD ) ) { DOut( "BB_B_RD" ); }
147
148   BBOr( bb, BB_BHORSE, BB_BDRAGON );
149   BBOr( bb, BB_BKING, bb );
150   if ( BBCmp( bb, BB_B_HDK ) ) { DOut( "BB_B_HDK" ); }
151
152   bb.p[0]  = ( BB_BPAWN.p[0] <<  9 ) & 0x7ffffffU;
153   bb.p[0] |= ( BB_BPAWN.p[1] >> 18 ) & 0x00001ffU;
154   bb.p[1]  = ( BB_BPAWN.p[1] <<  9 ) & 0x7ffffffU;
155   bb.p[1] |= ( BB_BPAWN.p[2] >> 18 ) & 0x00001ffU;
156   bb.p[2]  = ( BB_BPAWN.p[2] <<  9 ) & 0x7ffffffU;
157   if ( BBCmp( bb, BB_BPAWN_ATK ) ) { DOut( "BB_BPAWN_ATK" ); }
158
159   BBOr( bb, BB_BPAWN, BB_BLANCE );
160   BBOr( bb, bb, BB_BKNIGHT );
161   BBOr( bb, bb, BB_BSILVER );
162   BBOr( bb, bb, BB_BTGOLD );
163   BBOr( bb, bb, BB_BBISHOP );
164   BBOr( bb, bb, BB_BROOK );
165   BBOr( bb, bb, BB_B_HDK );
166   if ( BBCmp( bb, BB_BOCCUPY ) ) { DOut( "BB_BOCCUPY" ); }
167       
168   BBOr( bb, BB_WPRO_PAWN, BB_WGOLD );
169   BBOr( bb, BB_WPRO_LANCE, bb );
170   BBOr( bb, BB_WPRO_KNIGHT, bb );
171   BBOr( bb, BB_WPRO_SILVER, bb );
172   if ( BBCmp( bb, BB_WTGOLD ) ) { DOut( "BB_WTGOLD" ); }
173
174   BBOr( bb, BB_WBISHOP, BB_WHORSE );
175   if ( BBCmp( bb, BB_W_BH ) ) { DOut( "BB_W_BH" ); }
176
177   BBOr( bb, BB_WROOK, BB_WDRAGON );
178   if ( BBCmp( bb, BB_W_RD ) ) { DOut( "BB_W_RD" ); }
179
180   BBOr( bb, BB_WHORSE, BB_WDRAGON );
181   BBOr( bb, BB_WKING, bb );
182   if ( BBCmp( bb, BB_W_HDK ) ) { DOut( "BB_W_HDK" ); }
183
184   bb.p[2]  = ( BB_WPAWN.p[2] >>  9 );
185   bb.p[2] |= ( BB_WPAWN.p[1] << 18 ) & 0x7fc0000U;
186   bb.p[1]  = ( BB_WPAWN.p[1] >>  9 );
187   bb.p[1] |= ( BB_WPAWN.p[0] << 18 ) & 0x7fc0000U;
188   bb.p[0]  = ( BB_WPAWN.p[0] >>  9 );
189   if ( BBCmp( bb, BB_WPAWN_ATK ) ) { DOut( "BB_WPAWN_ATK" ); }
190
191   BBOr( bb, BB_WPAWN, BB_WLANCE );
192   BBOr( bb, BB_WKNIGHT, bb );
193   BBOr( bb, BB_WSILVER, bb );
194   BBOr( bb, BB_WTGOLD, bb );
195   BBOr( bb, BB_WBISHOP, bb );
196   BBOr( bb, BB_WROOK, bb );
197   BBOr( bb, BB_W_HDK, bb );
198   if ( BBCmp( bb, BB_WOCCUPY ) ) { DOut( "BB_WOCCUPY" ); }
199       
200   /* consistency of board-array */
201   CheckBoard( PAWN,        pawn );
202   CheckBoard( LANCE,       lance );
203   CheckBoard( KNIGHT,      knight );
204   CheckBoard( SILVER,      silver );
205   CheckBoard( GOLD,        gold );
206   CheckBoard( BISHOP,      bishop );
207   CheckBoard( ROOK,        rook );
208   CheckBoard( KING,        king );
209   CheckBoard( PRO_PAWN,    pro_pawn );
210   CheckBoard( PRO_LANCE,   pro_lance );
211   CheckBoard( PRO_KNIGHT,  pro_knight );
212   CheckBoard( PRO_SILVER,  pro_silver );
213   CheckBoard( HORSE,       horse );
214   CheckBoard( DRAGON,      dragon );
215
216   for ( sq = npiece = 0; sq < nsquare; sq++ )
217     {
218       if ( BOARD[sq] ) { npiece++; }
219     }
220   if ( npiece != PopuCount( OCCUPIED_FILE ) )  { DOut( "OCCUPIED_FILE" ); }
221   if ( npiece != PopuCount( OCCUPIED_DIAG2 ) ) { DOut( "OCCUPIED_DIAG2" ); }
222   if ( npiece != PopuCount( OCCUPIED_DIAG1 ) ) { DOut( "OCCUPIED_DIAG1" ); }
223
224
225   /* Material and Hash signature */
226   mate = eval_material( ptree );
227   if ( mate != MATERIAL ) { DOut( "value of material" ); }
228
229   hk = hash_func( ptree );
230   if ( hk != HASH_KEY  ) { DOut( "hash signature" ); }
231
232   if ( BOARD[SQ_BKING] !=  king ) { DOut( "SQ_BKING" ); }
233   if ( BOARD[SQ_WKING] != -king ) { DOut( "SQ_WKING" ); }
234
235   return 1;
236 }
237
238 #  undef DOut
239 #  undef CheckNum
240 #  undef CheckBoard
241
242 #endif  /* no NDEBUG */