Fix force mode after setboard
[bonanza.git] / movgenex.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include "shogi.h"
4
5
6 #define BAddMoveCap(piece)                                             \
7             utemp = From2Move(from) | Piece2Move(piece);               \
8             while ( BBTest( bb_move ) ) {                              \
9               to       = LastOne( bb_move );                           \
10               *pmove++ = To2Move(to) | Cap2Move(-BOARD[to]) | utemp;   \
11               Xor( to, bb_move ); }
12
13 #define BAddMove(piece) utemp = From2Move(from) | Piece2Move(piece);   \
14                         while ( BBTest( bb_move ) ) {                  \
15                         to       = LastOne( bb_move );                 \
16                         *pmove++ = To2Move(to) | utemp;                \
17                         Xor( to, bb_move ); }
18
19
20 #define WAddMoveCap(piece)                                             \
21             utemp = From2Move(from) | Piece2Move(piece);               \
22             while ( BBTest( bb_move ) ) {                              \
23               to      = FirstOne( bb_move );                           \
24               *pmove++ = To2Move(to) | Cap2Move(BOARD[to]) | utemp;    \
25               Xor( to, bb_move ); }
26
27 #define WAddMove(piece) utemp = From2Move(from) | Piece2Move(piece);   \
28                          while ( BBTest( bb_move ) ) {                 \
29                            to       = FirstOne( bb_move );             \
30                            *pmove++ = To2Move(to) | utemp;             \
31                            Xor( to, bb_move ); }
32
33
34 unsigned int * CONV
35 b_gen_cap_nopro_ex2( const tree_t * restrict ptree,
36                      unsigned int * restrict pmove )
37 {
38   int from, to;
39   unsigned int utemp, ubb_piece0, ubb_piece1, ubb_piece2, ubb_move0;
40   bitboard_t bb_target, bb_move, bb_piece;
41
42   bb_target = BB_WOCCUPY;
43
44   ubb_move0 = BB_BPAWN_ATK.p[0] & bb_target.p[0] & 0x003ffffU;
45   while( ubb_move0 )
46     {
47       to   = last_one0( ubb_move0 );
48       from = to + 9;
49       *pmove++ = To2Move(to) | From2Move(from)
50         | Cap2Move(-BOARD[to]) | Piece2Move(pawn);
51       ubb_move0 ^= abb_mask[to].p[0];
52     }
53
54   ubb_piece1 = BB_BBISHOP.p[1];
55   ubb_piece2 = BB_BBISHOP.p[2];
56   while( ubb_piece1 | ubb_piece2 )
57     {
58       from     = last_one12( ubb_piece1, ubb_piece2 );
59       ubb_move0 = BishopAttack0(from) & bb_target.p[0];
60       utemp     = From2Move(from) | Piece2Move(bishop);
61       while ( ubb_move0 )
62         {
63           to      = last_one0( ubb_move0 );
64           *pmove++ = To2Move(to) | Cap2Move(-BOARD[to]) | utemp;
65           ubb_move0 ^= abb_mask[to].p[0];
66         }
67       ubb_piece1 ^= abb_mask[from].p[1];
68       ubb_piece2 ^= abb_mask[from].p[2];
69     }
70   ubb_piece0 = BB_BBISHOP.p[0];
71   while( ubb_piece0 )
72     {
73       from = last_one0( ubb_piece0 );
74       AttackBishop( bb_move, from );
75       BBAnd( bb_move, bb_move, bb_target );
76       BAddMoveCap( bishop );
77       ubb_piece0 ^= abb_mask[from].p[0];
78     }
79
80   ubb_piece1 = BB_BROOK.p[1];
81   ubb_piece2 = BB_BROOK.p[2];
82   while( ubb_piece1 | ubb_piece2 )
83     {
84       from     = last_one12( ubb_piece1, ubb_piece2 );
85       AttackRook( bb_move, from );
86       ubb_move0 = bb_move.p[0] & bb_target.p[0];
87       utemp = From2Move(from) | Piece2Move(rook);
88       while ( ubb_move0 )
89         {
90           to      = last_one0( ubb_move0 );
91           *pmove++ = To2Move(to) | Cap2Move(-BOARD[to]) | utemp;
92           ubb_move0 ^= abb_mask[to].p[0];
93         }
94       ubb_piece1 ^= abb_mask[from].p[1];
95       ubb_piece2 ^= abb_mask[from].p[2];
96     }
97   ubb_piece0 = BB_BROOK.p[0];
98   while( ubb_piece0 )
99     {
100       from     = last_one0( ubb_piece0 );
101       AttackRook( bb_move, from );
102       BBAnd( bb_move, bb_move, bb_target );
103       BAddMoveCap( rook );
104       ubb_piece0 ^= abb_mask[from].p[0];
105     }
106
107   bb_piece = BB_BLANCE;
108   bb_target.p[0] &= 0x3fe00;
109   while( BBTest( bb_piece ) )
110     {
111       from     = LastOne( bb_piece );
112       ubb_move0 = AttackFile(from).p[0]
113         & abb_minus_rays[from].p[0] & bb_target.p[0];
114       utemp = From2Move(from) | Piece2Move(lance);
115       while ( ubb_move0 )
116         {
117           to      = last_one0( ubb_move0 );
118           *pmove++ = To2Move(to) | Cap2Move(-BOARD[to]) | utemp;
119           ubb_move0 ^= abb_mask[to].p[0];
120         }
121       Xor( from, bb_piece );
122     }
123
124   return pmove;
125 }
126
127
128 unsigned int * CONV
129 b_gen_nocap_nopro_ex2( const tree_t * restrict ptree,
130                        unsigned int * restrict pmove )
131 {
132   bitboard_t bb_target, bb_move, bb_piece;
133   unsigned int ubb_piece0, ubb_piece1, ubb_piece2, ubb_move0, ubb_target0;
134   unsigned int utemp;
135   int to, from;
136
137   BBOr( bb_target, BB_BOCCUPY, BB_WOCCUPY );
138   BBNot( bb_target, bb_target );
139
140   ubb_move0 = BB_BPAWN_ATK.p[0] & bb_target.p[0] & 0x003ffffU;
141   while( ubb_move0 )
142     {
143       to   = last_one0( ubb_move0 );
144       from = to + 9;
145       *pmove++ = To2Move(to) | From2Move(from) | Piece2Move(pawn);
146       ubb_move0 ^= abb_mask[to].p[0];
147     }
148
149   ubb_piece1 = BB_BBISHOP.p[1];
150   ubb_piece2 = BB_BBISHOP.p[2];
151   while( ubb_piece1 | ubb_piece2 )
152     {
153       from     = last_one12( ubb_piece1, ubb_piece2 );
154       ubb_move0 = BishopAttack0(from) & bb_target.p[0];
155       utemp     = From2Move(from) | Piece2Move(bishop);
156       while ( ubb_move0 )
157         {
158           to      = last_one0( ubb_move0 );
159           *pmove++ = To2Move(to) | utemp;
160           ubb_move0 ^= abb_mask[to].p[0];
161         }
162       ubb_piece1 ^= abb_mask[from].p[1];
163       ubb_piece2 ^= abb_mask[from].p[2];
164     }
165   ubb_piece0 = BB_BBISHOP.p[0];
166   while( ubb_piece0 )
167     {
168       from = last_one0( ubb_piece0 );
169       AttackBishop( bb_move, from );
170       BBAnd( bb_move, bb_move, bb_target );
171       BAddMove( bishop );
172       ubb_piece0 ^= abb_mask[from].p[0];
173     }
174
175   ubb_piece1 = BB_BROOK.p[1];
176   ubb_piece2 = BB_BROOK.p[2];
177   while( ubb_piece1 | ubb_piece2 )
178     {
179       from     = last_one12( ubb_piece1, ubb_piece2 );
180       AttackRook( bb_move, from );
181       ubb_move0 = bb_move.p[0] & bb_target.p[0];
182       utemp = From2Move(from) | Piece2Move(rook);
183       while ( ubb_move0 )
184         {
185           to      = last_one0( ubb_move0 );
186           *pmove++ = To2Move(to) | utemp;
187           ubb_move0 ^= abb_mask[to].p[0];
188         }
189       ubb_piece1 ^= abb_mask[from].p[1];
190       ubb_piece2 ^= abb_mask[from].p[2];
191     }
192   ubb_piece0 = BB_BROOK.p[0];
193   while( ubb_piece0 )
194     {
195       from     = last_one0( ubb_piece0 );
196       AttackRook( bb_move, from );
197       BBAnd( bb_move, bb_move, bb_target );
198       BAddMove( rook );
199       ubb_piece0 ^= abb_mask[from].p[0];
200     }
201
202   bb_piece = BB_BLANCE;
203   ubb_target0 = bb_target.p[0] & 0x3fe00;
204   while( BBTest( bb_piece ) )
205     {
206       from     = LastOne( bb_piece );
207       ubb_move0 = AttackFile(from).p[0]
208         & abb_minus_rays[from].p[0] & ubb_target0;
209       utemp = From2Move(from) | Piece2Move(lance);
210       while ( ubb_move0 )
211         {
212           to = last_one0( ubb_move0 );
213           *pmove++ = To2Move(to) | utemp;
214           ubb_move0 ^= abb_mask[to].p[0];
215         }
216       Xor( from, bb_piece );
217     }
218
219   return pmove;
220 }
221
222
223 unsigned int * CONV
224 w_gen_cap_nopro_ex2( const tree_t * restrict ptree,
225                      unsigned int * restrict pmove )
226 {
227   bitboard_t bb_target, bb_move, bb_piece;
228   unsigned int utemp, ubb_piece0, ubb_piece1, ubb_piece2, ubb_move2;
229   int from, to;
230
231   bb_target = BB_BOCCUPY;
232
233   ubb_move2 = BB_WPAWN_ATK.p[2] & bb_target.p[2] & 0x7fffe00U;
234   while( ubb_move2 )
235     {
236       to   = first_one2( ubb_move2 );
237       from = to - 9;
238       *pmove++ = To2Move(to) | From2Move(from)
239         | Cap2Move(BOARD[to]) | Piece2Move(pawn);
240       ubb_move2 ^= abb_mask[to].p[2];
241     }
242
243   ubb_piece0 = BB_WBISHOP.p[0];
244   ubb_piece1 = BB_WBISHOP.p[1];
245   while( ubb_piece0 | ubb_piece1 )
246     {
247       from     = first_one01( ubb_piece0, ubb_piece1 );
248       ubb_move2 = BishopAttack2(from) & bb_target.p[2];
249       utemp     = From2Move(from) | Piece2Move(bishop);
250       while ( ubb_move2 )
251         {
252           to      = first_one2( ubb_move2 );
253           *pmove++ = To2Move(to) | Cap2Move(BOARD[to]) | utemp;
254           ubb_move2 ^= abb_mask[to].p[2];
255         }
256       ubb_piece0 ^= abb_mask[from].p[0];
257       ubb_piece1 ^= abb_mask[from].p[1];
258     }
259   ubb_piece2 = BB_WBISHOP.p[2];
260   while( ubb_piece2 )
261     {
262       from = first_one2( ubb_piece2 );
263       AttackBishop( bb_move, from );
264       BBAnd( bb_move, bb_move, bb_target );
265       WAddMoveCap( bishop );
266       ubb_piece2 ^= abb_mask[from].p[2];
267     }
268
269   ubb_piece0 = BB_WROOK.p[0];
270   ubb_piece1 = BB_WROOK.p[1];
271   while( ubb_piece0 | ubb_piece1 )
272     {
273       from     = first_one01( ubb_piece0, ubb_piece1 );
274       AttackRook( bb_move, from );
275       ubb_move2 = bb_move.p[2] & bb_target.p[2];
276       utemp     = From2Move(from) | Piece2Move(rook);
277       while ( ubb_move2 )
278         {
279           to      = first_one2( ubb_move2 );
280           *pmove++ = To2Move(to) | Cap2Move(BOARD[to]) | utemp;
281           ubb_move2 ^= abb_mask[to].p[2];
282         }
283       ubb_piece0 ^= abb_mask[from].p[0];
284       ubb_piece1 ^= abb_mask[from].p[1];
285     }
286   ubb_piece2 = BB_WROOK.p[2];
287   while( ubb_piece2 )
288     {
289       from     = first_one2( ubb_piece2 );
290       AttackRook( bb_move, from );
291       BBAnd( bb_move, bb_move, bb_target );
292       WAddMoveCap( rook );
293       ubb_piece2 ^= abb_mask[from].p[2];
294     }
295
296   bb_piece = BB_WLANCE;
297   bb_target.p[2] &= 0x3fe00;
298   while( BBTest( bb_piece ) )
299     {
300       from      = FirstOne( bb_piece );
301       ubb_move2 = AttackFile(from).p[2]
302         & abb_plus_rays[from].p[2] & bb_target.p[2];
303       utemp = From2Move(from) | Piece2Move(lance);
304       while ( ubb_move2 )
305         {
306           to       = first_one2( ubb_move2 );
307           *pmove++ = To2Move(to) | Cap2Move(BOARD[to]) | utemp;
308           ubb_move2 ^= abb_mask[to].p[2];
309         }
310       Xor( from, bb_piece );
311     }
312
313   return pmove;
314 }
315
316
317 unsigned int * CONV
318 w_gen_nocap_nopro_ex2( const tree_t * restrict ptree,
319                        unsigned int * restrict pmove )
320 {
321   bitboard_t bb_target, bb_piece, bb_move;
322   unsigned int ubb_piece0, ubb_piece1, ubb_piece2, ubb_move2, ubb_target2;
323   unsigned int utemp;
324   int to, from;
325
326   BBOr( bb_target, BB_BOCCUPY, BB_WOCCUPY );
327   BBNot( bb_target, bb_target );
328
329   ubb_move2 = BB_WPAWN_ATK.p[2] & bb_target.p[2] & 0x7fffe00U;;
330   while( ubb_move2 )
331     {
332       to   = first_one2( ubb_move2 );
333       from = to - 9;
334       *pmove++ = To2Move(to) | From2Move(from) | Piece2Move(pawn);
335       ubb_move2 ^= abb_mask[to].p[2];
336     }
337
338   ubb_piece0 = BB_WBISHOP.p[0];
339   ubb_piece1 = BB_WBISHOP.p[1];
340   while( ubb_piece0 | ubb_piece1 )
341     {
342       from     = first_one01( ubb_piece0, ubb_piece1 );
343       ubb_move2 = BishopAttack2(from) & bb_target.p[2];
344       utemp     = From2Move(from) | Piece2Move(bishop);
345       while ( ubb_move2 )
346         {
347           to      = first_one2( ubb_move2 );
348           *pmove++ = To2Move(to) | utemp;
349           ubb_move2 ^= abb_mask[to].p[2];
350         }
351       ubb_piece0 ^= abb_mask[from].p[0];
352       ubb_piece1 ^= abb_mask[from].p[1];
353     }
354   ubb_piece2 = BB_WBISHOP.p[2];
355   while( ubb_piece2 )
356     {
357       from = first_one2( ubb_piece2 );
358       AttackBishop( bb_move, from );
359       BBAnd( bb_move, bb_move, bb_target );
360       WAddMove( bishop );
361       ubb_piece2 ^= abb_mask[from].p[2];
362     }
363
364   ubb_piece0 = BB_WROOK.p[0];
365   ubb_piece1 = BB_WROOK.p[1];
366   while( ubb_piece0 | ubb_piece1 )
367     {
368       from      = first_one01( ubb_piece0, ubb_piece1 );
369       AttackRook( bb_move, from );
370       ubb_move2 = bb_move.p[2] & bb_target.p[2];
371       utemp     = From2Move(from) | Piece2Move(rook);
372       while ( ubb_move2 )
373         {
374           to       = first_one2( ubb_move2 );
375           *pmove++ = To2Move(to) | utemp;
376           ubb_move2 ^= abb_mask[to].p[2];
377         }
378       ubb_piece0 ^= abb_mask[from].p[0];
379       ubb_piece1 ^= abb_mask[from].p[1];
380     }
381   ubb_piece2 = BB_WROOK.p[2];
382   while( ubb_piece2 )
383     {
384       from     = first_one2( ubb_piece2 );
385       AttackRook( bb_move, from );
386       BBAnd( bb_move, bb_move, bb_target );
387       WAddMove( rook );
388       ubb_piece2 ^= abb_mask[from].p[2];
389     }
390
391   bb_piece = BB_WLANCE;
392   ubb_target2 = bb_target.p[2] & 0x3fe00;
393   while( BBTest( bb_piece ) )
394     {
395       from = FirstOne( bb_piece );
396       ubb_move2 = AttackFile(from).p[2]
397         & abb_plus_rays[from].p[2] & ubb_target2;
398       utemp = From2Move(from) | Piece2Move(lance);
399       while ( ubb_move2 )
400         {
401           to = first_one2( ubb_move2 );
402           *pmove++ = To2Move(to) | utemp;
403           ubb_move2 ^= abb_mask[to].p[2];
404         }
405       Xor( from, bb_piece );
406     }
407
408   return pmove;
409 }
410
411
412 #undef BAddMoveCap
413 #undef BAddMove
414 #undef WAddMoveCap
415 #undef WAddMove