diff options
Diffstat (limited to 'FICS/eco.c')
-rw-r--r-- | FICS/eco.c | 428 |
1 files changed, 428 insertions, 0 deletions
diff --git a/FICS/eco.c b/FICS/eco.c new file mode 100644 index 0000000..80b1196 --- /dev/null +++ b/FICS/eco.c @@ -0,0 +1,428 @@ +#include "stdinclude.h" +#include "board.h" +#include "gamedb.h" +#include "command.h" +#include "playerdb.h" +#include "gameproc.h" +#include "obsproc.h" +#include "utils.h" +#include "common.h" +#include "config.h" + +PUBLIC char *book_dir = DEFAULT_BOOK; + +typedef struct { + char ECO[4]; + char FENpos[80]; +} ECO_entry; + +typedef struct { + char NIC[6]; + char FENpos[80]; +} NIC_entry; + +typedef struct { + char LONG[80]; + char FENpos[80]; +} LONG_entry; + +ECO_entry *ECO_book[1096]; +NIC_entry *NIC_book[1096]; +LONG_entry *LONG_book[4096]; + +int ECO_entries, NIC_entries, LONG_entries; + +char *boardToFEN(int g) +{ + int i,j; + static char FENstring[80]; + int FENcount = 0; + int space = 0; + + for(i=7; i>=0; i--) { + for(j=0; j<8; j++) { + switch(garray[g].game_state.board[j][i]) { + case W_PAWN: + if (space>0) { + FENstring[FENcount++]=space+'0'; + space=0; + } + FENstring[FENcount++]='P'; + break; + case W_ROOK: + if (space>0) { + FENstring[FENcount++]=space+'0'; + space=0; + } + FENstring[FENcount++]='R'; + break; + case W_KNIGHT: + if (space>0) { + FENstring[FENcount++]=space+'0'; + space=0; + } + FENstring[FENcount++]='N'; + break; + case W_BISHOP: + if (space>0) { + FENstring[FENcount++]=space+'0'; + space=0; + } + FENstring[FENcount++]='B'; + break; + case W_QUEEN: + if (space>0) { + FENstring[FENcount++]=space+'0'; + space=0; + } + FENstring[FENcount++]='Q'; + break; + case W_KING: + if (space>0) { + FENstring[FENcount++]=space+'0'; + space=0; + } + FENstring[FENcount++]='K'; + break; + case B_PAWN: + if (space>0) { + FENstring[FENcount++]=space+'0'; + space=0; + } + FENstring[FENcount++]='p'; + break; + case B_ROOK: + if (space>0) { + FENstring[FENcount++]=space+'0'; + space=0; + } + FENstring[FENcount++]='r'; + break; + case B_KNIGHT: + if (space>0) { + FENstring[FENcount++]=space+'0'; + space=0; + } + FENstring[FENcount++]='n'; + break; + case B_BISHOP: + if (space>0) { + FENstring[FENcount++]=space+'0'; + space=0; + } + FENstring[FENcount++]='b'; + break; + case B_QUEEN: + if (space>0) { + FENstring[FENcount++]=space+'0'; + space=0; + } + FENstring[FENcount++]='q'; + break; + case B_KING: + if (space>0) { + FENstring[FENcount++]=space+'0'; + space=0; + } + FENstring[FENcount++]='k'; + break; + default: + space++; + break; + } + } + if (space>0) { + FENstring[FENcount++]=space+'0'; + space=0; + } + FENstring[FENcount++]='/'; + } + FENstring[--FENcount]=' '; + FENstring[++FENcount]=(garray[g].game_state.onMove==WHITE) ? 'w' : 'b'; + FENstring[++FENcount]='\0'; + return FENstring; +} + +void ECO_init() +{ + FILE *fp; + char tmp[1024]; + char *ptmp= tmp; + char FENpos[73], ECO[4], onMove[2]; + char filename[1024]; + int i=0; + + sprintf(filename, "%s/eco999.idx", book_dir); + fp= fopen(filename, "r"); + if (!fp) { + fprintf(stderr, "Could not open ECO file\n"); + exit(1); + } + while (!feof(fp)) { + strcpy(ptmp, ""); + fgets(ptmp, 1024, fp); + if (feof(fp)) continue; + sscanf(ptmp, "%[\x21-z] %s", FENpos, onMove); + sprintf(FENpos, "%s %s", FENpos, onMove); + strcpy(ptmp, ""); + fgets(ptmp, 1024, fp); + if (feof(fp)) continue; + sscanf(ptmp, "%[0-z]", ECO); + ECO_book[i]= (ECO_entry *) malloc(sizeof(ECO_entry)); + if (ECO_book[i]==NULL) { + fprintf(stderr, "Cound not alloc mem for ECO entry %d.\n", i); + exit(1); + } + strcpy(ECO_book[i]->ECO, ECO); + strcpy(ECO_book[i]->FENpos, FENpos); + ++i; + } + fclose(fp); + ECO_book[i]=NULL; + fprintf(stderr, "%d entries in ECO book\n", i); + ECO_entries = i; + + while (--i >= 0) + if (ECO_book[i] == NULL) + fprintf(stderr, "ERROR! ECO book position number %d is NULL.", i); +} + +void NIC_init() +{ + FILE *fp; + char tmp[1024]; + char *ptmp= tmp; + char FENpos[73], NIC[6], onMove[2]; + char filename[1024]; + int i=0; + + sprintf(filename, "%s/nic999.idx", book_dir); + fp= fopen(filename, "r"); + if (!fp) { + fprintf(stderr, "Could not open NIC file\n"); + exit(1); + } + while (!feof(fp)) { + strcpy(ptmp, ""); + fgets(ptmp, 1024, fp); + if (feof(fp)) continue; + sscanf(ptmp, "%[\x21-z] %s", FENpos, onMove); + sprintf(FENpos, "%s %s", FENpos, onMove); + strcpy(ptmp, ""); + fgets(ptmp, 1024, fp); + if (feof(fp)) continue; + sscanf(ptmp, "%[.-z]", NIC); + NIC_book[i]= (NIC_entry *) malloc(sizeof(NIC_entry)); + if (NIC_book[i]==NULL) { + fprintf(stderr, "Cound not alloc mem for NIC entry %d.\n", i); + exit(1); + } + strcpy(NIC_book[i]->NIC, NIC); + strcpy(NIC_book[i]->FENpos, FENpos); + ++i; + } + fclose(fp); + NIC_book[i]=NULL; + fprintf(stderr, "%d entries in NIC book\n", i); + NIC_entries = i; +} + +void LONG_init() +{ + FILE *fp; + char tmp[1024]; + char *ptmp= tmp; + char FENpos[73], LONG[256], onMove[2]; + char filename[1024]; + int i=0; + + sprintf(filename, "%s/long999.idx", book_dir); + fp= fopen(filename, "r"); + if (!fp) { + fprintf(stderr, "Could not open LONG file\n"); + exit(1); + } + while (!feof(fp)) { + strcpy(ptmp, ""); + fgets(ptmp, 1024, fp); + if (feof(fp)) continue; + sscanf(ptmp, "%[\x21-z] %s", FENpos, onMove); + sprintf(FENpos, "%s %s", FENpos, onMove); + strcpy(ptmp, ""); + fgets(ptmp, 1024, fp); + if (feof(fp)) continue; + sscanf(ptmp, "%[^*\n]", LONG); + LONG_book[i]= (LONG_entry *) malloc(sizeof(LONG_entry)); + if (LONG_book[i]==NULL) { + fprintf(stderr, "Cound not alloc mem for LONG entry %d.\n", i); + exit(1); + } + strcpy(LONG_book[i]->LONG, LONG); + strcpy(LONG_book[i]->FENpos, FENpos); + ++i; + } + fclose(fp); + LONG_book[i]=NULL; + fprintf(stderr, "%d entries in LONG book\n", i); + LONG_entries = i; +} + +void BookInit() +{ + ECO_init(); + NIC_init(); + LONG_init(); +} + +char *getECO(int g) +{ + static char ECO[4]; + +#ifndef IGNORE_ECO + + int i, flag, l = 0, r = ECO_entries - 1, x; + + + if ((parray[garray[g].white].private) || (parray[garray[g].black].private)) { + strcpy(ECO, "---"); + return ECO; + } else { + if (garray[g].type == TYPE_WILD) { + strcpy(ECO, "---"); + return ECO; + } else if (garray[g].moveList == NULL) { + strcpy(ECO, "***"); + return ECO; + } else { + strcpy(ECO, "A00"); + } + } + + for (flag=0,i=garray[g].numHalfMoves; (i>0 && !flag); i--) { + l = 0; + r = ECO_entries - 1; + while ((r >= l) && !flag) { + x = (l+r)/2; + if ((strcmp(garray[g].moveList[i].FENpos, ECO_book[x]->FENpos)) < 0) + r = x - 1; + else + l = x + 1; + if (!strcmp(garray[g].moveList[i].FENpos, ECO_book[x]->FENpos)) { + strcpy(ECO, ECO_book[x]->ECO); + flag=1; + } + } + } +#else + + strcpy(ECO, "---"); + +#endif + + + return ECO; +} + +PUBLIC int com_eco(int p, param_list param) +{ + +#ifndef IGNORE_ECO + + int i, flag = 0, x, l, r; + int g1, p1; + + + if (param[0].type == TYPE_NULL) { /* own game */ + if (parray[p].game < 0) { + pprintf(p, "You are not playing or examining a game.\n"); + return COM_OK; + } + g1=parray[p].game; + if (garray[g1].status != GAME_EXAMINE && !pIsPlaying(p)) + return COM_OK; + } else { + g1 = GameNumFromParam (p, &p1, ¶m[0]); + if (g1 < 0) return COM_OK; + if ((g1 >= g_num) || ((garray[g1].status != GAME_ACTIVE) && + (garray[g1].status != GAME_EXAMINE))) { + pprintf(p, "There is no such game.\n"); + return COM_OK; + } + } + + if ((((parray[garray[g1].white].private) || + (parray[garray[g1].black].private))) && + (parray[p].adminLevel==0)) { + pprintf(p, "Sorry - that game is private.\n"); + return COM_OK; + } else { + if (garray[g1].type == TYPE_WILD) { + pprintf(p, "That game is a wild game.\n"); + return COM_OK; + } + } + + pprintf(p, "Info about game %d: \"%s vs. %s\"\n\n", g1+1, + garray[g1].white_name, + garray[g1].black_name); + + if (garray[g1].moveList==NULL) { + return COM_OK; + } + + for (flag=0,i=garray[g1].numHalfMoves; (i>0 && !flag); i--) { + l = 0; + r = ECO_entries - 1; + while ((r >= l) && !flag) { + x = (l+r)/2; + if ((strcmp(garray[g1].moveList[i].FENpos, ECO_book[x]->FENpos)) < 0) + r = x - 1; + else + l = x + 1; + if (!strcmp(garray[g1].moveList[i].FENpos, ECO_book[x]->FENpos)) { + pprintf(p, " ECO[%3d]: %s\n", i, ECO_book[x]->ECO); + flag=1; + } + } + } + + for (flag=0, i=garray[g1].numHalfMoves; ((i>0) && (!flag)); i--) { + l = 0; + r = NIC_entries - 1; + while ((r >=l) && !flag) { + x = (l+r)/2; + if ((strcmp(garray[g1].moveList[i].FENpos, NIC_book[x]->FENpos)) < 0) + r = x - 1; + else + l = x + 1; + if (!strcmp(garray[g1].moveList[i].FENpos, NIC_book[x]->FENpos)) { + pprintf(p, " NIC[%3d]: %s\n", i, NIC_book[x]->NIC); + flag=1; + } + } + } + + for (flag=0, i=garray[g1].numHalfMoves; ((i>0) && (!flag)); i--) { + l = 0; + r = LONG_entries - 1; + while ((r >=l) && !flag) { + x = (l+r)/2; + if ((strcmp(garray[g1].moveList[i].FENpos, LONG_book[x]->FENpos)) < 0) + r = x - 1; + else + l = x + 1; + if (!strcmp(garray[g1].moveList[i].FENpos, LONG_book[x]->FENpos)) { + pprintf(p, " LONG[%3d]: %s\n", i, LONG_book[x]->LONG); + flag=1; + } + } + } + +#else + + pprintf(p, "ECO not available... out of service!.\n"); + +#endif + + return COM_OK; +} |