aboutsummaryrefslogtreecommitdiffstats
path: root/FICS/eco.c
diff options
context:
space:
mode:
authorMarkus Uhlin <markus@nifty-networks.net>2023-12-07 21:31:49 +0100
committerMarkus Uhlin <markus@nifty-networks.net>2023-12-07 21:31:49 +0100
commit79b59f9b30fb6a1fdf8c3efb446271f7cb00d434 (patch)
treef6ade4ccbc3af20d825edacfd12b5da8ded8d240 /FICS/eco.c
FICS 1.6.2
Diffstat (limited to 'FICS/eco.c')
-rw-r--r--FICS/eco.c428
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, &param[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;
+}