int find_key(FILE *f, uint64 key, entry_t *entry){ int first, last, middle; entry_t first_entry=entry_none, last_entry,middle_entry; first=-1; if(fseek(f,-16,SEEK_END)){ *entry=entry_none; entry->key=key+1; //hack return -1; } last=ftell(f)/16; entry_from_file(f,&last_entry); while(1){ if(last-first==1){ *entry=last_entry; return last; } middle=(first+last)/2; fseek(f,16*middle,SEEK_SET); entry_from_file(f,&middle_entry); if(key<=middle_entry.key){ last=middle; last_entry=middle_entry; }else{ first=middle; first_entry=middle_entry; } } }
Move openBookAndGetNextMove(char* file_name, uint64* key){ FILE *f; entry_t entry; int offset; entry_t entries[MAX_MOVES]; int count=0; int ret, i; char move_s[6]; int total_weight; Move lastChosen={0,0}; f=fopen(file_name,"rb"); if(!f){ perror(file_name); return lastChosen; } offset=find_key(f,*key,&entry); if(entry.key!=*key){ // printf("%016llx: No such key\n",key); return lastChosen; } entries[0]=entry; count=1; fseek(f,16*(offset+1),SEEK_SET); while(1){ ret=entry_from_file(f,&entry); if(ret){ break; } if(entry.key!=*key){ break; } if(count==MAX_MOVES){ printf("#Too many moves in this position (max=%d)\n",MAX_MOVES); return lastChosen; } entries[count++]=entry; } total_weight=0; for(i=0;i<count;i++){ total_weight+=entries[i].weight; } double weightForChoosing=0; // srand(clock()); double randomNumber=(double)rand()/RAND_MAX; for(i=0;i<count;i++){ move_to_string(move_s,entries[i].move); if(move_s[0]>='a'&&move_s[0]<='h'){ if(move_s[1]>='1'&&move_s[1]<='8'){ if(move_s[2]>='a'&&move_s[2]<='h'){ if(move_s[3]>='1'&&move_s[3]<='8'){ lastChosen.from=(int)(move_s[0]-'a')+0x10*(7-(int)(move_s[1]-'1')); lastChosen.to=(int)(move_s[2]-'a')+0x10*(7-(int)(move_s[3]-'1')); if(move_s[4]=='q') lastChosen.promote=queen; else if(move_s[4]=='r') lastChosen.promote=knight; else if(move_s[4]=='b') lastChosen.promote=bishop; else if(move_s[4]=='n') lastChosen.promote=knight; } } } } printf("#move=%s weight=%5.2f%%\n", move_s, 100*((double) entries[i].weight/ (double) total_weight)); weightForChoosing+=((double) entries[i].weight/ (double) total_weight); if(weightForChoosing>randomNumber) break; } return lastChosen; }