@@ -48,7 +48,6 @@ extern volatile int ABORT_SIGNAL; // Defined by search.c
4848extern volatile int IS_PONDERING ; // Defined by search.c
4949extern PKNetwork PKNN ; // Defined by network.c
5050
51- pthread_mutex_t PONDERLOCK = PTHREAD_MUTEX_INITIALIZER ;
5251const char * StartPosition = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1" ;
5352
5453int main (int argc , char * * argv ) {
@@ -123,21 +122,11 @@ int main(int argc, char **argv) {
123122 else if (strStartsWith (str , "position" ))
124123 uciPosition (str , & board , chess960 );
125124
126- else if (strStartsWith (str , "go" )) {
127- pthread_mutex_lock (& PONDERLOCK );
128- uciGoStruct .multiPV = multiPV ;
129- uciGoStruct .board = & board ;
130- uciGoStruct .threads = threads ;
131- strncpy (uciGoStruct .str , str , 512 );
132- pthread_create (& pthreadsgo , NULL , & uciGo , & uciGoStruct );
133- pthread_detach (pthreadsgo );
134- }
125+ else if (strStartsWith (str , "go" ))
126+ uciGo (& uciGoStruct , & pthreadsgo , threads , & board , multiPV , str );
135127
136- else if (strEquals (str , "ponderhit" )) {
137- pthread_mutex_lock (& PONDERLOCK );
128+ else if (strEquals (str , "ponderhit" ))
138129 IS_PONDERING = 0 ;
139- pthread_mutex_unlock (& PONDERLOCK );
140- }
141130
142131 else if (strEquals (str , "stop" ))
143132 ABORT_SIGNAL = 1 , IS_PONDERING = 0 ;
@@ -155,101 +144,78 @@ int main(int argc, char **argv) {
155144 return 0 ;
156145}
157146
158- void * uciGo (void * cargo ) {
147+ void uciGo (UCIGoStruct * ucigo , pthread_t * pthread , Thread * threads , Board * board , int multiPV , char * str ) {
159148
160- // Get our starting time as soon as possible
161- double start = get_real_time ();
162-
163- Limits limits = {0 };
164- uint16_t bestMove , ponderMove ;
165- char moveStr [6 ];
166- int score ;
149+ /// Parse the entire "go" command in order to fill out a Limits struct, found at ucigo->limits.
150+ /// After we have processed all of this, we can execute a new search thread, held by *pthread,
151+ /// and detach it.
167152
168- uint64_t nodes = 0 ;
169- int depth = 0 , infinite = 0 ;
170- double wtime = 0 , btime = 0 , movetime = 0 ;
153+ double start = get_real_time ();
154+ double wtime = 0 , btime = 0 ;
171155 double winc = 0 , binc = 0 , mtg = -1 ;
172156
173- int multiPV = ((UCIGoStruct * )cargo )-> multiPV ;
174- char * str = ((UCIGoStruct * )cargo )-> str ;
175- Board * board = ((UCIGoStruct * )cargo )-> board ;
176- Thread * threads = ((UCIGoStruct * )cargo )-> threads ;
157+ char moveStr [6 ];
158+ char * ptr = strtok (str , " " );
177159
178160 uint16_t moves [MAX_MOVES ];
179- int size = genAllLegalMoves (board , moves );
180- int idx = 0 , searchmoves = 0 ;
161+ int size = genAllLegalMoves (board , moves ), idx = 0 ;
181162
182- // Reset global signals
183- IS_PONDERING = 0 ;
163+ Limits * limits = & ucigo -> limits ;
164+ memset ( limits , 0 , sizeof ( Limits )) ;
184165
185- // Init the tokenizer with spaces
186- char * ptr = strtok (str , " " );
166+ IS_PONDERING = FALSE; // Reset PONDERING every time to be safe
187167
188- // Parse any time control and search method information that was sent
189168 for (ptr = strtok (NULL , " " ); ptr != NULL ; ptr = strtok (NULL , " " )) {
190169
170+ // Parse time control conditions
191171 if (strEquals (ptr , "wtime" )) wtime = atoi (strtok (NULL , " " ));
192172 if (strEquals (ptr , "btime" )) btime = atoi (strtok (NULL , " " ));
193173 if (strEquals (ptr , "winc" )) winc = atoi (strtok (NULL , " " ));
194174 if (strEquals (ptr , "binc" )) binc = atoi (strtok (NULL , " " ));
195175 if (strEquals (ptr , "movestogo" )) mtg = atoi (strtok (NULL , " " ));
196- if (strEquals (ptr , "depth" )) depth = atoi (strtok (NULL , " " ));
197- if (strEquals (ptr , "movetime" )) movetime = atoi (strtok (NULL , " " ));
198- if (strEquals (ptr , "nodes" )) nodes = atof (strtok (NULL , " " ));
199176
200- if (strEquals (ptr , "infinite" )) infinite = 1 ;
201- if (strEquals (ptr , "searchmoves" )) searchmoves = 1 ;
202- if (strEquals (ptr , "ponder" )) IS_PONDERING = 1 ;
177+ // Parse special search termination conditions
178+ if (strEquals (ptr , "depth" )) limits -> depthLimit = atoi (strtok (NULL , " " ));
179+ if (strEquals (ptr , "movetime" )) limits -> timeLimit = atoi (strtok (NULL , " " ));
180+ if (strEquals (ptr , "nodes" )) limits -> nodeLimit = atof (strtok (NULL , " " ));
203181
182+ // Parse special search modes
183+ if (strEquals (ptr , "infinite" )) limits -> limitedByNone = TRUE;
184+ if (strEquals (ptr , "searchmoves" )) limits -> limitedByMoves = TRUE;
185+ if (strEquals (ptr , "ponder" )) IS_PONDERING = TRUE;
186+
187+ // Parse any specific moves that we are to search
204188 for (int i = 0 ; i < size ; i ++ ) {
205189 moveToString (moves [i ], moveStr , board -> chess960 );
206- if (strEquals (ptr , moveStr )) limits . searchMoves [idx ++ ] = moves [i ];
190+ if (strEquals (ptr , moveStr )) limits -> searchMoves [idx ++ ] = moves [i ];
207191 }
208192 }
209193
210- // Initialize limits for the search
211- limits .limitedByNone = infinite != 0 ;
212- limits .limitedByTime = movetime != 0 ;
213- limits .limitedByDepth = depth != 0 ;
214- limits .limitedByNodes = nodes != 0 ;
215- limits .limitedBySelf = !depth && !movetime && !infinite && !nodes ;
216- limits .limitedByMoves = searchmoves ;
217- limits .timeLimit = movetime ;
218- limits .depthLimit = depth ;
219- limits .nodeLimit = nodes ;
194+ // Special exit cases: Time, Depth, and Nodes
195+ limits -> limitedByTime = limits -> timeLimit != 0 ;
196+ limits -> limitedByDepth = limits -> depthLimit != 0 ;
197+ limits -> limitedByNodes = limits -> nodeLimit != 0 ;
198+
199+ // No special case nor infinite, so we set our own time
200+ limits -> limitedBySelf = !limits -> depthLimit && !limits -> timeLimit
201+ && !limits -> limitedByNone && !limits -> nodeLimit ;
220202
221203 // Pick the time values for the colour we are playing as
222- limits . start = (board -> turn == WHITE ) ? start : start ;
223- limits . time = (board -> turn == WHITE ) ? wtime : btime ;
224- limits . inc = (board -> turn == WHITE ) ? winc : binc ;
225- limits . mtg = (board -> turn == WHITE ) ? mtg : mtg ;
204+ limits -> start = (board -> turn == WHITE ) ? start : start ;
205+ limits -> time = (board -> turn == WHITE ) ? wtime : btime ;
206+ limits -> inc = (board -> turn == WHITE ) ? winc : binc ;
207+ limits -> mtg = (board -> turn == WHITE ) ? mtg : mtg ;
226208
227209 // Cap our MultiPV search based on the suggested or legal moves
228- limits . multiPV = MIN (multiPV , searchmoves ? idx : size );
210+ limits -> multiPV = MIN (multiPV , limits -> limitedByMoves ? idx : size );
229211
230- // Allow the main thread to respond to ponderhit
231- pthread_mutex_unlock (& PONDERLOCK );
212+ // Prepare the uciGoStruct for the new pthread
213+ ucigo -> board = board ;
214+ ucigo -> threads = threads ;
232215
233- // Execute search, return best and ponder moves
234- getBestMove (threads , board , & limits , & bestMove , & ponderMove , & score );
235-
236- // UCI spec does not want reports until out of pondering
237- while (IS_PONDERING );
238-
239- // Report best move ( we should always have one )
240- moveToString (bestMove , moveStr , board -> chess960 );
241- printf ("bestmove %s " , moveStr );
242-
243- // Report ponder move ( if we have one )
244- if (ponderMove != NONE_MOVE ) {
245- moveToString (ponderMove , moveStr , board -> chess960 );
246- printf ("ponder %s" , moveStr );
247- }
248-
249- // Make sure this all gets reported
250- printf ("\n" ); fflush (stdout );
251-
252- return NULL ;
216+ // Spawn a new thread to handle the search
217+ pthread_create (pthread , NULL , & start_search_threads , ucigo );
218+ pthread_detach (* pthread );
253219}
254220
255221void uciSetOption (char * str , Thread * * threads , int * multiPV , int * chess960 ) {
@@ -363,6 +329,7 @@ void uciPosition(char *str, Board *board, int chess960) {
363329 }
364330}
365331
332+
366333void uciReport (Thread * threads , PVariation * pv , int alpha , int beta ) {
367334
368335 // Gather all of the statistics that the UCI protocol would be
@@ -414,6 +381,7 @@ void uciReportCurrentMove(Board *board, uint16_t move, int currmove, int depth)
414381
415382}
416383
384+
417385int strEquals (char * str1 , char * str2 ) {
418386 return strcmp (str1 , str2 ) == 0 ;
419387}
0 commit comments