~ubuntu-branches/ubuntu/trusty/fruit/trusty

« back to all changes in this revision

Viewing changes to .pc/01-simple_go.patch/src/protocol.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Oliver Korff
  • Date: 2011-03-28 13:32:15 UTC
  • mfrom: (2.1.4 sid)
  • Revision ID: james.westby@ubuntu.com-20110328133215-dn813u8xrlz1poem
Tags: 2.1.dfsg-5
* Remove of README.Source file
* Switch to dpkg-source 3.0 (quilt) format
* Removed the knights dependencies, because knights is not longer 
  available for updates. Removed related documentation accordingly.
* Added no stripping to the Makefile.
* New standards version: 3.9.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
// protocol.cpp
 
3
 
 
4
// includes
 
5
 
 
6
#include <cstdarg>
 
7
#include <cstdio>
 
8
#include <cstdlib>
 
9
#include <cstring>
 
10
 
 
11
#include "board.h"
 
12
#include "book.h"
 
13
#include "eval.h"
 
14
#include "fen.h"
 
15
#include "material.h"
 
16
#include "move.h"
 
17
#include "move_do.h"
 
18
#include "move_legal.h"
 
19
#include "option.h"
 
20
#include "pawn.h"
 
21
#include "posix.h"
 
22
#include "protocol.h"
 
23
#include "pst.h"
 
24
#include "search.h"
 
25
#include "trans.h"
 
26
#include "util.h"
 
27
 
 
28
// constants
 
29
 
 
30
#define VERSION "2.1"
 
31
 
 
32
static const double NormalRatio = 1.0;
 
33
static const double PonderRatio = 1.25;
 
34
 
 
35
// variables
 
36
 
 
37
static bool Init;
 
38
 
 
39
static bool Searching; // search in progress?
 
40
static bool Infinite; // infinite or ponder mode?
 
41
static bool Delay; // postpone "bestmove" in infinite/ponder mode?
 
42
 
 
43
// prototypes
 
44
 
 
45
static void init              ();
 
46
static void loop_step         ();
 
47
 
 
48
static void parse_go          (char string[]);
 
49
static void parse_position    (char string[]);
 
50
static void parse_setoption   (char string[]);
 
51
 
 
52
static void send_best_move    ();
 
53
 
 
54
static bool string_equal      (const char s1[], const char s2[]);
 
55
static bool string_start_with (const char s1[], const char s2[]);
 
56
 
 
57
// functions
 
58
 
 
59
// loop()
 
60
 
 
61
void loop() {
 
62
 
 
63
   // init (to help debugging)
 
64
 
 
65
   Init = false;
 
66
 
 
67
   Searching = false;
 
68
   Infinite = false;
 
69
   Delay = false;
 
70
 
 
71
   search_clear();
 
72
 
 
73
   board_from_fen(SearchInput->board,StartFen);
 
74
 
 
75
   // loop
 
76
 
 
77
   while (true) loop_step();
 
78
}
 
79
 
 
80
// init()
 
81
 
 
82
static void init() {
 
83
 
 
84
   if (!Init) {
 
85
 
 
86
      // late initialisation
 
87
 
 
88
      Init = true;
 
89
 
 
90
      if (option_get_bool("OwnBook")) {
 
91
         book_open(option_get_string("BookFile"));
 
92
      }
 
93
 
 
94
      trans_alloc(Trans);
 
95
 
 
96
      pawn_init();
 
97
      pawn_alloc();
 
98
 
 
99
      material_init();
 
100
      material_alloc();
 
101
 
 
102
      pst_init();
 
103
      eval_init();
 
104
   }
 
105
}
 
106
 
 
107
// event()
 
108
 
 
109
void event() {
 
110
 
 
111
   while (!SearchInfo->stop && input_available()) loop_step();
 
112
}
 
113
 
 
114
// loop_step()
 
115
 
 
116
static void loop_step() {
 
117
 
 
118
   char string[65536];
 
119
 
 
120
   // read a line
 
121
 
 
122
   get(string,65536);
 
123
 
 
124
   // parse
 
125
 
 
126
   if (false) {
 
127
 
 
128
   } else if (string_start_with(string,"debug ")) {
 
129
 
 
130
      // dummy
 
131
 
 
132
   } else if (string_start_with(string,"go ")) {
 
133
 
 
134
      if (!Searching && !Delay) {
 
135
         init();
 
136
         parse_go(string);
 
137
      } else {
 
138
         ASSERT(false);
 
139
      }
 
140
 
 
141
   } else if (string_equal(string,"isready")) {
 
142
 
 
143
      if (!Searching && !Delay) {
 
144
         init();
 
145
      }
 
146
 
 
147
      send("readyok"); // no need to wait when searching (dixit SMK)
 
148
 
 
149
   } else if (string_equal(string,"ponderhit")) {
 
150
 
 
151
      if (Searching) {
 
152
 
 
153
         ASSERT(Infinite);
 
154
 
 
155
         SearchInput->infinite = false;
 
156
         Infinite = false;
 
157
 
 
158
      } else if (Delay) {
 
159
 
 
160
         send_best_move();
 
161
         Delay = false;
 
162
 
 
163
      } else {
 
164
 
 
165
         ASSERT(false);
 
166
      }
 
167
 
 
168
   } else if (string_start_with(string,"position ")) {
 
169
 
 
170
      if (!Searching && !Delay) {
 
171
         init();
 
172
         parse_position(string);
 
173
      } else {
 
174
         ASSERT(false);
 
175
      }
 
176
 
 
177
   } else if (string_equal(string,"quit")) {
 
178
 
 
179
      ASSERT(!Searching);
 
180
      ASSERT(!Delay);
 
181
 
 
182
      exit(EXIT_SUCCESS);
 
183
 
 
184
   } else if (string_start_with(string,"setoption ")) {
 
185
 
 
186
      if (!Searching && !Delay) {
 
187
         parse_setoption(string);
 
188
      } else {
 
189
         ASSERT(false);
 
190
      }
 
191
 
 
192
   } else if (string_equal(string,"stop")) {
 
193
 
 
194
      if (Searching) {
 
195
 
 
196
         SearchInfo->stop = true;
 
197
         Infinite = false;
 
198
 
 
199
      } else if (Delay) {
 
200
 
 
201
         send_best_move();
 
202
         Delay = false;
 
203
      }
 
204
 
 
205
   } else if (string_equal(string,"uci")) {
 
206
 
 
207
      ASSERT(!Searching);
 
208
      ASSERT(!Delay);
 
209
 
 
210
      send("id name Fruit " VERSION);
 
211
      send("id author Fabien Letouzey");
 
212
 
 
213
      option_list();
 
214
 
 
215
      send("uciok");
 
216
 
 
217
   } else if (string_equal(string,"ucinewgame")) {
 
218
 
 
219
      if (!Searching && !Delay && Init) {
 
220
         trans_clear(Trans);
 
221
      } else {
 
222
         ASSERT(false);
 
223
      }
 
224
   }
 
225
}
 
226
 
 
227
// parse_go()
 
228
 
 
229
static void parse_go(char string[]) {
 
230
 
 
231
   const char * ptr;
 
232
   bool infinite, ponder;
 
233
   int depth, mate, movestogo;
 
234
   sint64 nodes;
 
235
   double binc, btime, movetime, winc, wtime;
 
236
   double time, inc;
 
237
   double time_max, alloc;
 
238
 
 
239
   // init
 
240
 
 
241
   infinite = false;
 
242
   ponder = false;
 
243
 
 
244
   depth = -1;
 
245
   mate = -1;
 
246
   movestogo = -1;
 
247
 
 
248
   nodes = -1;
 
249
 
 
250
   binc = -1.0;
 
251
   btime = -1.0;
 
252
   movetime = -1.0;
 
253
   winc = -1.0;
 
254
   wtime = -1.0;
 
255
 
 
256
   // parse
 
257
 
 
258
   ptr = strtok(string," "); // skip "go"
 
259
 
 
260
   for (ptr = strtok(NULL," "); ptr != NULL; ptr = strtok(NULL," ")) {
 
261
 
 
262
      if (false) {
 
263
 
 
264
      } else if (string_equal(ptr,"binc")) {
 
265
 
 
266
         ptr = strtok(NULL," ");
 
267
         if (ptr == NULL) my_fatal("parse_go(): missing argument\n");
 
268
 
 
269
         binc = double(atoi(ptr)) / 1000.0;
 
270
         ASSERT(binc>=0.0);
 
271
 
 
272
      } else if (string_equal(ptr,"btime")) {
 
273
 
 
274
         ptr = strtok(NULL," ");
 
275
         if (ptr == NULL) my_fatal("parse_go(): missing argument\n");
 
276
 
 
277
         btime = double(atoi(ptr)) / 1000.0;
 
278
         ASSERT(btime>=0.0);
 
279
 
 
280
      } else if (string_equal(ptr,"depth")) {
 
281
 
 
282
         ptr = strtok(NULL," ");
 
283
         if (ptr == NULL) my_fatal("parse_go(): missing argument\n");
 
284
 
 
285
         depth = atoi(ptr);
 
286
         ASSERT(depth>=0);
 
287
 
 
288
      } else if (string_equal(ptr,"infinite")) {
 
289
 
 
290
         infinite = true;
 
291
 
 
292
      } else if (string_equal(ptr,"mate")) {
 
293
 
 
294
         ptr = strtok(NULL," ");
 
295
         if (ptr == NULL) my_fatal("parse_go(): missing argument\n");
 
296
 
 
297
         mate = atoi(ptr);
 
298
         ASSERT(mate>=0);
 
299
 
 
300
      } else if (string_equal(ptr,"movestogo")) {
 
301
 
 
302
         ptr = strtok(NULL," ");
 
303
         if (ptr == NULL) my_fatal("parse_go(): missing argument\n");
 
304
 
 
305
         movestogo = atoi(ptr);
 
306
         ASSERT(movestogo>=0);
 
307
 
 
308
      } else if (string_equal(ptr,"movetime")) {
 
309
 
 
310
         ptr = strtok(NULL," ");
 
311
         if (ptr == NULL) my_fatal("parse_go(): missing argument\n");
 
312
 
 
313
         movetime = double(atoi(ptr)) / 1000.0;
 
314
         ASSERT(movetime>=0.0);
 
315
 
 
316
      } else if (string_equal(ptr,"nodes")) {
 
317
 
 
318
         ptr = strtok(NULL," ");
 
319
         if (ptr == NULL) my_fatal("parse_go(): missing argument\n");
 
320
 
 
321
         nodes = my_atoll(ptr);
 
322
         ASSERT(nodes>=0);
 
323
 
 
324
      } else if (string_equal(ptr,"ponder")) {
 
325
 
 
326
         ponder = true;
 
327
 
 
328
      } else if (string_equal(ptr,"searchmoves")) {
 
329
 
 
330
         // dummy
 
331
 
 
332
      } else if (string_equal(ptr,"winc")) {
 
333
 
 
334
         ptr = strtok(NULL," ");
 
335
         if (ptr == NULL) my_fatal("parse_go(): missing argument\n");
 
336
 
 
337
         winc = double(atoi(ptr)) / 1000.0;
 
338
         ASSERT(winc>=0.0);
 
339
 
 
340
      } else if (string_equal(ptr,"wtime")) {
 
341
 
 
342
         ptr = strtok(NULL," ");
 
343
         if (ptr == NULL) my_fatal("parse_go(): missing argument\n");
 
344
 
 
345
         wtime = double(atoi(ptr)) / 1000.0;
 
346
         ASSERT(wtime>=0.0);
 
347
      }
 
348
   }
 
349
 
 
350
   // init
 
351
 
 
352
   search_clear();
 
353
 
 
354
   // depth limit
 
355
 
 
356
   if (depth >= 0) {
 
357
      SearchInput->depth_is_limited = true;
 
358
      SearchInput->depth_limit = depth;
 
359
   } else if (mate >= 0) {
 
360
      SearchInput->depth_is_limited = true;
 
361
      SearchInput->depth_limit = mate * 2 - 1; // HACK: move -> ply
 
362
   }
 
363
 
 
364
   // time limit
 
365
 
 
366
   if (COLOUR_IS_WHITE(SearchInput->board->turn)) {
 
367
      time = wtime;
 
368
      inc = winc;
 
369
   } else {
 
370
      time = btime;
 
371
      inc = binc;
 
372
   }
 
373
 
 
374
   if (movestogo <= 0 || movestogo > 30) movestogo = 30; // HACK
 
375
   if (inc < 0.0) inc = 0.0;
 
376
 
 
377
   if (movetime >= 0.0) {
 
378
 
 
379
      // fixed time
 
380
 
 
381
      SearchInput->time_is_limited = true;
 
382
      SearchInput->time_limit_1 = movetime * 5.0; // HACK to avoid early exit
 
383
      SearchInput->time_limit_2 = movetime;
 
384
 
 
385
   } else if (time >= 0.0) {
 
386
 
 
387
      // dynamic allocation
 
388
 
 
389
      time_max = time * 0.95 - 1.0;
 
390
      if (time_max < 0.0) time_max = 0.0;
 
391
 
 
392
      SearchInput->time_is_limited = true;
 
393
 
 
394
      alloc = (time_max + inc * double(movestogo-1)) / double(movestogo);
 
395
      alloc *= (option_get_bool("Ponder") ? PonderRatio : NormalRatio);
 
396
      if (alloc > time_max) alloc = time_max;
 
397
      SearchInput->time_limit_1 = alloc;
 
398
 
 
399
      alloc = (time_max + inc * double(movestogo-1)) * 0.5;
 
400
      if (alloc < SearchInput->time_limit_1) alloc = SearchInput->time_limit_1;
 
401
      if (alloc > time_max) alloc = time_max;
 
402
      SearchInput->time_limit_2 = alloc;
 
403
   }
 
404
 
 
405
   if (infinite || ponder) SearchInput->infinite = true;
 
406
 
 
407
   // search
 
408
 
 
409
   ASSERT(!Searching);
 
410
   ASSERT(!Delay);
 
411
 
 
412
   Searching = true;
 
413
   Infinite = infinite || ponder;
 
414
   Delay = false;
 
415
 
 
416
   search();
 
417
   search_update_current();
 
418
 
 
419
   ASSERT(Searching);
 
420
   ASSERT(!Delay);
 
421
 
 
422
   Searching = false;
 
423
   Delay = Infinite;
 
424
 
 
425
   if (!Delay) send_best_move();
 
426
}
 
427
 
 
428
// parse_position()
 
429
 
 
430
static void parse_position(char string[]) {
 
431
 
 
432
   const char * fen;
 
433
   char * moves;
 
434
   const char * ptr;
 
435
   char move_string[256];
 
436
   int move;
 
437
   undo_t undo[1];
 
438
 
 
439
   // init
 
440
 
 
441
   fen = strstr(string,"fen ");
 
442
   moves = strstr(string,"moves ");
 
443
 
 
444
   // start position
 
445
 
 
446
   if (fen != NULL) { // "fen" present
 
447
 
 
448
      if (moves != NULL) { // "moves" present
 
449
         ASSERT(moves>fen);
 
450
         moves[-1] = '\0'; // dirty, but so is UCI
 
451
      }
 
452
 
 
453
      board_from_fen(SearchInput->board,fen+4); // CHANGE ME
 
454
 
 
455
   } else {
 
456
 
 
457
      // HACK: assumes startpos
 
458
 
 
459
      board_from_fen(SearchInput->board,StartFen);
 
460
   }
 
461
 
 
462
   // moves
 
463
 
 
464
   if (moves != NULL) { // "moves" present
 
465
 
 
466
      ptr = moves + 6;
 
467
 
 
468
      while (*ptr != '\0') {
 
469
 
 
470
         move_string[0] = *ptr++;
 
471
         move_string[1] = *ptr++;
 
472
         move_string[2] = *ptr++;
 
473
         move_string[3] = *ptr++;
 
474
 
 
475
         if (*ptr == '\0' || *ptr == ' ') {
 
476
            move_string[4] = '\0';
 
477
         } else { // promote
 
478
            move_string[4] = *ptr++;
 
479
            move_string[5] = '\0';
 
480
         }
 
481
 
 
482
         move = move_from_string(move_string,SearchInput->board);
 
483
 
 
484
         move_do(SearchInput->board,move,undo);
 
485
 
 
486
         while (*ptr == ' ') ptr++;
 
487
      }
 
488
   }
 
489
}
 
490
 
 
491
// parse_setoption()
 
492
 
 
493
static void parse_setoption(char string[]) {
 
494
 
 
495
   const char * name;
 
496
   char * value;
 
497
 
 
498
   // init
 
499
 
 
500
   name = strstr(string,"name ");
 
501
   value = strstr(string,"value ");
 
502
 
 
503
   if (name == NULL || value == NULL || name >= value) return; // ignore buttons
 
504
 
 
505
   value[-1] = '\0'; // HACK
 
506
   name += 5;
 
507
   value += 6;
 
508
 
 
509
   // update
 
510
 
 
511
   option_set(name,value);
 
512
 
 
513
   // update transposition-table size if needed
 
514
 
 
515
   if (Init && my_string_equal(name,"Hash")) { // Init => already allocated
 
516
 
 
517
      ASSERT(!Searching);
 
518
 
 
519
      if (option_get_int("Hash") >= 4) {
 
520
         trans_free(Trans);
 
521
         trans_alloc(Trans);
 
522
      }
 
523
   }
 
524
}
 
525
 
 
526
// send_best_move()
 
527
 
 
528
static void send_best_move() {
 
529
 
 
530
   double time, speed, cpu;
 
531
   sint64 node_nb;
 
532
   char move_string[256];
 
533
   char ponder_string[256];
 
534
   int move;
 
535
   mv_t * pv;
 
536
 
 
537
   // info
 
538
 
 
539
   // HACK: should be in search.cpp
 
540
 
 
541
   time = SearchCurrent->time;
 
542
   speed = SearchCurrent->speed;
 
543
   cpu = SearchCurrent->cpu;
 
544
   node_nb = SearchCurrent->node_nb;
 
545
 
 
546
   send("info time %.0f nodes " S64_FORMAT " nps %.0f cpuload %.0f",time*1000.0,node_nb,speed,cpu*1000.0);
 
547
 
 
548
   trans_stats(Trans);
 
549
   // pawn_stats();
 
550
   // material_stats();
 
551
 
 
552
   // best move
 
553
 
 
554
   move = SearchBest->move;
 
555
   pv = SearchBest->pv;
 
556
 
 
557
   move_to_string(move,move_string,256);
 
558
 
 
559
   if (pv[0] == move && move_is_ok(pv[1])) {
 
560
      move_to_string(pv[1],ponder_string,256);
 
561
      send("bestmove %s ponder %s",move_string,ponder_string);
 
562
   } else {
 
563
      send("bestmove %s",move_string);
 
564
   }
 
565
}
 
566
 
 
567
// get()
 
568
 
 
569
void get(char string[], int size) {
 
570
 
 
571
   ASSERT(string!=NULL);
 
572
   ASSERT(size>=65536);
 
573
 
 
574
   if (!my_file_read_line(stdin,string,size)) { // EOF
 
575
      exit(EXIT_SUCCESS);
 
576
   }
 
577
}
 
578
 
 
579
// send()
 
580
 
 
581
void send(const char format[], ...) {
 
582
 
 
583
   va_list arg_list;
 
584
   char string[4096];
 
585
 
 
586
   ASSERT(format!=NULL);
 
587
 
 
588
   va_start(arg_list,format);
 
589
   vsprintf(string,format,arg_list);
 
590
   va_end(arg_list);
 
591
 
 
592
   fprintf(stdout,"%s\n",string);
 
593
}
 
594
 
 
595
// string_equal()
 
596
 
 
597
static bool string_equal(const char s1[], const char s2[]) {
 
598
 
 
599
   ASSERT(s1!=NULL);
 
600
   ASSERT(s2!=NULL);
 
601
 
 
602
   return strcmp(s1,s2) == 0;
 
603
}
 
604
 
 
605
// string_start_with()
 
606
 
 
607
static bool string_start_with(const char s1[], const char s2[]) {
 
608
 
 
609
   ASSERT(s1!=NULL);
 
610
   ASSERT(s2!=NULL);
 
611
 
 
612
   return strstr(s1,s2) == s1;
 
613
}
 
614
 
 
615
// end of protocol.cpp
 
616