version 1.4w10UCIb18
authorH.G. Muller <h.g.muller@hccnet.nl>
Thu, 9 Jun 2011 07:46:39 +0000 (09:46 +0200)
committerH.G. Muller <h.g.muller@hccnet.nl>
Thu, 9 Jun 2011 07:46:39 +0000 (09:46 +0200)
17 files changed:
ChangeLog
README
book_make.cpp
book_make.h
config.h
configure
configure.ac
engine.cpp
main.cpp
option.cpp
parse.cpp
polyglot.man
polyglot.pod
polyglot.spec
uci2uci.cpp
util.h
xboard2uci.cpp

index ab9261c..ca28e59 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,5 @@
+=========1.4w10UCIb18===========\r
+- Two new utilities: info-book and dump-book.\r
 =========1.4w10UCIb17===========\r
 - More refactoring. main.cpp is now #ifdef _WIN32 free.\r
 - The main loop (previously in adapter.cpp) is now in its own file mainloop.cpp.\r
diff --git a/README b/README
index fa7080c..6322277 100644 (file)
--- a/README
+++ b/README
@@ -5,7 +5,8 @@ POLYGLOT(6)                                                        POLYGLOT(6)
 NAME
        PolyGlot -  Winboard protocol to UCI protocol adapter
                 -  book engine for Polyglot books
-                -  a collection of utilities for creating opening books
+                -  a collection of utilities for creating and analyzing open-
+       ing books
                 -  a utility for analyzing epd files
                 -  a perft counter
 
@@ -20,6 +21,10 @@ SYNOPSIS
 
        polyglot merge-book -in1 inputfile1 -in2 inputfile2 [-out outputfile]
 
+       polyglot info-book [-bin inputfile] [-exact]
+
+       polyglot dumb-book [-bin inputfile] -color color [-out outputfile]
+
        polyglot [configfile] epd-test [-epd inputfile] [-min-depth depth]
        [-max-depth depth] [-max-time time] [-depth-delta delta]
 
@@ -78,6 +83,33 @@ DESCRIPTION
        PolyGlot can compile a pgn file into a binary PolyGlot book and fur-
        thermore it can merge two such binary books into a third one.
 
+       PolyGlot can also extract some useful information from PolyGlot books.
+       The utility "dump-book" dumps the "lines" in a book for a given color.
+       By definition a line is a sequence of moves (from the starting posi-
+       tion) in which the given color makes only book moves and the other
+       color makes arbitrary moves (i.e. not necessarily book moves).
+
+       Since a PolyGlot book is built up from positions and not lines there
+       may be (and there usually are) many positions in the book that are not
+       on a "line" as defined in the previous paragraph. It is convenient to
+       call such positions "isolated" positions. The utility "info-book"
+       counts such isolated positions.
+
+       Some of the isolated positions are provably unreachable and they could
+       in principle be deleted from the book. For example if a book contains
+       only the move "e4" in the starting position but also the position after
+       "d4 d5" then this last position is provably unreachable since it
+       requires white to make a non-book move when a book move is available.
+       Such situations arise frequently from the priority rules in merging
+       books.
+
+       Unfortunately not all isolated positions are provably unreachable and
+       it is difficult to identify the latter. If invoked with "-exact" the
+       utility info-book will attempt to count the isolated positions which
+       require a player to make a non-book move when a book move is available.
+       Due to the possibility of transpositions this is not a fool proof
+       method.
+
        Epd test mode
 
        In epd test mode, PolyGlot will search positions in an epd file and
@@ -158,6 +190,34 @@ OPTIONS
 
        When invoked as
 
+       polyglot dump-book
+
+       PolyGlot supports the following options
+
+       -bin (default: book.bin)
+           Input file in PolyGlot book format.
+
+       -color
+           The color for whom to generate the lines.
+
+       -out (default: book_<color>.txt)
+           The name of the output file.
+
+       When invoked as
+
+       polyglot info-book
+
+       PolyGlot supports the following options
+
+       -bin (default: book.bin)
+           Input file in PolyGlot book format.
+
+       -exact
+           Attempt to count the provably unreachable positions among the iso-
+           lated ones.  Note that this takes a very long time.
+
+       When invoked as
+
        polyglot epd-test
 
        (possibly with a config file as first argument) PolyGlot supports the
@@ -434,4 +494,4 @@ SEE ALSO
 
 
 
-                                  2009-01-14                       POLYGLOT(6)
+                                  2009-01-15                       POLYGLOT(6)
index ffffc9b..ba02f51 100644 (file)
@@ -1,4 +1,3 @@
-\r
 // book_make.cpp\r
 \r
 // includes\r
@@ -13,6 +12,7 @@
 #include "book_make.h"\r
 #include "move.h"\r
 #include "move_do.h"\r
+#include "move_gen.h"\r
 #include "move_legal.h"\r
 #include "pgn.h"\r
 #include "san.h"\r
 // constants\r
 \r
 static const int COUNT_MAX = 16384;\r
+static const int StringSize = 4096;\r
 \r
 static const int NIL = -1;\r
 \r
+// defines\r
+\r
+#define opp_search(s) ((s)==BOOK?ALL:BOOK)\r
+\r
 // types\r
 \r
 struct entry_t {\r
-   uint64 key;\r
-   uint16 move;\r
-   uint16 n;\r
-   uint16 sum;\r
-   uint16 colour;\r
+    uint64 key;\r
+    uint16 move;\r
+    uint16 count;\r
+    union{   // unfortunately minggw32 seems to have a bug with anon unions.\r
+        struct { \r
+            uint16 n;\r
+            uint16 sum;\r
+        };\r
+        struct{\r
+            uint8 height;\r
+            int line;\r
+        };\r
+    };\r
+    uint8 colour;\r
 };\r
 \r
 struct book_t {\r
@@ -42,6 +56,24 @@ struct book_t {
    sint32 * hash;\r
 };\r
 \r
+enum search_t {\r
+    BOOK,\r
+    ALL\r
+};\r
+\r
+struct info_t {\r
+    int height;\r
+    int line;\r
+    int initial_color;\r
+    bool book_trans_only;\r
+    bool extended_search;\r
+    uint16 moves[1024];\r
+    double probs[1024];\r
+    uint64 keys[1024];\r
+    FILE *output;\r
+};\r
+\r
+\r
 // variables\r
 \r
 static int MaxPly;\r
@@ -49,6 +81,7 @@ static int MinGame;
 static double MinScore;\r
 static bool RemoveWhite, RemoveBlack;\r
 static bool Uniform;\r
+static bool Quiet=false;\r
 \r
 static book_t Book[1];\r
 \r
@@ -71,6 +104,10 @@ static int    entry_score    (const entry_t * entry);
 static int    key_compare   (const void * p1, const void * p2);\r
 \r
 static void   write_integer (FILE * file, int size, uint64 n);\r
+static uint64 read_integer(FILE * file, int size);\r
+\r
+static void read_entry_file(FILE *f, entry_t *entry);\r
+static void write_entry_file(FILE * f, const entry_t * entry);\r
 \r
 // functions\r
 \r
@@ -332,9 +369,9 @@ static int find_entry(const board_t * board, int move) {
    int pos;\r
 \r
    ASSERT(board!=NULL);\r
-   ASSERT(move_is_ok(move));\r
+   ASSERT(move==MoveNone || move_is_ok(move));\r
 \r
-   ASSERT(move_is_legal(move,board));\r
+   ASSERT(move==MoveNone || move_is_legal(move,board));\r
 \r
    // init\r
 \r
@@ -342,7 +379,7 @@ static int find_entry(const board_t * board, int move) {
 \r
    // search\r
 \r
-   for (index = key & Book->mask; (pos=Book->hash[index]) != NIL; index = (index+1) & Book->mask) {\r
+   for (index = key & (uint64) Book->mask; (pos=Book->hash[index]) != NIL; index = (index+1) & Book->mask) {\r
 \r
       ASSERT(pos>=0&&pos<Book->size);\r
 \r
@@ -361,7 +398,7 @@ static int find_entry(const board_t * board, int move) {
 \r
       resize();\r
 \r
-      for (index = key & Book->mask; Book->hash[index] != NIL; index = (index+1) & Book->mask)\r
+      for (index = key & (uint64) Book->mask; Book->hash[index] != NIL; index = (index+1) & Book->mask)\r
          ;\r
    }\r
 \r
@@ -387,13 +424,24 @@ static int find_entry(const board_t * board, int move) {
    return pos;\r
 }\r
 \r
-// resize()\r
+// rebuild_hash_table\r
+\r
+static void rebuild_hash_table(){\r
+    int index,pos;\r
+    for (index = 0; index < Book->alloc*2; index++) {\r
+        Book->hash[index] = NIL;\r
+    }\r
+    for (pos = 0; pos < Book->size; pos++) {\r
+        for (index = Book->entry[pos].key & (uint64) Book->mask; Book->hash[index] != NIL; index = (index+1) & Book->mask)\r
+         ;\r
+        ASSERT(index>=0&&index<Book->alloc*2);\r
+        Book->hash[index] = pos;\r
+    }\r
+}\r
 \r
 static void resize() {\r
 \r
    int size;\r
-   int pos;\r
-   int index;\r
 \r
    ASSERT(Book->size==Book->alloc);\r
 \r
@@ -403,7 +451,9 @@ static void resize() {
    size = 0;\r
    size += Book->alloc * sizeof(entry_t);\r
    size += (Book->alloc*2) * sizeof(sint32);\r
-   if (size >= 1048576) printf("allocating %gMB ...\n",double(size)/1048576.0);\r
+\r
+   if (size >= 1048576) if(!Quiet){printf("allocating %gMB ...\n",double(size)/1048576.0);}\r
+\r
    // resize arrays\r
 \r
    Book->entry = (entry_t *) my_realloc(Book->entry,Book->alloc*sizeof(entry_t));\r
@@ -411,20 +461,10 @@ static void resize() {
 \r
    // rebuild hash table\r
 \r
-   for (index = 0; index < Book->alloc*2; index++) {\r
-      Book->hash[index] = NIL;\r
-   }\r
-\r
-   for (pos = 0; pos < Book->size; pos++) {\r
-\r
-      for (index = Book->entry[pos].key & Book->mask; Book->hash[index] != NIL; index = (index+1) & Book->mask)\r
-         ;\r
-\r
-      ASSERT(index>=0&&index<Book->alloc*2);\r
-      Book->hash[index] = pos;\r
-   }\r
+   rebuild_hash_table();\r
 }\r
 \r
+\r
 // halve_stats()\r
 \r
 static void halve_stats(uint64 key) {\r
@@ -434,7 +474,7 @@ static void halve_stats(uint64 key) {
 \r
    // search\r
 \r
-   for (index = key & Book->mask; (pos=Book->hash[index]) != NIL; index = (index+1) & Book->mask) {\r
+   for (index = key & (uint64) Book->mask; (pos=Book->hash[index]) != NIL; index = (index+1) & Book->mask) {\r
 \r
       ASSERT(pos>=0&&pos<Book->size);\r
 \r
@@ -536,5 +576,501 @@ static void write_integer(FILE * file, int size, uint64 n) {
    }\r
 }\r
 \r
+// read_integer()\r
+\r
+static uint64 read_integer(FILE * file, int size) {\r
+   uint64 n;\r
+   int i;\r
+   int b;\r
+   ASSERT(file!=NULL);\r
+   ASSERT(size>0&&size<=8);\r
+   n = 0;\r
+   for (i = 0; i < size; i++) {\r
+      b = fgetc(file);\r
+      if (b == EOF) {\r
+         if (feof(file)) {\r
+            my_fatal("read_integer(): fgetc(): EOF reached\n");\r
+         } else { // error\r
+            my_fatal("read_integer(): fgetc(): %s\n",strerror(errno));\r
+         }\r
+      }\r
+      ASSERT(b>=0&&b<256);\r
+      n = (n << 8) | b;\r
+   }\r
+   return n;\r
+}\r
+\r
+// read_entry_file\r
+\r
+static void read_entry_file(FILE *f, entry_t *entry){\r
+    uint64 n;\r
+    ASSERT(entry!=NULL);\r
+    n = entry->key   = read_integer(f,8);\r
+    entry->move  = read_integer(f,2);\r
+    entry->count = read_integer(f,2);\r
+    entry->n     = read_integer(f,2);\r
+    entry->sum   = read_integer(f,2);\r
+    ASSERT(n==entry->key); // test for mingw compiler bug with anon structs\r
+}\r
+\r
+// write_entry_file\r
+\r
+static void write_entry_file(FILE * f, const entry_t * entry) {\r
+   ASSERT(entry!=NULL);\r
+   write_integer(f,8,entry->key);\r
+   write_integer(f,2,entry->move);\r
+   write_integer(f,2,entry->count);\r
+   write_integer(f,2,entry->n);\r
+   write_integer(f,2,entry->sum);\r
+}\r
+\r
+static void print_list(const board_t *board, list_t *list){\r
+    int i;\r
+    uint16 move;\r
+    char move_string[256];\r
+    for (i = 0; i < list_size(list); i++) {\r
+        move = list_move(list,i);\r
+        move_to_san(move,board,move_string,256);\r
+        printf("%s",move_string);\r
+    }\r
+    printf("\n");\r
+}\r
+\r
+// book_load()\r
+// loads a polyglot book\r
+\r
+static void book_load(const char filename[]){\r
+    FILE* f;\r
+    entry_t entry[1];\r
+    int size;\r
+    int i;\r
+    int pos;\r
+    int index;\r
+    ASSERT(filename!=NULL);\r
+    if(!(f=fopen(filename,"rb"))){\r
+        my_fatal("book_load() : can't open file \"%s\" for reading: %s\n",filename,strerror(errno));\r
+    }\r
+    fseek(f,0L,SEEK_END);   // superportable way to get size of book!\r
+    size=ftell(f)/16;\r
+    fseek(f,0,SEEK_SET);\r
+    for(i=0L;i<size;i++){\r
+        read_entry_file(f,entry);\r
+        ASSERT(Book->size<=Book->alloc);\r
+        if (Book->size == Book->alloc) {\r
+                // allocate more memoryx\r
+            resize();\r
+        }\r
+            // insert into the book\r
+        pos = Book->size++;\r
+        Book->entry[pos].key = entry->key;\r
+        ASSERT(entry->move!=MoveNone);\r
+        Book->entry[pos].move = entry->move;\r
+        Book->entry[pos].count = entry->count;\r
+        Book->entry[pos].n = entry->n;\r
+        Book->entry[pos].sum = entry->sum;\r
+        Book->entry[pos].colour = ColourNone;\r
+            // find free hash table spot\r
+        for (index = entry->key & (uint64) Book->mask;\r
+             Book->hash[index] != NIL;\r
+             index = (index+1) & Book->mask);\r
+            // insert into the hash table\r
+        ASSERT(index>=0&&index<Book->alloc*2);\r
+        ASSERT(Book->hash[index]==NIL);\r
+        Book->hash[index] = pos;\r
+        ASSERT(pos>=0&&pos<Book->size);\r
+    }\r
+    fclose(f);\r
+}\r
+\r
+// gen_book_moves()\r
+// similar signature as gen_legal_moves\r
+static int gen_book_moves(list_t * list, const board_t * board){\r
+    int first_pos, pos, index;\r
+    entry_t entry[1];\r
+    list_clear(list);\r
+    bool found;\r
+    found=FALSE;\r
+    for (index = board->key & (uint64) Book->mask; (first_pos=Book->hash[index]) != NIL; index = (index+1) & Book->mask) {\r
+        ASSERT(first_pos>=0&&first_pos<Book->size);\r
+        if (Book->entry[first_pos].key == board->key) {\r
+            found=TRUE;\r
+            break; // found\r
+        }\r
+    }\r
+    if(!found) return -1;\r
+    if(Book->entry[first_pos].move==MoveNone) return -1;\r
+    for (pos = first_pos; pos < Book->size; pos++) {\r
+        *entry=Book->entry[pos];\r
+        if (entry->key != board->key) break;\r
+        if (entry->count > 0 &&\r
+            entry->move != MoveNone &&\r
+            move_is_legal(entry->move,board)) {\r
+            list_add(list,entry->move,entry->count);\r
+        }\r
+    }\r
+    return first_pos;\r
+}\r
+\r
+// gen_opp_book_moves()\r
+// moves to which opponent has a reply in book\r
+// similar signature as gen_legal_moves\r
+static void gen_opp_book_moves(list_t * list, const board_t * board){\r
+    int move;\r
+    list_t new_list[1], legal_moves[1];\r
+    board_t new_board[1];\r
+    int i;\r
+    list_clear(list);\r
+    gen_legal_moves(legal_moves,board);\r
+    for (i = 0; i < list_size(legal_moves); i++) {\r
+        move = list_move(legal_moves,i);\r
+            // scratch_board\r
+        memcpy(new_board, board, sizeof(board_t));\r
+        move_do(new_board,move);\r
+        gen_book_moves(new_list,new_board); // wasteful in time but tested!\r
+        if(list_size(new_list)!=0){\r
+            list_add(list,move);\r
+        }\r
+    }\r
+}\r
+\r
+static void print_moves(info_t *info){\r
+    board_t board[1];\r
+    char move_string[256];\r
+    int i;\r
+    int color=White;\r
+    if(!info->output){\r
+        return;\r
+    }\r
+    board_start(board);\r
+    for(i=0;i<info->height;i++){\r
+        if(color==White){\r
+            fprintf(info->output,"%d. ",i/2+1);\r
+            color=Black;\r
+        }else{\r
+            color=White;\r
+        }\r
+        move_to_san(info->moves[i],board,move_string,256);\r
+        fprintf(info->output,"%s", move_string);\r
+        if(color==colour_opp(info->initial_color)){\r
+            fprintf(info->output,"{%.0f%%} ",100*info->probs[i]);\r
+        }else{\r
+            fprintf(info->output," ");\r
+        }\r
+        move_do(board,info->moves[i]);\r
+    }\r
+}\r
+\r
+static int search_book(board_t *board, info_t *info, search_t search){\r
+    list_t list[1];\r
+    board_t new_board[1];\r
+    uint16 move;\r
+    int count;\r
+    int ret;\r
+    int i;\r
+    int offset;\r
+    int pos;\r
+    int size;\r
+    int prob_sum;\r
+    double probs[256];\r
+    for(i=0;i<256;i++){\r
+        probs[i]=0.0;  // kill compiler warnings\r
+    }\r
+    for(i=0;i<info->height;i++){\r
+        if(board->key==info->keys[i]){\r
+            if(info->output){\r
+                fprintf(info->output,"%d: ",info->line);\r
+                print_moves(info);\r
+                fprintf(info->output,"{cycle: ply=%d}\n",i);\r
+            }\r
+            info->line++;\r
+            return 1; // end of line because of cycle\r
+        }\r
+    }\r
+    if(!info->book_trans_only || (info->book_trans_only && search==BOOK)){\r
+        info->keys[info->height]=board->key;\r
+        size=Book->size;  // hack\r
+        pos=find_entry(board,MoveNone);\r
+        if(size==Book->size){\r
+            if(info->output){\r
+                fprintf(info->output,"%d: ",info->line);\r
+                print_moves(info);\r
+                fprintf(info->output,"{trans: line=%d, ply=%d}\n",\r
+                        Book->entry[pos].line,\r
+                        Book->entry[pos].height);\r
+            }\r
+            info->line++;\r
+            return 1; // end of line because of transposition\r
+        }else{\r
+            Book->entry[pos].height=info->height;\r
+            Book->entry[pos].line=info->line;\r
+        }\r
+    }\r
+    count=0;\r
+    if(search==BOOK){\r
+        offset=gen_book_moves(list,board);\r
+        if(info->extended_search){\r
+            gen_legal_moves(list,board);\r
+        }\r
+//        ASSERT(offset!=-1);\r
+        if(offset!=-1){ // only false in starting position for black book\r
+            Book->entry[offset].colour=board->turn;\r
+            prob_sum=0;\r
+            if(!info->extended_search){\r
+                for(i=0;i<list_size(list);i++){\r
+                    prob_sum+=uint16(list_value(list,i));\r
+                }\r
+                for(i=0;i<list_size(list);i++){\r
+                    probs[i]=double(uint16(list_value(list,i)))/double(prob_sum);\r
+                }\r
+            }\r
+        }\r
+    }else{\r
+        gen_opp_book_moves(list,board);\r
+    }\r
+    for (i = 0; i < list_size(list); i++) {\r
+        move = list_move(list,i);\r
+        memcpy(new_board, board, sizeof(board_t));\r
+        ASSERT(move_is_legal(move,new_board));\r
+        move_do(new_board,move);\r
+        ASSERT(search!=opp_search(search));\r
+        info->moves[info->height++]=move;\r
+        if(search==BOOK){\r
+            info->probs[info->height-1]=probs[i];\r
+        }\r
+        ret=search_book(new_board, info, opp_search(search));\r
+        if(ret==0 && search==BOOK){\r
+            if(info->output){\r
+                fprintf(info->output,"%d: ",info->line);\r
+                print_moves(info);\r
+                fprintf(info->output,"\n");\r
+            }\r
+            info->line++;\r
+            ret=1; // end of line book move counts for 1\r
+        }\r
+        info->height--;\r
+        ASSERT(info->height>=0);\r
+        count+=ret;\r
+    }\r
+    return count;\r
+}\r
+\r
+void init_info(info_t *info){\r
+    info->line=1;\r
+    info->height=0;\r
+    info->output=NULL;\r
+    info->initial_color=White;\r
+    info->book_trans_only=FALSE;\r
+}\r
+\r
+// book_clean()\r
+// remove MoveNone entries from book and rebuild hash table\r
+void book_clean(){\r
+    int read_ptr,write_ptr;\r
+    write_ptr=0;\r
+    for(read_ptr=0;read_ptr<Book->size;read_ptr++){\r
+        if(Book->entry[read_ptr].move!=MoveNone){\r
+            Book->entry[write_ptr++]=Book->entry[read_ptr];\r
+        }\r
+    }\r
+    Book->size=write_ptr;\r
+    rebuild_hash_table();\r
+}\r
+\r
+// book_dump()\r
+\r
+void book_dump(int argc, char * argv[]) {\r
+    const char * bin_file=NULL;\r
+    const char * txt_file=NULL;\r
+    char string[StringSize];\r
+    int color=ColourNone;\r
+    board_t board[1];\r
+    info_t info[1];\r
+    int i;\r
+    FILE *f;\r
+    my_string_set(&bin_file,"book.bin");\r
+    for (i = 1; i < argc; i++) {\r
+        if (false) {\r
+        } else if (my_string_equal(argv[i],"dump-book")) {\r
+                // skip\r
+        } else if (my_string_equal(argv[i],"-bin")) {\r
+            i++;\r
+            if (i==argc) my_fatal("book_dump(): missing argument\n");\r
+            my_string_set(&bin_file,argv[i]);\r
+        } else if (my_string_equal(argv[i],"-out")) {\r
+            i++;\r
+            if (i==argc) my_fatal("book_dump(): missing argument\n");\r
+            my_string_set(&txt_file,argv[i]);\r
+        } else if (my_string_equal(argv[i],"-color") || my_string_equal(argv[i],"-colour")) {\r
+            i++;\r
+            if (i == argc) my_fatal("book_dump(): missing argument\n");\r
+            if(my_string_equal(argv[i],"white")){\r
+                color=White;\r
+            }else if (my_string_equal(argv[i],"black")){\r
+                color=Black;\r
+            }else{\r
+                my_fatal("book_dump(): unknown color \"%s\"\n",argv[i]);\r
+            }\r
+        } else {\r
+            my_fatal("book_dump(): unknown option \"%s\"\n",argv[i]);\r
+        }\r
+    }\r
+    if(color==ColourNone){\r
+        my_fatal("book_dump(): you must specify a color\n");\r
+    }\r
+    if(txt_file==NULL){\r
+        snprintf(string,StringSize,"book_%s.txt",color?"white":"black");\r
+        my_string_set(&txt_file,string);\r
+    }\r
+\r
+    book_clear();\r
+    if(!Quiet){printf("loading book ...\n");}\r
+    book_load(bin_file);\r
+    board_start(board);\r
+    init_info(info);\r
+    info->initial_color=color;\r
+    if(!(f=fopen(txt_file,"w"))){\r
+        my_fatal("book_dump(): can't open file \"%s\" for writing: %s",\r
+                 txt_file,strerror(errno));\r
+    }\r
+    info->output=f;\r
+    fprintf(info->output,"Dump of \"%s\" for %s.\n",\r
+            bin_file,color==White?"white":"black");\r
+    if(color==White){\r
+        if(!Quiet){printf("generating lines for white...\n");}\r
+        search_book(board,info, BOOK);\r
+    }else{\r
+        if(!Quiet){printf("generating lines for black...\n");}\r
+        search_book(board,info, ALL);\r
+    }\r
+}\r
+\r
+// book_info()\r
+\r
+void book_info(int argc,char* argv[]){\r
+    const char *bin_file=NULL;\r
+    board_t board[1];\r
+    info_t info[1];\r
+    uint64 last_key;\r
+    int pos;\r
+    int white_pos,black_pos,total_pos,white_pos_extended,\r
+        black_pos_extended,white_pos_extended_diff,black_pos_extended_diff;\r
+    int s;\r
+    bool extended_search=FALSE;\r
+    int i;\r
+    Quiet=TRUE;\r
+    my_string_set(&bin_file,"book.bin");\r
+\r
+    for (i = 1; i < argc; i++) {\r
+        if (false) {\r
+        } else if (my_string_equal(argv[i],"info-book")) {\r
+                // skip\r
+        } else if (my_string_equal(argv[i],"-bin")) {\r
+            i++;\r
+            if (i==argc) my_fatal("book_info(): missing argument\n");\r
+            my_string_set(&bin_file,argv[i]);\r
+        } else if (my_string_equal(argv[i],"-exact")) {\r
+            extended_search=TRUE;\r
+        } else {\r
+            my_fatal("book_info(): unknown option \"%s\"\n",argv[i]);\r
+        }\r
+    }\r
+    book_clear();\r
+    if(!Quiet){printf("loading book ...\n");}\r
+    book_load(bin_file);\r
+    s=Book->size;\r
+\r
+    board_start(board);\r
+    init_info(info);\r
+    info->book_trans_only=FALSE;\r
+    info->initial_color=White;\r
+    info->extended_search=FALSE;\r
+    search_book(board,info, BOOK);\r
+    printf("Lines for white                : %8d\n",info->line-1);\r
+\r
+\r
+    info->line=1;\r
+    info->height=0;\r
+    info->initial_color=Black;\r
+    book_clean();\r
+    ASSERT(Book->size==s);\r
+    board_start(board);\r
+    search_book(board,info, ALL);\r
+    printf("Lines for black                : %8d\n",info->line-1);\r
+\r
+    book_clean();\r
+    ASSERT(Book->size==s);\r
+    white_pos=0;\r
+    black_pos=0;\r
+    total_pos=0;\r
+    last_key=0;\r
+    for(pos=0;pos<Book->size;pos++){\r
+        if(Book->entry[pos].key==last_key){\r
+            ASSERT(Book->entry[pos].colour==ColourNone);\r
+            continue;\r
+        }\r
+        last_key=Book->entry[pos].key;\r
+        total_pos++;\r
+        if(Book->entry[pos].colour==White){\r
+            white_pos++;\r
+        }else if(Book->entry[pos].colour==Black){\r
+            black_pos++;\r
+        }\r
+    }\r
+    printf("Positions on lines for white   : %8d\n",white_pos);\r
+    printf("Positions on lines for black   : %8d\n",black_pos);\r
+\r
+    \r
+    if(extended_search){\r
+        init_info(info);\r
+        info->book_trans_only=TRUE;\r
+        info->initial_color=White;\r
+        info->extended_search=TRUE;\r
+        book_clean();\r
+        board_start(board);\r
+        search_book(board,info, BOOK);\r
+\r
+        init_info(info);\r
+        info->book_trans_only=TRUE;\r
+        info->initial_color=Black;\r
+        info->extended_search=TRUE;\r
+        book_clean();\r
+        board_start(board);\r
+        search_book(board,info, ALL);\r
+        book_clean();\r
+        ASSERT(Book->size==s);\r
+        white_pos_extended=0;\r
+        black_pos_extended=0;\r
+        last_key=0;\r
+        for(pos=0;pos<Book->size;pos++){\r
+            if(Book->entry[pos].key==last_key){\r
+                ASSERT(Book->entry[pos].colour==ColourNone);\r
+                continue;\r
+            }\r
+            last_key=Book->entry[pos].key;\r
+            if(Book->entry[pos].colour==White){\r
+                white_pos_extended++;\r
+            }else if(Book->entry[pos].colour==Black){\r
+                black_pos_extended++;\r
+            }\r
+        }\r
+        white_pos_extended_diff=white_pos_extended-white_pos;\r
+        black_pos_extended_diff=black_pos_extended-black_pos;\r
+        printf("Unreachable white positions(?) : %8d\n",\r
+               white_pos_extended_diff);\r
+        printf("Unreachable black positions(?) : %8d\n",\r
+               black_pos_extended_diff);\r
+\r
+    }\r
+    if(extended_search){\r
+        printf("Isolated positions             : %8d\n",\r
+               total_pos-white_pos_extended-black_pos_extended);\r
+    }else{\r
+        printf("Isolated positions             : %8d\n",\r
+               total_pos-white_pos-black_pos);\r
+    }\r
+}\r
+\r
+\r
+\r
 // end of book_make.cpp\r
 \r
index 3302db4..f4054c0 100644 (file)
@@ -11,6 +11,8 @@
 // functions\r
 \r
 extern void book_make (int argc, char * argv[]);\r
+extern void book_dump (int argc, char * argv[]);\r
+extern void book_info (int argc, char * argv[]);\r
 \r
 #endif // !defined BOOK_MAKE_H\r
 \r
index 2de88c9..f9a4be7 100644 (file)
--- a/config.h
+++ b/config.h
 #define PACKAGE_NAME "polyglot"
 
 /* Define to the full name and version of this package. */
-#define PACKAGE_STRING "polyglot 1.4w10UCIb17"
+#define PACKAGE_STRING "polyglot 1.4w10UCIb18"
 
 /* Define to the one symbol short name of this package. */
 #define PACKAGE_TARNAME "polyglot"
 
 /* Define to the version of this package. */
-#define PACKAGE_VERSION "1.4w10UCIb17"
+#define PACKAGE_VERSION "1.4w10UCIb18"
 
 /* Define to 1 if the C compiler supports function prototypes. */
 #define PROTOTYPES 1
 #define TIME_WITH_SYS_TIME 1
 
 /* Version number of package */
-#define VERSION "1.4w10UCIb17"
+#define VERSION "1.4w10UCIb18"
 
 /* Define like PROTOTYPES; this can be used by system headers. */
 #define __PROTOTYPES 1
index 77ab853..1dfe736 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.61 for polyglot 1.4w10UCIb17.
+# Generated by GNU Autoconf 2.61 for polyglot 1.4w10UCIb18.
 #
 # Report bugs to <michel.vandenbergh@uhasselt.be>.
 #
@@ -574,8 +574,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
 # Identity of this package.
 PACKAGE_NAME='polyglot'
 PACKAGE_TARNAME='polyglot'
-PACKAGE_VERSION='1.4w10UCIb17'
-PACKAGE_STRING='polyglot 1.4w10UCIb17'
+PACKAGE_VERSION='1.4w10UCIb18'
+PACKAGE_STRING='polyglot 1.4w10UCIb18'
 PACKAGE_BUGREPORT='michel.vandenbergh@uhasselt.be'
 
 ac_unique_file="mainloop.cpp"
@@ -1216,7 +1216,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures polyglot 1.4w10UCIb17 to adapt to many kinds of systems.
+\`configure' configures polyglot 1.4w10UCIb18 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1282,7 +1282,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of polyglot 1.4w10UCIb17:";;
+     short | recursive ) echo "Configuration of polyglot 1.4w10UCIb18:";;
    esac
   cat <<\_ACEOF
 
@@ -1368,7 +1368,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-polyglot configure 1.4w10UCIb17
+polyglot configure 1.4w10UCIb18
 generated by GNU Autoconf 2.61
 
 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1382,7 +1382,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by polyglot $as_me 1.4w10UCIb17, which was
+It was created by polyglot $as_me 1.4w10UCIb18, which was
 generated by GNU Autoconf 2.61.  Invocation command line was
 
   $ $0 $@
@@ -2072,7 +2072,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='polyglot'
- VERSION='1.4w10UCIb17'
+ VERSION='1.4w10UCIb18'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -7344,7 +7344,7 @@ exec 6>&1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by polyglot $as_me 1.4w10UCIb17, which was
+This file was extended by polyglot $as_me 1.4w10UCIb18, which was
 generated by GNU Autoconf 2.61.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -7397,7 +7397,7 @@ Report bugs to <bug-autoconf@gnu.org>."
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
 ac_cs_version="\\
-polyglot config.status 1.4w10UCIb17
+polyglot config.status 1.4w10UCIb18
 configured by $0, generated by GNU Autoconf 2.61,
   with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
 
index 1973b38..987344d 100644 (file)
@@ -2,7 +2,7 @@
 # Process this file with autoconf to produce a configure script.
 
 AC_PREREQ(2.61)
-AC_INIT([polyglot], [1.4w10UCIb17], [michel.vandenbergh@uhasselt.be])
+AC_INIT([polyglot], [1.4w10UCIb18], [michel.vandenbergh@uhasselt.be])
 AM_INIT_AUTOMAKE
 AC_CONFIG_SRCDIR([mainloop.cpp])
 AC_CONFIG_HEADER([config.h])
index a898049..b674272 100644 (file)
@@ -22,7 +22,7 @@
 \r
 // constants\r
 \r
-static const int StringSize = 4096;\r
+static const unsigned int StringSize = 4096;\r
 \r
 // variables\r
 \r
index b46be4a..83f1019 100644 (file)
--- a/main.cpp
+++ b/main.cpp
 // constants\r
 \r
 \r
-static const char * const Version = "1.4W10UCIb17";\r
+static const char * const Version = "1.4W10UCIb18";\r
 static const char * const HelpMessage = "\\r
 SYNTAX\n\\r
-polyglot [configfile]\n\\r
-polyglot make-book [-pgn inputfile] [-bin outputfile] [-max-ply ply] [-min-game games] [-min-score score] [-only-white] [-only-black] [-uniform]\n\\r
-polyglot merge-book -in1 inputfile1 -in2 inputfile2 [-out outputfile]\n\\r
-polyglot [configfile] epd-test [-epd inputfile] [-min-depth depth] [-max-depth depth] [-max-time time] [-depth-delta delta]\n\\r
-polyglot perft [-fen fen] [-max-depth depth]\\r
+* polyglot [configfile]\n\\r
+* polyglot -ec enginecommand\n\\r
+* polyglot make-book [-pgn inputfile] [-bin outputfile] [-max-ply ply] [-min-game games] [-min-score score] [-only-white] [-only-black] [-uniform]\n\\r
+* polyglot merge-book -in1 inputfile1 -in2 inputfile2 [-out outputfile]\n\\r
+* polyglot info-book [-bin inputfile] [-exact]\n\\r
+* polyglot dumb-book [-bin inputfile] -color color [-out outputfile]\n\\r
+* polyglot [configfile] epd-test [-epd inputfile] [-min-depth depth] [-max-depth depth] [-max-time time] [-depth-delta delta]\n\\r
+* polyglot perft [-fen fen] [-max-depth depth]\\r
 ";\r
 \r
 static const int SearchDepth = 63;\r
@@ -59,7 +62,6 @@ static void parse_option ();
 static void init_book ();\r
 static bool parse_line   (char line[], char * * name_ptr, char * * value_ptr);\r
 static void stop_search  ();\r
-static void sig_quit(int);\r
 \r
 // functions\r
 \r
@@ -101,6 +103,21 @@ int main(int argc, char * argv[]) {
         book_merge(argc,argv);\r
         return EXIT_SUCCESS;\r
     }\r
+\r
+       if (argc >= 2 && my_string_equal(argv[1],"merge-book")) {\r
+      book_merge(argc,argv);\r
+      return EXIT_SUCCESS;\r
+   }\r
+\r
+   if (argc >= 2 && my_string_equal(argv[1],"dump-book")) {\r
+      book_dump(argc,argv);\r
+      return EXIT_SUCCESS;\r
+   }\r
+\r
+   if (argc >= 2 && my_string_equal(argv[1],"info-book")) {\r
+      book_info(argc,argv);\r
+      return EXIT_SUCCESS;\r
+   }\r
     \r
     if (argc >= 2 && my_string_equal(argv[1],"perft")) {\r
         do_perft(argc,argv);\r
@@ -185,7 +202,6 @@ void polyglot_set_option(char *name, char *value){ // this must be cleaned up!
 // init_book()\r
 \r
 static void init_book(){\r
-    const char *empty_var[]={};\r
     book_clear();\r
     if (option_get_bool("Book")){\r
         my_log("POLYGLOT *** SETTING BOOK ***\n");\r
@@ -221,8 +237,6 @@ static void parse_option() {
            my_fatal("parse_option(): missing [Engine] section\n");\r
        }\r
        \r
-       if(line[0]=='#') continue;\r
-       \r
        if (my_string_case_equal(line,"[engine]")) break;\r
        \r
        if (parse_line(line,&name,&value)) {\r
@@ -249,8 +263,6 @@ static void parse_option() {
    Init = true;\r
    while (my_file_read_line(file,line,256)) {\r
        if (line[0] == '[') my_fatal("parse_option(): unknown section %s\n",line);\r
-       if (line[0]=='#') continue;\r
-       \r
        if (parse_line(line,&name,&value)) {\r
            uci_send_option(Uci,name,"%s",value);\r
                //to get a decent display in winboard_x we need to now if an engine really is doing multipv analysis\r
index 0462000..5cb5024 100644 (file)
@@ -81,7 +81,7 @@ void option_init() {
     option_t *p=Option;\r
     const char * name;\r
 \r
-    while(name=(p++)->name){\r
+    while((name=(p++)->name)){\r
         option_set(name,option_get_default(name));\r
     }\r
 }\r
index 9b12c38..f2340f4 100644 (file)
--- a/parse.cpp
+++ b/parse.cpp
@@ -83,7 +83,7 @@ bool parse_is_ok(const parse_t * parse) {
 \r
    if (parse == NULL) return false;\r
    if (parse->string == NULL) return false;\r
-   if (parse->pos < 0 || parse->pos > strlen(parse->string)) return false;\r
+   if (parse->pos < 0 || parse->pos > (int) strlen(parse->string)) return false;\r
    if (parse->keyword_nb < 0 || parse->keyword_nb >= KEYWORD_NUMBER) return false;\r
 \r
    return true;\r
index e6d0ca8..e0dcef7 100644 (file)
 .\" ========================================================================
 .\"
 .IX Title "POLYGLOT 6"
-.TH POLYGLOT 6 "2009-01-14" "" ""
+.TH POLYGLOT 6 "2009-01-15" "" ""
 .SH "NAME"
 PolyGlot \-  Winboard protocol to UCI protocol adapter
          \-  book engine for Polyglot books 
-         \-  a collection of utilities for creating opening books
+         \-  a collection of utilities for creating and analyzing opening books
          \-  a utility for analyzing epd files
          \-  a perft counter
 .SH "SYNOPSIS"
@@ -146,6 +146,10 @@ polyglot make-book [\-pgn inputfile] [\-bin outputfile] [\-max\-ply ply] [\-min\
 .PP
 polyglot merge-book \-in1 inputfile1 \-in2 inputfile2 [\-out outputfile]
 .PP
+polyglot info-book [\-bin inputfile] [\-exact]
+.PP
+polyglot dumb-book [\-bin inputfile] \-color color [\-out outputfile]
+.PP
 polyglot [configfile] epd-test [\-epd inputfile] [\-min\-depth depth] [\-max\-depth depth] [\-max\-time time] [\-depth\-delta delta] 
 .PP
 polyglot perft [\-fen fen] [\-max\-depth depth]
@@ -200,7 +204,33 @@ Other opening book formats such as ChessBase's .ctg format and Arena's
 by their own GUIs. 
 .PP
 PolyGlot can compile a pgn file into a binary PolyGlot book and furthermore
-it can merge two such binary books into a third one. 
+it can merge two such binary books into a third one.
+.PP
+PolyGlot can also extract some useful information from PolyGlot books. The utility
+\&\*(L"dump\-book\*(R" dumps the \*(L"lines\*(R" in a book for a given color. By definition
+a line is a sequence of moves (from the starting position) in which
+the given color makes only book moves and the other color makes 
+arbitrary moves (i.e. not necessarily book moves).
+.PP
+Since a PolyGlot book is built up from positions and not lines there
+may be (and there usually are) many positions in the book that are not
+on a \*(L"line\*(R" as defined in the previous paragraph. It is convenient
+to call such positions \*(L"isolated\*(R" positions. The utility \*(L"info\-book\*(R"
+counts such isolated positions.
+.PP
+Some of the isolated positions are provably unreachable and they
+could in principle be deleted from the book. For example if a book
+contains only the move \*(L"e4\*(R" in the starting position but also the
+position after \*(L"d4 d5\*(R" then this last position is provably unreachable
+since it requires white to make a non-book move when a book move is
+available. Such situations arise frequently from the priority rules
+in merging books.
+.PP
+Unfortunately not all isolated positions are provably unreachable and
+it is difficult to identify the latter. If invoked with \*(L"\-exact\*(R" the
+utility info-book will attempt to count the isolated positions which
+require a player to make a non-book move when a book move is available.
+Due to the possibility of transpositions this is not a fool proof method.
 .Sh "Epd test mode"
 .IX Subsection "Epd test mode"
 In epd test mode, PolyGlot will search positions in an epd file and
@@ -277,6 +307,34 @@ Input files are not symmetrical, \*(L"in1\*(R" has priority over \*(L"in2\*(R".
 words when a position occurs both in \*(L"in1\*(R" and \*(L"in2\*(R" only the
 moves and weights from \*(L"in1\*(R" will be retained in \*(L"out\*(R".
 .PP
+When invoked
+as
+.Sh "polyglot dump-book"
+.IX Subsection "polyglot dump-book"
+PolyGlot supports the following options
+.IP "\fB\-bin\fR (default: book.bin)" 4
+.IX Item "-bin (default: book.bin)"
+Input file in PolyGlot book format.
+.IP "\fB\-color\fR" 4
+.IX Item "-color"
+The color for whom to generate the lines.
+.IP "\fB\-out\fR (default: book_<color>.txt)" 4
+.IX Item "-out (default: book_<color>.txt)"
+The name of the output file.
+.PP
+When invoked
+as
+.Sh "polyglot info-book"
+.IX Subsection "polyglot info-book"
+PolyGlot supports the following options
+.IP "\fB\-bin\fR (default: book.bin)" 4
+.IX Item "-bin (default: book.bin)"
+Input file in PolyGlot book format.
+.IP "\fB\-exact\fR" 4
+.IX Item "-exact"
+Attempt to count the provably unreachable positions among the isolated ones.
+Note that this takes a very long time. 
+.PP
 When invoked as
 .Sh "polyglot epd-test"
 .IX Subsection "polyglot epd-test"
index db61280..0024cd1 100644 (file)
@@ -2,7 +2,7 @@
 
 PolyGlot -  Winboard protocol to UCI protocol adapter
          -  book engine for Polyglot books 
-         -  a collection of utilities for creating opening books
+         -  a collection of utilities for creating and analyzing opening books
          -  a utility for analyzing epd files
          -  a perft counter
 
@@ -16,6 +16,10 @@ polyglot make-book [-pgn inputfile] [-bin outputfile] [-max-ply ply] [-min-game
 
 polyglot merge-book -in1 inputfile1 -in2 inputfile2 [-out outputfile]
 
+polyglot info-book [-bin inputfile] [-exact]
+
+polyglot dumb-book [-bin inputfile] -color color [-out outputfile]
+
 polyglot [configfile] epd-test [-epd inputfile] [-min-depth depth] [-max-depth depth] [-max-time time] [-depth-delta delta] 
 
 polyglot perft [-fen fen] [-max-depth depth]
@@ -72,7 +76,33 @@ Other opening book formats such as ChessBase's .ctg format and Arena's
 by their own GUIs. 
 
 PolyGlot can compile a pgn file into a binary PolyGlot book and furthermore
-it can merge two such binary books into a third one. 
+it can merge two such binary books into a third one.
+
+PolyGlot can also extract some useful information from PolyGlot books. The utility
+"dump-book" dumps the "lines" in a book for a given color. By definition
+a line is a sequence of moves (from the starting position) in which
+the given color makes only book moves and the other color makes 
+arbitrary moves (i.e. not necessarily book moves).
+
+Since a PolyGlot book is built up from positions and not lines there
+may be (and there usually are) many positions in the book that are not
+on a "line" as defined in the previous paragraph. It is convenient
+to call such positions "isolated" positions. The utility "info-book"
+counts such isolated positions.
+
+Some of the isolated positions are provably unreachable and they
+could in principle be deleted from the book. For example if a book
+contains only the move "e4" in the starting position but also the
+position after "d4 d5" then this last position is provably unreachable
+since it requires white to make a non-book move when a book move is
+available. Such situations arise frequently from the priority rules
+in merging books.
+
+Unfortunately not all isolated positions are provably unreachable and
+it is difficult to identify the latter. If invoked with "-exact" the
+utility info-book will attempt to count the isolated positions which
+require a player to make a non-book move when a book move is available.
+Due to the possibility of transpositions this is not a fool proof method.
 
 =head2 Epd test mode
 
@@ -172,6 +202,49 @@ Input files are not symmetrical, "in1" has priority over "in2". In other
 words when a position occurs both in "in1" and "in2" only the
 moves and weights from "in1" will be retained in "out".
 
+When invoked
+as
+
+=head2 polyglot dump-book
+
+PolyGlot supports the following options
+
+=over 4
+
+=item B<-bin> (default: book.bin)
+
+Input file in PolyGlot book format.
+
+=item B<-color> 
+
+The color for whom to generate the lines.
+
+=item B<-out> (default: book_<color>.txt)
+
+The name of the output file.
+
+=back
+
+When invoked
+as
+
+=head2 polyglot info-book
+
+PolyGlot supports the following options
+
+=over 4
+
+=item B<-bin> (default: book.bin)
+
+Input file in PolyGlot book format.
+
+=item B<-exact> 
+
+Attempt to count the provably unreachable positions among the isolated ones.
+Note that this takes a very long time. 
+
+=back
+
 When invoked as
 
 =head2 polyglot epd-test
index 67a4465..959b69d 100644 (file)
@@ -1,6 +1,6 @@
 Summary: A Winboard protocol to UCI protocol adapter
 Name: polyglot
-Version: 1.4w10UCIb17
+Version: 1.4w10UCIb18
 Release: 1
 License: GPL
 Group: Amusement/Games
index 5dab703..a19b4da 100644 (file)
@@ -146,9 +146,8 @@ static void format_uci_option_line(char * option_line,option_t *opt){
 // send_uci_options()
 
 void send_uci_options() {
-    int i,j;
+    int i;
     option_t *p=Option;
-    const char * name;
     char option_line[StringSize]="";
     gui_send(GUI,"id name %s", Uci->name);
     gui_send(GUI,"id author %s", Uci->author);
@@ -171,7 +170,6 @@ void send_uci_options() {
 
 
 static void parse_setoption(const char string[]) {
-    parse_t parse[1];
     char *name;
     char *pg_name;
     char *value;
diff --git a/util.h b/util.h
index 9449f12..759cd16 100644 (file)
--- a/util.h
+++ b/util.h
 #  define ASSERT(a)\r
 #endif\r
 \r
+#ifdef _WIN32\r
+#define snprintf _snprintf\r
+#endif\r
+\r
 // types\r
 \r
 typedef signed char sint8;\r
index ed241a0..1ffda48 100644 (file)
@@ -479,7 +479,7 @@ void xboard_step(char string[]) {
         } else if (XB->has_feature_egt && match(string,"egtpath * *")){\r
                 char *type=Star[0];\r
                 char *path=Star[1];\r
-                if(!my_string_case_equal(Star[0],"nalimov")){\r
+                if(!my_string_case_equal(type,"nalimov")){\r
                    // refuse\r
                     gui_send(GUI,"Error (unsupported table base format): %s",string);\r
                 }else if(my_string_empty(path)){\r
@@ -1132,8 +1132,6 @@ static void search_update() {
    int move;\r
    int move_nb;\r
    board_t board[1];\r
-   int nalimov_cache;\r
-   int real_memory;\r
 \r
    ASSERT(!Uci->searching);\r
 \r