2 * This utility looks up the moves and their scores in a Polyglot book
5 * pg_show <book> <hex key>"
7 * You can find the hex key of a FEN using pg_key.
9 * This code is released in the public domain by Michel Van den Bergh.
17 typedef unsigned char uint8;
18 typedef unsigned short uint16;
19 typedef unsigned int uint32;
22 typedef unsigned __int64 uint64;
24 typedef unsigned long long int uint64;
34 entry_t entry_none = {
38 char *promote_pieces=" nbrq";
42 int int_from_file(FILE *f, int l, uint64 *r){
54 int entry_from_file(FILE *f, entry_t *entry){
57 ret=int_from_file(f,8,&r);
60 ret=int_from_file(f,2,&r);
63 ret=int_from_file(f,2,&r);
66 ret=int_from_file(f,4,&r);
72 int find_key(FILE *f, uint64 key, entry_t *entry){
73 int first, last, middle;
74 entry_t first_entry=entry_none, last_entry,middle_entry;
76 if(fseek(f,-16,SEEK_END)){
78 entry->key=key+1; //hack
82 entry_from_file(f,&last_entry);
88 middle=(first+last)/2;
89 fseek(f,16*middle,SEEK_SET);
90 entry_from_file(f,&middle_entry);
91 if(key<=middle_entry.key){
93 last_entry=middle_entry;
96 first_entry=middle_entry;
101 void move_to_string(char move_s[6], uint16 move){
102 int f,fr,ff,t,tr,tf,p;
115 move_s[4]=promote_pieces[p];
120 if(!strcmp(move_s,"e1h1")){
121 strcpy(move_s,"e1g1");
122 }else if(!strcmp(move_s,"e1a1")){
123 strcpy(move_s,"e1c1");
124 }else if(!strcmp(move_s,"e8h8")){
125 strcpy(move_s,"e8g8");
126 }else if(!strcmp(move_s,"e8a8")){
127 strcpy(move_s,"e8c8");
131 int main(int argc, char *argv[]){
137 entry_t entries[MAX_MOVES];
143 printf("Usage: pg_show <book> <hex key>\n");
148 sscanf(argv[2],"%16I64x",&key);
150 sscanf(argv[2],"%16llx",&key);
152 f=fopen(file_name,"rb");
157 offset=find_key(f,key,&entry);
160 printf("%016I64x: No such key\n",key);
162 printf("%016llx: No such key\n",key);
168 fseek(f,16*(offset+1),SEEK_SET);
170 ret=entry_from_file(f,&entry);
177 if(count==MAX_MOVES){
178 printf("Too many moves in this position (max=%d)\n",MAX_MOVES);
181 entries[count++]=entry;
184 for(i=0;i<count;i++){
185 total_weight+=entries[i].weight;
187 for(i=0;i<count;i++){
188 move_to_string(move_s,entries[i].move);
189 printf("move=%s weight=%5.2f%%\n",
191 100*((double) entries[i].weight/ (double) total_weight));