|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T m
Length: 25561 (0x63d9) Types: TextFile Names: »main.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki └─⟦this⟧ »EUUGD11/gnu-31mar87/chess/main.c«
/* This file contains the command-parser for CHESS. Copyright (C) 1986 Free Software Foundation, Inc. This file is part of CHESS. CHESS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY. No author or distributor accepts responsibility to anyone for the consequences of using it or for whether it serves any particular purpose or works at all, unless he says so in writing. Refer to the CHESS General Public License for full details. Everyone is granted permission to copy, modify and redistribute CHESS, but only under the conditions described in the CHESS General Public License. A copy of this license is supposed to have been given to you along with CHESS so you can know your rights and responsibilities. It should be in a file named COPYING. Among other things, the copyright notice and this notice must be preserved on all copies. */ #include <stdio.h> #include <ctype.h> #include <sys/types.h> #include <sys/time.h> #include <sys/resource.h> #include <sys/file.h> #include "gnuchess.h" #define VERSION "GNU Chess 11.26.86\n\ Copyright (C) 1986 Stuart Cracraft/Free Software Foundation, Inc.\n" #define FSIZE 120 #define MAXTESTBD 10 #define fast_eval ((bd[TOMOVE].moved == WHITE) ? bd[WMAT].moved - bd[BMAT].moved : bd[BMAT].moved - bd[WMAT].moved) FILE *hisf = NULL; char *fgets(); /* * First 10 positions from Bratko/Kopec, "A Test for Comparison of * Human and Computer Performance in Chess", Advances in Computer Chess 3, * Pergamon Press, 1982 * These positions are used by the test-moves and test-search commands * for testing purposes. */ char *testbds[MAXTESTBD] = { "1k1r4pp1b1R23q2pp4p32B54Q3PPP2B22K5-", "3r1k24npp11ppr3pp6PP2PPPP11NR55K22R5+", "2q1rr1k3bbnnpp2p1pp12pPp3PpP1P1P11P2BNNP2BQ1PRK7R-", "rnbqkb1rp3pppp1p62ppP33N42P5PPP1QPPPR1B1KB1R+", "r1b2rk12q1b1ppp2ppn21p63QP31BN1B3PPP3PPR4RK1+", "2r3k1pppR1pp14p34P1P15P21P4K1P1P58+", "1nk1r1r1pp2n1pp4p3q2pPp1Nb1pP1P2B1P2R22P1B1PPR2Q2K1+", "4b3p3kp26p13pP2p2pP1P24K1P1P3N2P8+", "2kr1bnrpbpq42n1pp23p3p3P1P1B2N2N1QPPP3PP2KR1B1R+", "3rr1k1pp3pp11qn2np183p4PP1R1P22P1NQPPR1B3K1-"}; typedef struct { char *dptr; int dsize; } datum; datum fetch(); int gentype = MAILBOX, neither = FALSE; #ifdef PARALLEL int parallel = TRUE; #endif PARALLEL extern int iv; extern int compare(),sorttype,myprocid; extern long hashval; extern struct timeval timcpu; extern struct rusage rubuf; struct mvlist scoredmvs[MAXMOVES]; char forsythe[80],bkmove[10]; int gotbook; long random(); datum key,posp; int moveinbook[MAXMOVES],mbi; int pcval[MAXPC+1] = {0, 100, 325, 350, 500, 900, 5000}; struct bdtype bd[120] = { OFF,9050,OFF,9050,OFF,WHITE,OFF,0,OFF,0,OFF,95,OFF,25,OFF,0,OFF,0,OFF,0, OFF,0,OFF,0,OFF,0,OFF,0,OFF,0,OFF,0,OFF,0,OFF,0,OFF,0,OFF,0, OFF,0,BR, 0,BN, 0,BB, 0,BQ, 0,BK, 0,BB, 0,BN, 0,BR, 0,OFF,0, OFF,0,BP, 0,BP, 0,BP, 0,BP, 0,BP, 0,BP, 0,BP, 0,BP, 0,OFF,0, OFF,0,EMP,0,EMP,0,EMP,0,EMP,0,EMP,0,EMP,0,EMP,0,EMP,0,OFF,0, OFF,0,EMP,0,EMP,0,EMP,0,EMP,0,EMP,0,EMP,0,EMP,0,EMP,0,OFF,0, OFF,0,EMP,0,EMP,0,EMP,0,EMP,0,EMP,0,EMP,0,EMP,0,EMP,0,OFF,0, OFF,0,EMP,0,EMP,0,EMP,0,EMP,0,EMP,0,EMP,0,EMP,0,EMP,0,OFF,0, OFF,0,WP, 0,WP, 0,WP, 0,WP, 0,WP ,0,WP, 0,WP, 0,WP, 0,OFF,0, OFF,0,WR, 0,WN, 0,WB, 0,WQ, 0,WK, 0,WB, 0,WN, 0,WR, 0,OFF,0, OFF,0,OFF,0,OFF,0,OFF,0,OFF,0,OFF,0,OFF,0,OFF,0,OFF,0,OFF,0, OFF,0,OFF,0,OFF,0,OFF,0,OFF,0,OFF,0,OFF,0,OFF,0,OFF,0,OFF,0}; struct bdtype startbd[120]; struct dirtypes pieces[MAXPC+6] = { 2, FALSE, -9, -11, 0, 0, 0, 0, 0, 0, /* black pawns */ 2, FALSE, 9, 11, 0, 0, 0, 0, 0, 0, /* white pawns */ 8, FALSE, -19, -21, -8, -12, 12, 8, 21, 19, /* knights */ 4, TRUE, -11, -9, 9, 11, 0, 0, 0, 0, /* bishops */ 4, TRUE, -10, -1, 1, 10, 0, 0, 0, 0, /* rooks */ 8, TRUE, -11, -9, 9, 11, -10, -1, 1, 10, /* queens */ 8, FALSE, -11, -9, 9, 11, -10, -1, 1, 10}; /* kings */ struct mvlist moves[MAXMOVES]; struct gmlist history[MAXGAME]; struct mvlist stack[MAXSTACK]; int nmoves = 0, nmovessco = 0, compat = 1, /* 1 => turn on display-handling */ cnt = 1, /* 0 => otherwise don't */ histtot, /* Total history of game */ stacktot = -1, fnodestot = 0, snodestot = 0, treenodes = 0, termnodes = 0, bestmove = 0, bestscore = 0, bestfrom = 0, bestto = 0, maxdepth = 0; char *histmp = "GAMES/chXXXXXX"; long random(); /* * Zero_history wipes out all history. */ zero_history() { int i; for (i = 0; i < MAXGAME; i++) history[i].depth = -1; } /* * read_history attempts to read a history file. */ read_history() { int index, ply, scor, rate; long node; float cpu; char wmove[10],bmove[10],sqr[5]; FILE *fp; char filename[MAXSTR]; index = 0; printf("Name of history file? "); if (scanf("%s",filename) != EOF) { if ((fp = fopen(filename,"r")) == NULL) { printf("Sorry, cannot open %s\n",filename); return; } if (fscanf(fp," White Black Depth Nodes Score Cpu Rate") == EOF) { printf("Bad history file %s. No game restored.\n",filename); return; } histtot = 0; while (fscanf(fp,"%d. %s %s %d %d %d %f %d", &index,wmove,bmove,&ply,&node,&scor,&cpu,&rate) != EOF) { index--; history[index].depth = ply; history[index].nodes = node; history[index].score = scor; history[index].cpu = cpu; history[index].rate = rate; history[index].wmove.flags = 0; history[index].bmove.flags = 0; sqr[0] = wmove[0]; sqr[1] = wmove[1]; sqr[2] = NULL; history[index].wmove.from = alg_to_lin(sqr); sqr[0] = wmove[2]; sqr[1] = wmove[3]; sqr[2] = NULL; history[index].wmove.to = alg_to_lin(sqr); history[index].wmove.movpiece = bd[history[index].wmove.from].piece; history[index].wmove.cappiece = bd[history[index].wmove.to].piece; if (history[index].wmove.movpiece == WK) if (history[index].wmove.to == 97 && history[index].wmove.from == 95) history[index].wmove.flags |= KCASFLAG; else if (history[index].wmove.to == 93 && history[index].wmove.from == 95) history[index].wmove.flags |= QCASFLAG; makemove(history[index].wmove,bd); sqr[0] = bmove[0]; sqr[1] = bmove[1]; sqr[2] = NULL; history[index].bmove.from = alg_to_lin(sqr); sqr[0] = bmove[2]; sqr[1] = bmove[3]; sqr[2] = NULL; history[index].bmove.to = alg_to_lin(sqr); history[index].bmove.movpiece = bd[history[index].bmove.from].piece; history[index].bmove.cappiece = bd[history[index].bmove.to].piece; if (history[index].bmove.movpiece == BK) if (history[index].bmove.to == 27 && history[index].bmove.from == 25) history[index].bmove.flags |= KCASFLAG; else if (history[index].bmove.to == 23 && history[index].bmove.from == 25) history[index].bmove.flags |= QCASFLAG; makemove(history[index].bmove,bd); histtot++; } if (index > 0) printf("Game of %d moves retrieved\n",index+1); else printf("Sorry, that is an empty game file\n"); fclose(fp); } else printf("No file entered.\n"); } /* * Write out a history file. */ write_history() { int i,dstat,nzero; long nstat; float cstat; nzero = dstat = nstat = 0; cstat = 0.0; unlink(histmp); mktemp(histmp); unlink(histmp); hisf = fopen(histmp,"w"); if (hisf == NULL) { fprintf(stderr, "cannot open history temp file %s\n",histmp); return; } fprintf(hisf," White Black Depth Nodes Score Cpu Rate\n"); for (i = 1; i <= histtot; i++) if (history[i].depth >= 0) { fprintf(hisf,"%d. ",i); lin_to_alg(history[i].wmove.from,hisf); lin_to_alg(history[i].wmove.to,hisf); fprintf(hisf," "); if (history[i].bmove.from != NULL) { lin_to_alg(history[i].bmove.from,hisf); lin_to_alg(history[i].bmove.to,hisf); } if (history[i].nodes > 0) { dstat += history[i].depth; nstat += history[i].nodes; cstat += history[i].cpu; } else nzero++; if (history[i].depth > 0) fprintf(hisf,"\t %2d %6d %6d %6.2f %.0f\n", history[i].depth, history[i].nodes, history[i].score, (history[i].cpu < 0) ? 0.0 : history[i].cpu, (history[i].nodes > 0) ? history[i].rate : 0); } else break; if (histtot - nzero > 0) fprintf(hisf,"Averages: %5.2f ply, %.0f nodes, %5.2f cpu, %.0f nodes/sec\n", (float)dstat / (float)((histtot) - nzero), (float)nstat / (float)((histtot) - nzero), (float)cstat / (float)((histtot) - nzero), (float)(nstat / (float)((histtot) - nzero)) / (float) (cstat / (float)((histtot) - nzero))); fclose(hisf); } /* * Print a history of the current game on the terminal. */ list_history() { int i,dstat,nzero; long nstat; float cstat; nzero = dstat = nstat = 0; cstat = 0.0; printf(" White Black Depth Nodes Score Cpu Rate\n"); for (i = 1; i <= histtot; i++) { if (history[i].depth >= 0) { printf("%d. ",i); putchar(' '); lin_to_alg(history[i].wmove.from,stdout); lin_to_alg(history[i].wmove.to,stdout); putchar(' '); if (history[i].bmove.from != NULL) { lin_to_alg(history[i].bmove.from,stdout); lin_to_alg(history[i].bmove.to,stdout); } if (history[i].nodes > 0) { dstat += history[i].depth; nstat += history[i].nodes; cstat += history[i].cpu; } else nzero++; printf("\t %2d %6d %6d %6.2f %.0f\n", history[i].depth, history[i].nodes, history[i].score, (history[i].cpu < 0) ? 0.0 : history[i].cpu, (history[i].nodes > 0) ? history[i].rate : 0); } else break; } if (histtot - nzero > 0) { /* printf("histtot = %d, nzero = %d\n", histtot, nzero); */ printf("Averages: %5.2f ply, %.0f nodes, %5.2f cpu, %.0f nodes/sec\n", (float)dstat / (float)((histtot) - nzero), (float)nstat / (float)((histtot) - nzero), (float)cstat / (float)((histtot) - nzero), (float)(nstat / (float)((histtot) - nzero)) / (float) (cstat / (float)((histtot) - nzero))); } } testmoves() { int i,j; float tottim = 0.0,timused; printf("1000 move generations): "); fflush(stdout); timeon(); for (i = 0; i < 1000; i++) generate(bd,moves); timeoff(); timused = (float)timcpu.tv_sec+((float)timcpu.tv_usec/1000000.); printf("%.2f gens/sec\n",1000/timused); for (i = 0; i < MAXTESTBD; i++) { termnodes = treenodes = 0; clear_bd(bd); iboard(bd,testbds[i]); timeon(); printf("Bd %d. ",i); fflush(stdout); for (j = 0; j < 500; j++) generate(bd,moves); bd[TOMOVE].moved == OPPCOLOR(bd[TOMOVE].moved); for (j = 0; j < 500; j++) generate(bd,moves); timeoff(); bd[TOMOVE].moved == OPPCOLOR(bd[TOMOVE].moved); timused = (float)timcpu.tv_sec+ ((float)timcpu.tv_usec/1000000.); tottim += 1000/timused; printf("generate rate = %.2f gens/sec\n",1000/timused); fflush(stdout); } printf("Average for all positions: %.2f\n",tottim/MAXTESTBD); fflush(stdout); } testsearch() { int i,j,width; float timused; for (i = 0; i < MAXTESTBD; i++) { termnodes = treenodes = 0; clear_bd(bd); iboard(bd,testbds[i]); #ifdef TRANSP init_hash(); clear_hash(); #endif TRANSP timeon(); bestscore = search(bd,MININT,MAXINT,maxdepth); timeoff(); width = pps(bd,moves); sorttype = SCORESORT; qsort(moves,width,sizeof (struct mvlist), compare); printf("%d. My move: ",i+1,maxdepth); lin_to_alg(bestfrom,stdout); lin_to_alg(bestto,stdout); timused = (float)timcpu.tv_sec+ ((float)timcpu.tv_usec/1000000.); printf(" Nodes = %d/%d Score = %d Time = %.2f Rate = %.2f\n", treenodes,termnodes,bestscore,timused,termnodes/timused); bestmove = searchlist(bestfrom,bestto,moves,width); makemove(moves[bestmove],bd); } } help() { printf("Legal commands are:\n"); printf("A move such as: e2e4, g8f6, e1g1, etc.\n"); printf("attack\t\t- determine if square is attacked by color\n"); printf("bd\t\t- print regular board\n"); printf("book\t\t- compile book into binary format\n"); printf("cbd\t\t- print move count board\n"); printf("depth\t\t- set depth of search\n"); printf("enter\t\t- enter book played thus far into book\n"); printf("first\t\t- computer should play white\n"); printf("fill\t\t- fill board with new position\n"); printf("history\t\t- print history of game\n"); printf("historyf\t- print history of game to temp file\n"); printf("legals\t\t- show legal moves for side to move\n"); printf("neither\t\t- play neither side\n"); printf("quit\t\t- exit program\n"); printf("read\t\t- read a history file\n"); printf("reset\t\t- set board to starting position\n"); printf("score\t\t- statically evaluate current position\n"); printf("self\t\t- play self\n"); printf("static\t\t- show static exchange on a square\n"); printf("switch\t\t- force computer to move\n"); printf("test-moves\t- test move generator\n"); printf("test-search\t- test search\n"); printf("undo\t\t- retract last move\n"); } main(argc,argv) int argc; char *argv[]; { register i,j,movei; int x; char bookfl1[80],bookfl2[80]; char obd[MAXSTR],stdptr[MAXSTR]; long mover; float timused; int index,score,depth,width,prevscore = 0,self = FALSE,seval,feval, toteval,totmoves,tempint,nsame,fd1,fd2; char cmd[20],frsq[3],tosq[3],tempstr[10];; init_rands(); /* Initialize random numbers */ init_hash(bd); /* And hash table */ strcpy(bookfl1,BOOKOBJ); /* Figure out names of opening book database */ strcat(bookfl1,".dir"); strcpy(bookfl2,BOOKOBJ); strcat(bookfl2,".pag"); gotbook = FALSE; if (access(bookfl1,F_OK) >= 0 && access(bookfl2,F_OK) >= 0) /* Exist? */ { dbminit(BOOKOBJ); /* Yes, open it */ gotbook = TRUE; } else { /* Non-existant, create them */ close(creat(bookfl1,0600)); close(creat(bookfl2,0600)); } #ifdef TRANSP clear_hash(); #endif zero_history(); histtot = 0; nmoves = 0; #ifdef TABLEGEN copybd(bd,startbd); fillpctab(startbd); fillpwntab(startbd); listtabs(); /* List move-gen tables */ #endif maxdepth = DEPTH; #ifdef PARALLEL if (argc > 1) /* Is this a parallel-processor process? */ { /* must be invoked via "gnuchess -p <input-board> depth index len host" */ myprocid = atoi(argv[2]); printf("processor %d starting...\n",myprocid); fflush(stdout); do_parallel(); exit(); /* width = pps(bd,moves); if (width > 1) { maxdepth = atoi(argv[3]); clear_bd(bd); iboard(bd,argv[2]); single_parallel(bd,atoi(argv[3]),atoi(argv[4]),atoi(argv[5]), argv[6]); exit(); } */ } else { #endif PARALLEL while (argc > 1 && argv[1][0] == '-') { if (isdigit(argv[1][1])) maxdepth = argv[1][1] - '0'; else compat = 0; argv++; argc--; } #ifdef PARALLEL } #endif PARALLEL if (compat) { printf("Chess\n"); setlinebuf(stdout); } else printf(VERSION); depth = maxdepth; copybd(bd,startbd); for (;;) { if (self == FALSE) { if (!compat) putchar('_'); if (scanf("%s",cmd) == EOF) strcpy(cmd,"quit"); } else cmd[0] = NULL; if (strcmp(cmd,"bd") == 0) pboard(bd,FALSE); else if (strcmp(cmd,"cbd") == 0) { printf("Command has been disabled.\n"); pboard(bd,TRUE); } else if (strcmp(cmd,"book") == 0) { unlink(bookfl1); /* Get rid of stray book */ unlink(bookfl2); fd1 = open(bookfl1,O_CREAT,0666); /* Create empty new book */ fd2 = open(bookfl2,O_CREAT,0666); close(fd1); close(fd2); book(); /* Do the actual creation of book */ init_rands(); /* Create random numbers */ init_hash(bd); /* Initialize hash values */ dbminit(BOOKOBJ); /* Initialize and open our new book */ } else if (strcmp(cmd,"enter") == 0) /* Enter current game in book */ { write_book(); } else if (strcmp(cmd,"test-moves") == 0) testmoves(); else if (strcmp(cmd,"?") == 0) help(); else if (strcmp(cmd,"test-search") == 0) testsearch(); else if (strcmp(cmd,"legals") == 0) { printf("side? "); scanf("%s",tempstr); tempint = bd[TOMOVE].moved; bd[TOMOVE].moved = ((strcmp(tempstr,"white") == 0) ? WHITE : BLACK); width = pps(bd,moves); /* sorttype = SCORESORT; qsort(moves,width,sizeof (struct mvlist), compare); */ listmoves(moves,width); bd[TOMOVE].moved = tempint; } else if (strcmp(cmd,"read") == 0) { read_history(); } else if (strcmp(cmd,"reset") == 0) { iv = 0; /* Initial value for aspiration */ for (i = 0; i < 120; i++) { bd[i].piece = startbd[i].piece; bd[i].moved = startbd[i].moved; } #ifdef TRANSP init_hash(); clear_hash(); #endif histtot = 0; nmoves = 0; } else if (strcmp(cmd,"static") == 0) { printf("sq? "); fflush(stdout); scanf("%d",&tempint); if (tempint != 0) { showstatic(bd,tempint); printf("total static for board = %d\n",modmat(bd)); } else printf("%d\n",modmat(bd)); } else if (strcmp(cmd,"attack") == 0) { printf("sq attacked by color? "); fflush(stdout); scanf("%d %s",&tempint,tempstr); if (sqattacked(bd,tempint,(strcmp(tempstr,"white") == 0) ? WHITE : BLACK)) printf("Yes. Square %d is attacked by %s\n",tempint,tempstr); else printf("No. Square %d is not attacked by %s\n",tempint,tempstr); showattacks(bd,tempint); } else if (strcmp(cmd,"depth") == 0) { printf("depth (non-zero positive integer)? "); fflush(stdout); scanf("%d",&tempint); depth = maxdepth = tempint; } else if (strcmp(cmd,"fill") == 0) { clear_bd(bd); printf("Please input board in Forsythe notation.\n"); printf("Terminate with return.\n"); printf("Initial setup is rnbqkbnrpppppppp8888PPPPPPPPRNBQKBNR+\n"); fflush(stdout); scanf("%s",forsythe); iboard(bd,forsythe); #ifdef TRANSP init_hash(); clear_hash(); #endif printf("WMAT = %d, BMAT = %d\n", bd[WMAT].moved,bd[BMAT].moved); } else if (strcmp(cmd,"history") == 0) list_history(); else if (strcmp(cmd,"historyf") == 0) write_history(); else if (strcmp(cmd,"list-hash") == 0) #ifdef TRANSP list_hash(); #else printf("Hash table not installed presently.\n"); #endif else if (strcmp(cmd,"quit") == 0) { /* dbmclose(); */ #ifdef PARALLEL if (parallel) quit_parallel(); #endif PARALLEL break; } else if (strcmp(cmd,"increm") == 0) { printf("Command has been disabled.\n"); /* increm(bd,maxdepth); */ } #ifdef PARALLEL else if (strcmp(cmd,"parallel") == 0) { if (!parallel) { printf("enabling parallelism...\n"); list_parallel(); make_data(); start_parallel(); parallel = TRUE; myprocid = 2; } else { printf("disabling parallelism...\n"); parallel = FALSE; } } #endif PARALLEL else if (strcmp(cmd,"score") == 0) { feval = fast_eval; printf("Evaluation is from point of view of player to move.\n"); printf("material = %d",feval); } else if (strcmp(cmd,"undo") == 0) movem(moves,cmd,TRUE,bd); else if (strcmp(cmd,"remove") == 0) { movem(moves,cmd,TRUE,bd); movem(moves,cmd,TRUE,bd); } else if (strcmp(cmd,"self") == 0) self = TRUE; else if (strcmp(cmd,"neither") == 0) neither = TRUE; else if (((strlen(cmd) == 4) && isalpha(cmd[0]) && isdigit(cmd[1]) && isalpha(cmd[2]) && isdigit(cmd[3])) || (strcmp(cmd,"switch") == 0) || ((strcmp(cmd,"first") == 0) && histtot == 0) || self) { termnodes = treenodes = 0; if (strcmp(cmd,"switch") == 0 || strcmp(cmd,"first") == 0) { neither = FALSE; } if (self || (strcmp(cmd,"switch")==0) || ((strcmp(cmd,"first") == 0) && histtot == 0) || movem(moves,cmd,FALSE,bd)) { write_history(); nmovessco = 0; if (!neither) { if (compat && strcmp(cmd,"first") != 0) { if (bd[TOMOVE].moved == BLACK) printf("%d. %s\n", histtot, cmd); else { printf("%d. ... %s\n", histtot,cmd); } } #ifdef TRANSP clear_hash(); #endif width = pps(bd,moves); /* sorttype = SCORESORT; qsort(moves,width,sizeof (struct mvlist), compare); */ /* uncomment this only if we want to see output of pps before each search listmoves(moves,width); */ if (width > 1) /* Regular move */ { timeon(); /* Randomize across opening moves, otherwise pick first variation */ #ifdef RANDOM mbi = 0; if (gotbook) { for (movei = 0; movei < width; movei++) { makemove(moves[movei],bd); key.dptr = (char *)&hashval; key.dsize = 4; posp = fetch(key); /* match all moves that have the same position as well as * the correct side on move */ /* strcpy(stdptr,posp.dptr); printf("stdptr = %s\n",stdptr); fflush(stdout); if (rindex(posp.dptr,"+")) printf("White move\n"); else printf("Black move\n"); fflush(stdout); */ if (posp.dptr != NULL) /* && ((stdptr[strlen(stdptr)-1] == '+') && bd[TOMOVE].moved == WHITE) || ((stdptr[strlen(stdptr)-1] == '-') && bd[TOMOVE].moved == BLACK)) */ { /* printf("Move %d(%s)[%ld] in book: ",movei, posp.dptr,hashval); lin_to_alg(moves[movei].from,stdout); lin_to_alg(moves[movei].to,stdout); putchar('\n'); */ moveinbook[mbi++] = movei; } unmakemove(moves[movei],bd); } moveinbook[mbi] = -1; /* printf("A total of %d book moves available!\n", mbi); */ if (mbi > 0) { /* printf("Book moves are available\n"); for (mbi = 0; moveinbook[mbi] != -1; mbi++) { lin_to_alg(moves[moveinbook[mbi]].from,stdout); lin_to_alg(moves[moveinbook[mbi]].to,stdout); putchar(' '); } */ srandom(getpid()+(int)time(0)); mover = random()%mbi; bestmove = moveinbook[mover]; bestfrom = moves[bestmove].from; bestto = moves[bestmove].to; /* putchar('\n'); */ } #ifdef PARALLEL else if (!parallel) #else else #endif PARALLEL bestscore = aspiration(bd,MININT,MAXINT,depth); /* bestscore = search(bd,MININT,MAXINT,depth); */ #ifdef PARALLEL else bestscore = multiple_parallel(bd,depth); #endif PARALLEL #else key.dptr = (char *)&hashval; key.dsize = 4; posp = fetch(key); if (posp.dptr == NULL) /* Not in book */ /* bestscore = search(bd,MININT,MAXINT,depth); */ bestscore = aspiration(bd,MININT,MAXINT,depth); else if (posp.dptr != NULL) /* in book */ { /* printf("Position in book!\n"); */ bestmove = searchlist(((10-(posp.dptr[1]- '0'))*10)+posp.dptr[0]-'a'+1, ((10-(posp.dptr[3]-'0'))*10)+posp.dptr[2]- 'a'+1, moves,width); } #endif RANDOM } else { #ifdef PARALLEL if (!parallel) #endif PARALLEL bestscore = aspiration(bd,MININT,MAXINT,depth); /* bestscore = search(bd,MININT,MAXINT,depth); */ #ifdef PARALLEL else bestscore = multiple_parallel(bd,depth); #endif PARALLEL } timeoff(); } else if (width == 1) /* Only one legal move */ { bestmove = 0; bestfrom = moves[bestmove].from; bestto = moves[bestmove].to; } else if (width == 0) /* Checkmate/Stalemate */ { if (sqattacked(bd,locate_king(bd), OPPCOLOR(bd[TOMOVE].moved))) printf("%s wins\n",bd[TOMOVE].moved == WHITE ? "Black" : "White"); else printf("Stale mate\n"); continue; } width = pps(bd,moves); /* sorttype = SCORESORT; qsort(moves,width,sizeof (struct mvlist), compare); */ if (!compat) printf("My move: "); else if (bd[TOMOVE].moved == BLACK) printf("%d. ... ", histtot); else if (bd[TOMOVE].moved == WHITE) printf("%d. ",histtot); bestmove = searchlist(bestfrom,bestto,moves,width); lin_to_alg(moves[bestmove].from,stdout); lin_to_alg(moves[bestmove].to,stdout); putchar('\n'); /* printf("Principal variation: "); listpv(); */ timused = (float)timcpu.tv_sec+ ((float)timcpu.tv_usec/1000000.); if (!compat) printf("Depth = %d, Nodes = %d/%d, Score = %d, Time = %.2f, Rate = %.2f\n", depth,treenodes,termnodes,bestscore,timused,termnodes/timused); recordmove(moves[bestmove],depth,termnodes,bestscore, timused,termnodes/timused, bd[TOMOVE].moved == WHITE); makemove(moves[bestmove],bd); write_history(); } } } #ifdef XWINDOW else fprintf(stderr, "Illegal command\n"); #endif XWINDOW } }