5 static int read_rest_list( tree_t * restrict ptree,
6 unsigned int * restrict pmove_list );
8 static int is_move_rest( unsigned int move,
9 const unsigned int * restrict pmove_restraint );
12 make_root_move_list( tree_t * restrict ptree, int flag )
14 unsigned int * restrict pmove;
15 unsigned int arestraint_list[ MAX_LEGAL_MOVES ];
16 int asort[ MAX_LEGAL_MOVES ];
17 unsigned int move, move_best;
18 int i, j, k, h, value, num_root_move, iret, value_pre_pv;
21 if ( flag & flag_refer_rest ) { read_rest_list( ptree, arestraint_list ); }
22 else { arestraint_list[0] = 0; }
24 pmove = ptree->move_last[0];
25 ptree->move_last[1] = GenCaptures( root_turn, pmove );
26 ptree->move_last[1] = GenNoCaptures( root_turn, ptree->move_last[1] );
27 ptree->move_last[1] = GenDrop( root_turn, ptree->move_last[1] );
28 num_root_move = (int)( ptree->move_last[1] - pmove );
30 value_pre_pv = INT_MIN;
33 for ( i = 0; i < num_root_move; i++ )
35 if ( ! ( game_status & flag_nopeek )
36 && ( game_status & ( flag_puzzling | flag_pondering ) )
40 iret = next_cmdline( 0 );
43 game_status |= flag_search_error;
46 else if ( iret == -2 )
48 out_warning( "%s", str_error );
51 else if ( game_status & flag_quit ) { return 1; }
54 iret = procedure( ptree );
57 game_status |= flag_search_error;
61 else if ( iret == -2 )
63 out_warning( "%s", str_error );
67 else if ( iret == 1 ) { next_cmdline( 1 ); }
69 if ( game_status & ( flag_quit | flag_quit_ponder
80 MakeMove( root_turn, move, 1 );
81 if ( ! InCheck( root_turn )
82 && ! is_move_rest( move, arestraint_list ) )
85 if ( InCheck(Flip(root_turn)) )
88 = (unsigned char)( ptree->nsuc_check[0] + 1U );
89 if ( ptree->nsuc_check[2] >= 2 * 2 )
91 iret = detect_repetition( ptree, 2, Flip(root_turn), 2 );
95 if ( iret == perpetual_check ) { value = INT_MIN; }
97 ptree->current_move[1] = move;
98 value = -search_quies( ptree, -score_bound, score_bound,
99 Flip(root_turn), 2, 1 );
100 if ( value > value_best )
105 if ( I2IsPromote(move) ) { value++; }
106 if ( move == ptree->pv[0].a[1] )
108 value_pre_pv = value;
113 UnMakeMove( root_turn, move, 1 );
116 if ( UToCap(move_best) ) { root_move_cap = 1; }
119 for ( k = SHELL_H_LEN - 1; k >= 0; k-- )
122 for ( i = num_root_move-h-1; i >= 0; i-- )
126 for ( j = i+h; j < num_root_move && asort[j] > value; j += h )
128 asort[j-h] = asort[j];
129 pmove[j-h] = pmove[j];
136 /* discard all of moves cause mate or perpetual check */
137 if ( asort[0] >= -score_max_eval )
139 for ( ; num_root_move; num_root_move-- )
141 if ( asort[num_root_move-1] >= -score_max_eval ) { break; }
145 /* discard perpetual checks */
146 else for ( ; num_root_move; num_root_move-- )
148 if ( asort[num_root_move-1] != INT_MIN ) { break; }
151 for ( i = 0; i < num_root_move; i++ )
153 root_move_list[i].move = pmove[i];
154 root_move_list[i].nodes = 0;
155 root_move_list[i].status = 0;
157 if ( value_pre_pv != INT_MIN ) { asort[0] = value_pre_pv; }
158 root_nmove = num_root_move;
160 if ( num_root_move > 1 && ! ( game_status & flag_puzzling ) )
162 int id_easy_move = 0;
164 if ( asort[0] > asort[1] + ( MT_CAP_DRAGON * 3 ) / 8 )
167 easy_min = - ( MT_CAP_DRAGON * 4 ) / 16;
168 easy_max = ( MT_CAP_DRAGON * 32 ) / 16;
169 easy_abs = ( MT_CAP_DRAGON * 19 ) / 16;
171 else if ( asort[0] > asort[1] + ( MT_CAP_DRAGON * 2 ) / 8 )
174 easy_min = - ( MT_CAP_DRAGON * 3 ) / 16;
175 easy_max = ( MT_CAP_DRAGON * 6 ) / 16;
176 easy_abs = ( MT_CAP_DRAGON * 9 ) / 16;
178 else if ( asort[0] > asort[1] + MT_CAP_DRAGON / 8
179 && asort[0] > - MT_CAP_DRAGON / 8
180 && I2From(pmove[0]) < nsquare )
183 easy_min = - ( MT_CAP_DRAGON * 2 ) / 16;
184 easy_max = ( MT_CAP_DRAGON * 4 ) / 16;
185 easy_abs = ( MT_CAP_DRAGON * 6 ) / 16;
190 Out( "\n the root move %s looks easy (type %d).\n",
191 str_CSA_move(pmove[0]), id_easy_move );
192 Out( " evasion:%d, capture:%d, promotion:%d, drop:%d, "
194 ptree->nsuc_check[1] ? 1 : 0,
195 UToCap(pmove[0]) ? 1 : 0,
196 I2IsPromote(pmove[0]) ? 1 : 0,
197 I2From(pmove[0]) >= nsquare ? 1 : 0,
198 asort[0], asort[1] );
199 easy_value = asort[0];
208 read_rest_list( tree_t * restrict ptree, unsigned int * restrict pmove_list )
214 if ( analyze_mode ) { // [HGM] exclude: in analyze mode we use the interactively updated list in stead of the file
215 for ( imove = 0; imove < MAX_LEGAL_MOVES && exclude_list[imove]; imove++ )
216 pmove_list[imove] = exclude_list[imove];
217 pmove_list[imove] = 0;
221 pf = file_open( "restraint.dat", "r" );
222 if ( pf == NULL ) { return -2; }
224 for ( imove = 0; imove < MAX_LEGAL_MOVES; imove++ )
226 #if defined(_MSC_VER)
227 iret = fscanf_s( pf, "%s\n", a, 65536 );
229 iret = fscanf( pf, "%s\n", a );
231 if ( iret != 1 ) { break; }
232 iret = interpret_CSA_move( ptree, pmove_list+imove, a );
240 pmove_list[imove] = 0;
242 return file_close( pf );
247 is_move_rest( unsigned int move,
248 const unsigned int * restrict pmove_restraint )
250 while ( *pmove_restraint )
252 if ( move == *pmove_restraint++ ) { return 1; }