7 gen_next_move( tree_t * restrict ptree, int ply, int turn )
9 switch ( ptree->anext_move[ply].next_phase )
13 unsigned int * restrict pmove;
14 int * restrict psortv = ptree->sort_value;
15 unsigned int move, killer1, killer2, move_hash, move_best, move_second;
16 int i, j, sortv, n, value_best, value_second, value, remaining;
18 ptree->anext_move[ply].phase_done = 0;
19 ptree->anext_move[ply].next_phase = next_move_capture;
20 ptree->anext_move[ply].move_last = pmove = ptree->move_last[ply];
21 ptree->move_last[ply] = GenCaptures( turn, pmove );
23 move_hash = ptree->amove_hash[ply];
24 killer1 = ptree->amove_killer[ply].no1;
25 killer2 = ptree->amove_killer[ply].no2;
27 move_best = move_second = 0;
28 value_best = value_second = 0;
29 n = (int)( ptree->move_last[ply] - pmove );
30 for ( i = 0; i < n; i++ )
33 sortv = swap( ptree, move, -1, INT_MAX, turn );
34 if ( sortv > value_best )
36 move_second = move_best;
37 value_second = value_best;
41 else if ( sortv > value_second )
46 if ( move == move_hash ) { sortv = INT_MIN; }
47 else if ( UToFromToPromo(move) == killer1 )
50 value = ptree->amove_killer[ply].no1_value
51 + p_value_ex[15U+UToCap(move)];
52 if ( sortv < value ) { sortv = value; }
53 if ( sortv > -1 ) { remaining++; }
55 else if ( UToFromToPromo(move) == killer2 )
58 value = ptree->amove_killer[ply].no2_value
59 + p_value_ex[15U+UToCap(move)];
60 if ( sortv < value ) { sortv = value; }
61 if ( sortv > -1 ) { remaining++; }
63 else if ( sortv > -1 ) { remaining++; }
68 && killer1 != move_hash
69 && ptree->amove_killer[ply].no1_value > -1
70 && is_move_valid( ptree, killer1, turn ) )
72 *( ptree->move_last[ply]++ ) = killer1;
73 psortv[n++] = ptree->amove_killer[ply].no1_value;
78 && killer2 != move_hash
79 && ptree->amove_killer[ply].no2_value > -1
80 && is_move_valid( ptree, killer2, turn ) )
82 *( ptree->move_last[ply]++ ) = killer2;
83 psortv[n++] = ptree->amove_killer[ply].no2_value;
87 ptree->anext_move[ply].value_cap1 = value_best;
88 ptree->anext_move[ply].move_cap1 = move_best;
89 ptree->anext_move[ply].value_cap2 = value_second;
90 ptree->anext_move[ply].move_cap2 = move_second;
91 ptree->anext_move[ply].remaining = remaining;
95 for ( i = n-2; i >= 0; i-- )
97 sortv = psortv[i]; move = pmove[i];
98 for ( j = i+1; psortv[j] > sortv; j++ )
100 psortv[j-1] = psortv[j]; pmove[j-1] = pmove[j];
102 psortv[j-1] = sortv; pmove[j-1] = move;
104 if ( psortv[n-1] == INT_MIN ) { ptree->move_last[ply]--; }
106 #if ! defined(MINIMUM)
107 if ( move_hash && ! is_move_valid( ptree, move_hash, turn ) )
109 out_warning( "An invalid hash move is found!!" );
110 ptree->amove_hash[ply] = move_hash = 0U;
116 if ( move_hash == move_best )
118 ptree->anext_move[ply].phase_done |= phase_cap1;
121 if ( UToFromToPromo(move_hash) == killer1 )
123 ptree->anext_move[ply].phase_done |= phase_killer1;
125 else if ( UToFromToPromo(move_hash) == killer2 )
127 ptree->anext_move[ply].phase_done |= phase_killer2;
129 ptree->anext_move[ply].phase_done |= phase_hash;
130 MOVE_CURR = move_hash;
135 case next_move_capture:
136 if ( ptree->anext_move[ply].remaining-- )
140 MOVE_CURR = move = *(ptree->anext_move[ply].move_last++);
141 if ( move == ptree->anext_move[ply].move_cap1 )
143 ptree->anext_move[ply].phase_done |= phase_cap1;
146 if ( UToFromToPromo(move) == ptree->amove_killer[ply].no1 )
148 ptree->anext_move[ply].phase_done |= phase_killer1;
150 else if ( UToFromToPromo(move) == ptree->amove_killer[ply].no2 )
152 ptree->anext_move[ply].phase_done |= phase_killer2;
158 unsigned int * restrict pmove;
159 unsigned int value_best, value, key, good, tried;
164 ptree->move_last[ply] = GenNoCaptures( turn, ptree->move_last[ply] );
165 ptree->move_last[ply] = GenDrop( turn, ptree->move_last[ply] );
167 n = (int)( ptree->move_last[ply] - ptree->anext_move[ply].move_last );
168 pmove = ptree->anext_move[ply].move_last;
169 for ( i = 0; i < n; i++ )
171 if ( pmove[i] == ptree->amove_hash[ply]
172 || ( pmove[i] == ptree->amove_killer[ply].no1
173 && ( ptree->anext_move[ply].phase_done
175 || ( pmove[i] == ptree->amove_killer[ply].no2
176 && ( ptree->anext_move[ply].phase_done
177 & phase_killer2 ) ) )
183 if ( UToCap(pmove[i]) ) { continue; }
184 if ( I2IsPromote(pmove[i])
185 && I2PieceMove(pmove[i]) != silver ) { continue; }
188 key = phash( pmove[i], turn );
189 good = ptree->hist_good[key] + 1;
190 tried = ptree->hist_tried[key] + 2;
191 value = ( good * 8192U ) / tried;
192 if ( value > value_best )
201 ptree->anext_move[ply].phase_done |= phase_history1;
202 ptree->anext_move[ply].next_phase = next_move_history2;
203 MOVE_CURR = pmove[ibest];
209 case next_move_history2:
211 unsigned int * restrict pmove;
212 unsigned int value_best, value, key, good, tried;
215 ptree->anext_move[ply].next_phase = next_move_misc;
218 n = (int)( ptree->move_last[ply] - ptree->anext_move[ply].move_last );
219 pmove = ptree->anext_move[ply].move_last;
221 for ( i = 0; i < n; i++ )
223 if ( UToCap(pmove[i]) ) { continue; }
224 if ( I2IsPromote(pmove[i])
225 && I2PieceMove(pmove[i]) != silver ) { continue; }
227 key = phash( pmove[i], turn );
228 good = ptree->hist_good[key] + 1;
229 tried = ptree->hist_tried[key] + 2;
230 value = ( good * 8192U ) / tried;
231 if ( value > value_best && pmove[i] )
240 ptree->anext_move[ply].phase_done |= phase_history2;
241 MOVE_CURR = pmove[ibest];
248 assert( ptree->anext_move[ply].next_phase == next_move_misc );
249 while ( ptree->anext_move[ply].move_last < ptree->move_last[ply] )
251 if ( *( ptree->anext_move[ply].move_last ) )
253 MOVE_CURR = *(ptree->anext_move[ply].move_last++);
254 ptree->anext_move[ply].phase_done |= phase_misc;
257 ptree->anext_move[ply].move_last++;
265 gen_next_evasion( tree_t * restrict ptree, int ply, int turn )
267 switch ( ptree->anext_move[ply].next_phase )
269 case next_evasion_hash:
270 ptree->move_last[ply] = GenEvasion( turn, ptree->move_last[ply] );
272 if ( ptree->amove_hash[ply] )
274 #if ! defined(MINIMUM)
275 unsigned int * restrict p;
277 for ( p = ptree->move_last[ply-1]; p < ptree->move_last[ply]; p++ )
278 if ( *p == ptree->amove_hash[ply] ) { break; }
280 if ( *p != ptree->amove_hash[ply] )
282 out_warning( "An invalid hash evasion-move is found!!" );
283 out_board( ptree, stdout, 0, 0 );
284 Out( "%c%s\n", ach_turn[turn],
285 str_CSA_move(ptree->amove_hash[ply]) );
286 Out( "hash key = %" PRIu64 ", hand = %u, turn = %d\n",
287 HASH_KEY, HAND_B, turn );
288 ptree->amove_hash[ply] = 0U;
293 ptree->anext_move[ply].next_phase = next_evasion_genall;
294 ptree->current_move[ply] = ptree->amove_hash[ply];
299 case next_evasion_genall:
301 unsigned int * restrict pmove;
302 int * restrict psortv;
306 ptree->anext_move[ply].next_phase = next_evasion_misc;
307 ptree->anext_move[ply].move_last = pmove = ptree->move_last[ply-1];
308 n = (int)( ptree->move_last[ply] - pmove );
309 psortv = ptree->sort_value;
311 for ( i = n-1; i >= 0; i-- )
314 if ( move == ptree->amove_hash[ply] )
319 else if ( I2PieceMove(move) == king )
321 sortv = p_value_ex[UToCap(move)+15] * 2;
324 sortv = swap( ptree, move, INT_MIN, INT_MAX, turn );
325 sortv += estimate_score_diff( ptree, move, turn );
332 for ( i = n-2; i >= 0; i-- )
334 sortv = psortv[i]; move = pmove[i];
335 for ( j = i+1; psortv[j] > sortv; j++ )
337 psortv[j-1] = psortv[j]; pmove[j-1] = pmove[j];
339 psortv[j-1] = sortv; pmove[j-1] = move;
344 assert( ptree->anext_move[ply].next_phase == next_evasion_misc );
345 while ( ptree->anext_move[ply].move_last < ptree->move_last[ply] )
347 if ( *( ptree->anext_move[ply].move_last ) )
349 MOVE_CURR = *(ptree->anext_move[ply].move_last++);
352 ptree->anext_move[ply].move_last++;