Scid  4.6.5
pbook.cpp
Go to the documentation of this file.
1 //////////////////////////////////////////////////////////////////////
2 //
3 // FILE: pbook.cpp
4 // PBook class methods
5 //
6 // Part of: Scid (Shane's Chess Information Database)
7 // Version: 2.3
8 //
9 // Notice: Copyright (c) 1999-2000 Shane Hudson. All rights reserved.
10 //
11 // Author: Shane Hudson (sgh@users.sourceforge.net)
12 //
13 //////////////////////////////////////////////////////////////////////
14 
15 
16 // A PBook is a collection of chess positions, each with a textual
17 // comment or description.
18 
19 
20 #include "common.h"
21 #include "dstring.h"
22 #include "pbook.h"
23 #include "misc.h"
24 #include "mfile.h"
25 
26 
27 // PBOOK_HASH_BITS: Size of array of hash value counts.
28 static const uint PBOOK_HASH_BITS = 65536;
29 static const uint PBOOK_HASH_BYTES = (PBOOK_HASH_BITS >> 3);
30 #define PBOOK_HASH(pos) ((pos)->HashValue() & (PBOOK_HASH_BITS - 1))
31 
32 typedef char compactBoardStr [36];
33 
34 
35 void
36 PBook::SetHashFlag (Position * pos) {
37  uint hash = PBOOK_HASH(pos);
38  uint index = hash >> 3;
39  uint mask = 1 << (hash & 7);
40  if (HashFlags == NULL) {
41  HashFlags = new byte [PBOOK_HASH_BYTES];
42  for (uint i=0; i < PBOOK_HASH_BYTES >> 3; i++) { HashFlags[i] = 0; }
43  }
44  HashFlags[index] |= mask;
45 }
46 
47 bool
48 PBook::GetHashFlag (Position * pos)
49 {
50  uint hash = PBOOK_HASH(pos);
51  uint index = hash >> 3;
52  uint mask = 1 << (hash & 7);
53  if (HashFlags == NULL) { return true; }
54  return ((HashFlags[index] & mask) != 0);
55 }
56 
57 
58 void
59 PBook::AddNodeToList (bookNodeT * node)
60 {
61  ASSERT (NodeListCount <= NodeListCapacity);
62  if (NodeListCount >= NodeListCapacity) {
63  NodeListCapacity += NodeListCapacity;
64  bookNodePtrT * newlist = new bookNodePtrT [NodeListCapacity];
65  for (uint i=0; i < NodeListCount; i++) {
66  newlist[i] = NodeList[i];
67  }
68  delete[] NodeList;
69  NodeList = newlist;
70  }
71  NodeList[NodeListCount] = node;
72  node->data.id = NodeListCount;
73  NodeListCount++;
74 }
75 
76 void
78 {
79  Altered = false;
80  ReadOnly = false;
81  LeastMaterial = PBOOK_MAX_MATERIAL;
82  SkipCount = 0;
83  FileName = NULL;
84  for (uint t=0; t <= PBOOK_MAX_MATERIAL; t++) {
85  Tree[t] = new StrTree<bookDataT>;
86  }
87  NextIndex = 0;
88  Stats_PositionBytes = 0;
89  Stats_CommentBytes = 0;
90  for (uint i=0; i <= PBOOK_MAX_MATERIAL; i++) {
91  Stats_Lookups[i] = Stats_Inserts[i] = 0;
92  }
93  Stats_TotalLookups = 0;
94  Stats_TotalInserts = 0;
95  NodeListCapacity = 1000;
96  NodeList = new bookNodePtrT [NodeListCapacity];
97  NodeListCount = 0;
98  HashFlags = NULL;
99 }
100 
102 {
103  for (uint i=0; i <= PBOOK_MAX_MATERIAL; i++) {
104  Tree[i]->IterateStart();
105  bookNodeT* node;
106  while ((node = Tree[i]->Iterate()) != NULL) {
107  delete[] node->data.comment;
108  }
109  delete Tree[i];
110  }
111  if (FileName != NULL) { delete[] FileName; }
112  if (HashFlags != NULL) delete[] HashFlags;
113  delete [] NodeList;
114 }
115 
116 void
117 PBook::SetFileName (const char * fname)
118 {
119  if (FileName) { delete[] FileName; }
120  if (!fname) { FileName = NULL; return; }
121 
122  // Allocate space for the filename string:
123  FileName = strDuplicate(fname);
124 }
125 
126 inline const char *
127 epd_findOpcode (const char * epdStr, const char * opcode)
128 {
129  const char * s = epdStr;
130  while (*s != 0) {
131  while (*s == ' ' || *s == '\n') { s++; }
132  if (strIsPrefix (opcode, s)) {
133  const char *codeEnd = s + strLength(opcode);
134  if (*codeEnd == ' ') {
135  return codeEnd + 1;
136  }
137  }
138  while (*s != '\n' && *s != 0) { s++; }
139  }
140  return NULL;
141 }
142 
143 
144 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
145 // PBook::Find(): Find a position and get its comment.
146 errorT
147 PBook::Find (Position * pos, const char ** ptrComment)
148 {
149  // First, check the optimisation of material count:
150  uint material = pos->GetCount(WHITE) + pos->GetCount(BLACK);
151  ASSERT (material <= PBOOK_MAX_MATERIAL);
152  if (Tree[material]->Size() == 0) {
153  SkipCount++;
154  return ERROR_NotFound;
155  }
156 
157  Stats_Lookups[material]++;
158  Stats_TotalLookups++;
159 
160  // Quick check if any boards in the tree start with the first byte
161  // of this board, to save time:
162  byte firstByte = pos->CompactStrFirstByte();
163  if (Tree[material]->FirstByteSize (firstByte) == 0) {
164  SkipCount++;
165  return ERROR_NotFound;
166  }
167 
168  // Quick check if the hash value of the search position is
169  // not the hash value of any positions in the tree:
170  if (! GetHashFlag (pos)) {
171  SkipCount++;
172  return ERROR_NotFound;
173  }
174 
175  // Generate the compact board string for this position, and lookup:
176  compactBoardStr cboard;
177  pos->PrintCompactStr (cboard);
178  bookNodeT * node = Tree[material]->Lookup (cboard);
179  if (!node) { return ERROR_NotFound; }
180  if (ptrComment) { *ptrComment = node->data.comment; }
181  return OK;
182 }
183 
184 
185 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~
186 // PBook::FindOpcode():
187 // Finds a position and extracts the requested opcode.
188 errorT
189 PBook::FindOpcode (Position * pos, const char * opcode, DString * target)
190 {
191  const char * comment = NULL;
192  errorT err = Find (pos, &comment);
193  if (err != OK) { return ERROR_NotFound; }
194 
195  const char * s = epd_findOpcode (comment, opcode);
196  if (s == NULL) { return ERROR_NotFound; }
197  while (*s != 0 && *s != '\n') {
198  target->AddChar (*s);
199  s++;
200  }
201  return OK;
202 }
203 
204 errorT
206 {
207  const char * comment = NULL;
208  errorT err = Find (pos, &comment);
209  if (err != OK) { return ERROR_NotFound; }
210 
211  const char * s = epd_findOpcode (comment, "ce");
212  if (s != NULL) {
213  int ce = strGetInteger (s);
214  if (pos->GetToMove() == BLACK) { ce = -ce; }
215  char temp[20];
216  sprintf (temp, "%+.2f", ((double) ce) / 100.0);
217  target->Append (temp);
218  return OK;
219  }
220  static const char * opcodes[] = {
221  "eco", "nic", "pv", "pm", "bm", "id", NULL
222  };
223  for (const char ** opcode = opcodes; *opcode != NULL; opcode++) {
224  s = epd_findOpcode (comment, *opcode);
225  if (s != NULL) {
226  while (*s != 0 && *s != '\n') {
227  target->AddChar (*s);
228  s++;
229  }
230  return OK;
231  }
232  }
233  return ERROR_NotFound;
234 }
235 
236 
237 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~
238 // PBook::FindNext():
239 // Finds the next position in order after the current one, and
240 // sets it.
241 // If the flag <forwards> is false, the previous position is found
242 // instead.
243 errorT
244 PBook::FindNext (Position * pos, bool forwards)
245 {
246  ASSERT (pos != NULL);
247  uint totalSize = Size();
248  if (totalSize == 0) { return ERROR_NotFound; }
249  if (forwards) {
250  do {
251  NextIndex++;
252  if (NextIndex >= NodeListCount) { NextIndex = 0; }
253  } while (NodeList[NextIndex] == NULL);
254  } else {
255  do {
256  if (NextIndex == 0) {
257  NextIndex = NodeListCount - 1;
258  } else {
259  NextIndex--;
260  }
261  } while (NodeList[NextIndex] == NULL);
262  }
263 
264 
265  bookNodeT * node = NodeList[NextIndex];
266  ASSERT (node != NULL);
267  errorT err = pos->ReadFromCompactStr ((const byte *) node->name);
268  if (err != OK) { return err; }
269  pos->SetEPTarget (node->data.enpassant);
270 
271  // Now print to FEN and re-read, to ensure the piece lists are in
272  // the order produced by a FEN specification -- this is necessary
273  // since a game with a specified start position has the piece lists
274  // in the FEN-generated order:
275 
276  char temp[200];
277  pos->PrintFEN (temp, FEN_CASTLING_EP);
278  err = pos->ReadFromFEN (temp);
279  return err;
280 }
281 
282 
283 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
284 // PBook::Insert(): Insert a position. Returns OK if a new position
285 // was inserted, or updates the comment and returns ERROR_Exists if
286 // the position was already in the PBook.
287 errorT
288 PBook::Insert (Position * pos, const char * comment)
289 {
290  ASSERT (pos && comment);
291  bookNodeT * node;
292  errorT err;
293 
294  uint material = pos->GetCount(WHITE) + pos->GetCount(BLACK);
295  compactBoardStr cboard;
296  pos->PrintCompactStr (cboard);
297  err = Tree[material]->Insert (cboard, &node);
298  if (err != OK) { // Already exists; we overwrite the old data.
299  delete[] node->data.comment;
300  } else {
301  SetHashFlag (pos);
302  AddNodeToList (node);
303  }
304  node->data.comment = strDuplicate (comment);
305  node->data.enpassant = pos->GetEPTarget();
306  Altered = true;
307 
308  if (material < LeastMaterial) {
309  LeastMaterial = material;
310  }
311  Stats_Inserts[material]++;
312  Stats_TotalInserts++;
313  return err;
314 }
315 
316 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
317 // PBook::Delete():
318 // Delete a position from the PBook.
319 errorT
321 {
322  uint material = pos->GetCount(WHITE) + pos->GetCount(BLACK);
323  compactBoardStr cboard;
324  pos->PrintCompactStr (cboard);
325  bookNodeT * node = Tree[material]->Delete (cboard);
326  if (!node) { return ERROR_NotFound; }
327 
328  NodeList[node->data.id] = NULL;
329  // Delete the comment string:
330  delete[] node->data.comment;
331  delete node;
332 
333  Altered = true;
334  return OK;
335 }
336 
337 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~
338 // PBook::EcoSummary():
339 // Produce a summary from the PBook for the specified ECO code prefix.
340 void
341 PBook::EcoSummary (const char * ecoPrefix, DString * dstr)
342 {
343  uint depth = strLength (ecoPrefix);
344  const char * prevEcoStr = "";
345  for (uint i=0; i < NodeListCount; i++) {
346  bookNodeT * node = NodeList[i];
347  if (node == NULL) { continue; }
348  const char * comment = node->data.comment;
349  const char * ecoStr = epd_findOpcode (comment, "eco");
350  const char * movesStr = epd_findOpcode (comment, "moves");
351  if (ecoStr != NULL && strIsPrefix (ecoPrefix, ecoStr)) {
352  if (depth < 3 && strPrefix (ecoStr, prevEcoStr) >= depth+1) {
353  continue;
354  }
355  prevEcoStr = ecoStr;
356  while (*ecoStr != '\n' && *ecoStr != 0) {
357  dstr->AddChar (*ecoStr);
358  ecoStr++;
359  }
360  dstr->Append (" ");
361  while (*movesStr != '\n' && *movesStr != 0) {
362  dstr->AddChar (*movesStr);
363  movesStr++;
364  }
365  dstr->AddChar ('\n');
366  }
367  }
368 }
369 
370 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~
371 // PBook::StripOpcode:
372 // Strips the specified opcode from every position in the book.
373 // Only the first occurrence of an opcode is removed for any position,
374 // but opcodes are not supposed to occur more than once anyway.
375 // Returns the number of positions where an opcode was removed.
376 uint
377 PBook::StripOpcode (const char * opcode)
378 {
379  char * searchCode = new char [strLength(opcode) + 2];
380  strCopy (searchCode, opcode);
381  strAppend (searchCode, " ");
382  DString dstr;
383  uint countFound = 0;
384 
385  for (uint i=0; i < NodeListCount; i++) {
386  bookNodeT * node = NodeList[i];
387  if (node == NULL) { continue; }
388  const char * s = node->data.comment;
389  int startIndex = -1;
390  int index = 0;
391  // Look for a line with a matching opcode:
392  while (*s != 0) {
393  while (*s == '\n' || *s == ' ') { s++; index++; }
394  if (strIsPrefix (searchCode, s)) {
395  startIndex = index;
396  countFound++;
397  break;
398  }
399  while (*s != 0 && *s != '\n') { s++; index++; }
400  }
401  if (startIndex > -1) {
402  s = node->data.comment;
403  index = 0;
404  // Add all characters before the line to be stripped:
405  dstr.Clear();
406  while (index < startIndex) {
407  dstr.AddChar (s[index]);
408  index++;
409  }
410  // Now find the end of this line:
411  s = &(s[startIndex + 1]);
412  while (*s != 0 && *s != '\n') { s++; }
413  if (*s == '\n') { s++; }
414  while (*s != 0) { dstr.AddChar (*s); s++; }
415 
416  delete[] node->data.comment;
417  node->data.comment = strDuplicate (dstr.Data());
418  }
419  }
420  delete[] searchCode;
421  return countFound;
422 }
423 
424 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~
425 // PBook::ReadEcoFile():
426 // Read an ECO (not EPD) format file.
427 errorT
429 {
430  MFile fp;
431  if (fp.Open (FileName, FMODE_ReadOnly) != OK) {
432  return ERROR_FileOpen;
433  }
434 
435  ReadOnly = true;
436  LineCount = 1;
437  Position std_start;
438  std_start.StdStart();
439  DString text;
440  DString moves;
441  ecoStringT ecoStr;
442  ecoT ecoCode;
443  int ch;
444  errorT err = OK;
445  bool done = false;
446 
447  // Loop to read in and add all positions:
448 
449  while (!done) {
450  // Find the next ECO code:
451  while (true) {
452  ch = fp.ReadOneByte();
453  if (ch == EOF) { done = true; break; }
454  if (ch == '\n') { LineCount++; }
455  if (ch >= 'A' && ch <= 'E') { break; }
456  if (ch == '#') {
457  while (ch != '\n' && ch != EOF) {
458  ch = fp.ReadOneByte();
459  }
460  if (ch == EOF) { done = true; }
461  LineCount++;
462  }
463  }
464  if (done) { break; }
465 
466  // Read in the rest of the ECO code:
467  ecoStr[0] = ch;
468  ch = fp.ReadOneByte();
469  if (ch < '0' || ch > '9') { goto corrupt; }
470  ecoStr[1] = ch;
471  ch = fp.ReadOneByte();
472  if (ch < '0' || ch > '9') { goto corrupt; }
473  ecoStr[2] = ch;
474  ecoStr[3] = 0;
475 
476  // Now check for optional extra part of code, e.g. "A00a1":
477  ch = fp.ReadOneByte();
478  if (ch >= 'a' && ch <= 'z') {
479  ecoStr[3] = ch; ecoStr[4] = 0;
480  ch = fp.ReadOneByte();
481  if (ch >= '1' && ch <= '4') {
482  ecoStr[4] = ch; ecoStr[5] = 0;
483  }
484  }
485 
486  // Now put ecoCode in the text string and read the text in quotes:
487  ecoCode = eco_FromString (ecoStr);
488  eco_ToExtendedString (ecoCode, ecoStr);
489  text.Clear();
490  text.Append ("eco ", ecoStr, " [");
491 
492  // Find the start of the text:
493  while ((ch = fp.ReadOneByte()) != '"') {
494  if (ch == EOF) { goto corrupt; }
495  }
496  while ((ch = fp.ReadOneByte()) != '"') {
497  if (ch == EOF) { goto corrupt; }
498  text.AddChar ((char) ch);
499  }
500  text.Append ("]\n");
501 
502  // Now read the position:
503  moves.Clear();
504  char prev = 0;
505  while ((ch = fp.ReadOneByte()) != '*') {
506  if (ch == EOF) { goto corrupt; }
507  if (ch == '\n') {
508  ch = ' ';
509  LineCount++;
510  }
511  if (ch != ' ' || prev != ' ') {
512  moves.AddChar ((char) ch);
513  }
514  prev = ch;
515  }
516  Position pos (std_start);
517  err = pos.ReadLine (moves.Data());
518  if (err != OK) { goto corrupt; }
519  text.Append ("moves ", strTrimLeft (moves.Data()), "\n");
520  if (Insert (&pos, text.Data()) != OK) {
521  // Position already exists: just ignore it.
522  }
523  }
524  return OK;
525 corrupt:
526  return ERROR_Corrupt;
527 }
528 
529 void ReadLine (DString* s, MFile * fp)
530 {
531  int ch = fp->ReadOneByte();
532  while (ch != '\n' && ch != EOF) {
533  if (ch != '\r') s->AddChar (ch);
534  ch = fp->ReadOneByte();
535  }
536 }
537 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
538 // PBook::ReadFile(): read in a file.
539 errorT
541 {
542  ASSERT (FileName != NULL);
543 
544  ReadOnly = false;
545  MFile fp;
546  if (fp.Open (FileName, FMODE_Both) != OK) {
547  ReadOnly = true;
548  if (fp.Open (FileName, FMODE_ReadOnly) != OK) {
549  return ERROR_FileOpen;
550  }
551  }
552 
553  LineCount = 1;
554  Position * pos = new Position;
555  DString * line = new DString;
556  ReadLine(line, &fp);
557  DString dstr;
558 
559  while (line->Length() || ! fp.EndOfFile()) {
560 
561  if (pos->ReadFromFEN (line->Data()) != OK) {
562  fprintf (stderr, "Error reading line: %u\n", LineCount);
563  LineCount++;
564  line->Clear();
565  ReadLine(line, &fp);
566  continue;
567  //exit (1);
568  }
569 
570  char * s = (char *) line->Data();
571  // Skip over first four fields, which were the position:
572  while (*s == ' ') { s++; }
573  for (uint i=0; i < 4; i++) {
574  while (*s != ' ' && *s != 0) { s++; }
575  while (*s == ' ') { s++; }
576  }
577  // Now process each field in turn:
578  while (*s == ';' || *s == ' ') { s++; }
579  dstr.Clear();
580  while (*s != 0) {
581  while (*s == ';' || *s == ' ') { s++; }
582  bool seenCode = false;
583  while (*s != ';' && *s != 0) {
584  seenCode = true;
585  char ch = *s;
586  // Check for backslash (escape) character:
587  if (ch == '\\') {
588  s++;
589  ch = *s;
590  // "\s" -> semicolon within a field:
591  if (ch == 's') { ch = ';'; }
592  }
593  dstr.AddChar (ch);
594  s++;
595  }
596  if (seenCode) { dstr.AddChar ('\n'); }
597  }
598 
599  if (Insert (pos, dstr.Data()) != OK) {
600  //fprintf (stderr, "Warning: position already exists! Line %u\n",
601  // LineCount);
602  }
603  LineCount++;
604  line->Clear();
605  ReadLine(line, &fp);
606  }
607  delete pos;
608  delete line;
609  Altered = false;
610  NextIndex = NodeListCount - 1;
611  return OK;
612 }
613 
614 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
615 // PBook::WriteFile(): writes the entire PBook to a file.
616 errorT
618 {
619  ASSERT (FileName != NULL);
620  bookNodeT * node;
621  FILE * fp = fopen (FileName, "w");
622  if (!fp) { return ERROR_FileOpen; }
623 
624  Stats_PositionBytes = 0;
625  Stats_CommentBytes = 0;
626 
627  Position * pos = new Position;
628  char tempStr [200];
629  for (uint i=0; i < NodeListCount; i++) {
630  node = NodeList[i];
631  if (node == NULL) { continue; }
632  if (pos->ReadFromCompactStr ((const byte *) node->name) != OK) {
633  fclose (fp);
634  delete pos;
635  return ERROR_Corrupt;
636  }
637  pos->SetEPTarget (node->data.enpassant);
638  pos->PrintFEN (tempStr, FEN_CASTLING_EP);
639  fprintf (fp, "%s", tempStr);
640  Stats_PositionBytes += strLength (tempStr);
641  bool atCodeStart = true;
642  char * s = node->data.comment;
643  while (*s != 0) {
644  if (*s == '\n') {
645  if (! atCodeStart) { fputc (';', fp); Stats_CommentBytes++; }
646  atCodeStart = true;
647  s++;
648  while (*s == ' ') { s++; }
649  } else {
650  if (atCodeStart) { fputc (' ', fp); Stats_CommentBytes++; }
651  atCodeStart = false;
652  // Encode "\" as "\\" and ";" as "\s":
653  char ch = *s;
654  switch (ch) {
655  case '\\':
656  fputc ('\\', fp);
657  fputc ('\\', fp);
658  Stats_CommentBytes += 2;
659  break;
660  case ';':
661  fputc ('\\', fp);
662  fputc ('s', fp);
663  Stats_CommentBytes += 2;
664  break;
665  default:
666  fputc (ch, fp);
667  Stats_CommentBytes++;
668  }
669  s++;
670  }
671  }
672  fputc ('\n', fp);
673  Stats_CommentBytes++;
674  }
675  fclose(fp);
676  delete pos;
677  Altered = false;
678  return OK;
679 }
680 
681 void
682 PBook::DumpStats (FILE * fp)
683 {
684  fprintf (fp, "%d\n", LeastMaterial);
685  for (uint i=LeastMaterial; i <= PBOOK_MAX_MATERIAL; i++) {
686  fprintf (fp, "%4d %8d (%5.2f%%) ", i, Stats_Lookups[i],
687  (float)Stats_Lookups[i] * 100.0 / Stats_TotalLookups);
688  fprintf (fp, "%8d (%5.2f%%)\n", Stats_Inserts[i],
689  (float)Stats_Inserts[i] * 100.0 / Stats_TotalInserts);
690  }
691 }
692 
693 //////////////////////////////////////////////////////////////////////
694 // EOF: pbook.cpp
695 //////////////////////////////////////////////////////////////////////
nodeT< C > * Delete(const char *str)
Definition: strtree.h:673
unsigned char byte
Definition: common.h:97
void PrintCompactStr(char *cboard)
Definition: position.cpp:2752
#define PBOOK_MAX_MATERIAL
Definition: pbook.h:26
uint strLength(const char *str)
Definition: misc.h:492
const colorT WHITE
Definition: common.h:203
char * name
Definition: strtree.h:68
Definition: mfile.h:52
const char * strTrimLeft(const char *target, const char *trimChars)
Definition: misc.cpp:347
uint GetCount(colorT c)
Definition: position.h:163
void PrintFEN(char *str, uint flags)
Definition: position.cpp:2975
uint id
Definition: pbook.h:29
void DumpStats(FILE *fp)
Definition: pbook.cpp:682
const errorT OK
Definition: error.h:23
bool strIsPrefix(const char *prefix, const char *longStr)
Definition: misc.h:412
void SetFileName(const char *filename)
Definition: pbook.cpp:117
errorT FindNext(Position *pos, bool forwards)
Definition: pbook.cpp:244
char * strDuplicate(const char *original)
Definition: misc.cpp:239
errorT FindSummary(Position *pos, DString *target)
Definition: pbook.cpp:205
uint StripOpcode(const char *opcode)
Definition: pbook.cpp:377
void IterateStart()
Definition: strtree.h:150
#define ASSERT(f)
Definition: common.h:67
const char * Data()
Definition: dstring.h:28
const colorT BLACK
Definition: common.h:204
errorT ReadFromCompactStr(const byte *str)
Definition: position.cpp:2724
uint Size()
Definition: pbook.h:90
uint strPrefix(const char *s1, const char *s2)
Definition: misc.h:395
errorT Insert(const char *str, nodeT< C > **returnNode)
Definition: strtree.h:423
errorT ReadFromFEN(const char *s)
Definition: position.cpp:2812
char ecoStringT[6]
Definition: common.h:162
squareT enpassant
Definition: pbook.h:31
errorT FindOpcode(Position *pos, const char *opcode, DString *target)
Definition: pbook.cpp:189
errorT Open(const char *name, fileModeT fmode)
Definition: mfile.cpp:95
errorT Insert(Position *pos, const char *comment)
Definition: pbook.cpp:288
~PBook()
Definition: pbook.cpp:101
void AddChar(char ch)
Definition: dstring.h:32
uint32_t uint
Definition: common.h:99
char * comment
Definition: pbook.h:30
void ReadLine(DString *s, MFile *fp)
Definition: pbook.cpp:529
void StdStart()
Definition: position.h:145
void Init()
Definition: pbook.cpp:77
int strGetInteger(const char *str)
Definition: misc.h:266
byte CompactStrFirstByte()
Definition: position.h:275
errorT WriteFile()
Definition: pbook.cpp:617
ushort ecoT
Definition: common.h:161
void eco_ToExtendedString(ecoT ecoCode, char *ecoStr)
Definition: misc.h:186
errorT ReadLine(const char *s)
Definition: position.cpp:2556
unsigned short errorT
Definition: error.h:20
void SetEPTarget(squareT s)
Definition: position.h:152
int ReadOneByte()
Definition: mfile.h:143
char * strAppend(char *target, const char *extra)
Definition: misc.cpp:222
void Append(uint i)
Definition: dstring.h:46
errorT Find(Position *pos, const char **ptrComment)
Definition: pbook.cpp:147
errorT ReadEcoFile()
Definition: pbook.cpp:428
materialw
Definition: board.tcl:1551
void strCopy(char *target, const char *original)
Definition: misc.h:379
ecoT eco_FromString(const char *ecoStr)
Definition: misc.cpp:69
char compactBoardStr[36]
Definition: pbook.cpp:32
const errorT ERROR_Corrupt
Definition: error.h:46
colorT GetToMove()
Definition: position.h:155
bool EndOfFile()
Definition: mfile.h:108
#define PBOOK_HASH(pos)
Definition: pbook.cpp:30
errorT Delete(Position *pos)
Definition: pbook.cpp:320
const char * epd_findOpcode(const char *epdStr, const char *opcode)
Definition: pbook.cpp:127
C data
Definition: strtree.h:69
void EcoSummary(const char *ecoPrefix, DString *dstr)
Definition: pbook.cpp:341
squareT GetEPTarget()
Definition: position.h:153
nodeT< C > * Lookup(const char *str)
Definition: strtree.h:389
const errorT ERROR_NotFound
Definition: error.h:50
errorT ReadFile()
Definition: pbook.cpp:540
size_t Length(void)
Definition: dstring.h:30
const errorT ERROR_FileOpen
Definition: error.h:31
const uint FEN_CASTLING_EP
Definition: position.h:49
void Clear()
Definition: dstring.h:26