Annotation of 43BSDReno/games/chess/uxdsp.c, revision 1.1.1.1

1.1       root        1: /*
                      2:   ALPHA interface for CHESS
                      3:    
                      4:   Revision: 4-25-88
                      5:    
                      6:   Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc.
                      7:   Copyright (c) 1988  John Stanback
                      8: 
                      9:   This file is part of CHESS.
                     10: 
                     11:   CHESS is distributed in the hope that it will be useful,
                     12:   but WITHOUT ANY WARRANTY.  No author or distributor
                     13:   accepts responsibility to anyone for the consequences of using it
                     14:   or for whether it serves any particular purpose or works at all,
                     15:   unless he says so in writing.  Refer to the CHESS General Public
                     16:   License for full details.
                     17: 
                     18:   Everyone is granted permission to copy, modify and redistribute
                     19:   CHESS, but only under the conditions described in the
                     20:   CHESS General Public License.   A copy of this license is
                     21:   supposed to have been given to you along with CHESS so you
                     22:   can know your rights and responsibilities.  It should be in a
                     23:   file named COPYING.  Among other things, the copyright notice
                     24:   and this notice must be preserved on all copies.
                     25: */
                     26: 
                     27: 
                     28: #include <stdio.h>
                     29: #include <ctype.h>
                     30: #include <sys/param.h>
                     31: #include <sys/times.h>
                     32: #include <sys/file.h>
                     33: #include <curses.h>
                     34: #include <signal.h>
                     35: #include "gnuchess.h"
                     36: #ifdef NEWMOVE
                     37: #include "move.h"
                     38: #endif
                     39: #include "pathnames.h"
                     40: 
                     41: struct tms tmbuf1,tmbuf2;
                     42: int TerminateSearch(),Die();
                     43: 
                     44: #define scanz fflush(stdout),scanw
                     45: #define printz printw
                     46: 
                     47: 
                     48: Initialize()
                     49: {
                     50:   signal(SIGINT,Die); signal(SIGQUIT,Die);
                     51:   initscr();
                     52:   crmode();
                     53: }
                     54: 
                     55: 
                     56: ExitChess()
                     57: {
                     58:   nocrmode();
                     59:   endwin();
                     60:   exit(0);
                     61: }
                     62: 
                     63: 
                     64: Die()
                     65: {
                     66: char s[80];
                     67:   signal(SIGINT,SIG_IGN);
                     68:   signal(SIGQUIT,SIG_IGN);
                     69:   ShowMessage("Abort? ");
                     70:   scanz("%s",s);
                     71:   if (strcmp(s,"yes") == 0) ExitChess();
                     72:   signal(SIGINT,Die); signal(SIGQUIT,Die);
                     73: }
                     74: 
                     75: 
                     76: TerminateSearch()
                     77: {
                     78:   signal(SIGINT,SIG_IGN);
                     79:   signal(SIGQUIT,SIG_IGN);
                     80:   timeout = true;
                     81:   bothsides = false;
                     82:   signal(SIGINT,Die); signal(SIGQUIT,Die);
                     83: }
                     84: 
                     85: 
                     86: InputCommand()
                     87: 
                     88: /*
                     89:    Process the users command. If easy mode is OFF (the computer is 
                     90:    thinking on opponents time) and the program is out of book, then make 
                     91:    the 'hint' move on the board and call SelectMove() to find a response. 
                     92:    The user terminates the search by entering ^C (quit siqnal) before 
                     93:    entering a command. If the opponent does not make the hint move, then 
                     94:    set Sdepth to zero. 
                     95: */
                     96: 
                     97: {
                     98: short ok,i,tmp;
                     99: long cnt,rate,t1,t2;
                    100: unsigned short mv;
                    101: char s[80];
                    102: 
                    103:   ok = quit = false;
                    104:   player = opponent;
                    105:   ShowSidetomove();
                    106:   ft = 0;
                    107:   if (hint > 0 && !easy && Book == NULL)
                    108:     {
                    109:       fflush(stdout);
                    110:       time0 = time((long *)0);
                    111:       algbr(hint>>8,hint & 0xFF,false);
                    112:       strcpy(s,mvstr1);
                    113:       tmp = epsquare;
                    114:       if (VerifyMove(s,1,&mv))
                    115:         {
                    116:           PromptForMove();
                    117:           SelectMove(computer,2);
                    118:           VerifyMove(mvstr1,2,&mv);
                    119:           if (Sdepth > 0) Sdepth--;
                    120:         }
                    121:       ft = time((long *)0) - time0;
                    122:       epsquare = tmp;
                    123:     }
                    124:   
                    125:   signal(SIGINT,Die); signal(SIGQUIT,Die);
                    126:   while (!(ok || quit))
                    127:     {
                    128:       PromptForMove();
                    129:       scanz("%s",s);
                    130:       player = opponent;
                    131:       ok = VerifyMove(s,0,&mv);
                    132:       if (ok && mv != hint)
                    133:         {
                    134:           Sdepth = 0;
                    135:           ft = 0;
                    136:         }
                    137:         
                    138:       if (strcmp(s,"bd") == 0)
                    139:         {
                    140:           ClrScreen();
                    141:           UpdateDisplay(0,0,1,0);
                    142:         }
                    143:       if (strcmp(s,"quit") == 0) quit = true;
                    144:       if (strcmp(s,"post") == 0) post = !post;
                    145:       if (strcmp(s,"edit") == 0) EditBoard();
                    146:       if (strcmp(s,"go") == 0) ok = true;
                    147:       if (strcmp(s,"help") == 0) help();
                    148:       if (strcmp(s,"force") == 0) force = !force;
                    149:       if (strcmp(s,"book") == 0) Book = NULL;
                    150:       if (strcmp(s,"undo") == 0 && GameCnt >= 0) Undo();
                    151:       if (strcmp(s,"new") == 0) NewGame();
                    152:       if (strcmp(s,"list") == 0) ListGame();
                    153:       if (strcmp(s,"level") == 0) SelectLevel();
                    154:       if (strcmp(s,"hash") == 0) hashflag = !hashflag;
                    155:       if (strcmp(s,"beep") == 0) beep = !beep;
                    156:       if (strcmp(s,"Awindow") == 0) ChangeAlphaWindow();
                    157:       if (strcmp(s,"Bwindow") == 0) ChangeBetaWindow();
                    158:       if (strcmp(s,"hint") == 0) GiveHint();
                    159:       if (strcmp(s,"both") == 0)
                    160:         {
                    161:           bothsides = !bothsides;
                    162:           Sdepth = 0;
                    163:           SelectMove(opponent,1);
                    164:           ok = true;
                    165:         }
                    166:       if (strcmp(s,"reverse") == 0)
                    167:         {
                    168:           reverse = !reverse;
                    169:           ClrScreen();
                    170:           UpdateDisplay(0,0,1,0);
                    171:         }
                    172:       if (strcmp(s,"switch") == 0)
                    173:         {
                    174:           computer = otherside[computer];
                    175:           opponent = otherside[opponent];
                    176:           force = false;
                    177:           Sdepth = 0;
                    178:           ok = true;
                    179:         }
                    180:       if (strcmp(s,"white") == 0)  
                    181:         {
                    182:           computer = white; opponent = black;
                    183:           ok = true; force = false;
                    184:           Sdepth = 0;
                    185:         }
                    186:       if (strcmp(s,"black") == 0)
                    187:         {
                    188:           computer = black; opponent = white;
                    189:           ok = true; force = false;
                    190:           Sdepth = 0;
                    191:         }
                    192:       if (strcmp(s,"remove") == 0 && GameCnt >= 1) 
                    193:         {
                    194:           Undo(); Undo();
                    195:         }
                    196:       if (strcmp(s,"get") == 0) GetGame();
                    197:       if (strcmp(s,"save") == 0) SaveGame();
                    198:       if (strcmp(s,"depth") == 0) ChangeSearchDepth();
                    199:       if (strcmp(s,"random") == 0) dither = 6;
                    200:       if (strcmp(s,"easy") == 0) easy = !easy;
                    201:       if (strcmp(s,"contempt") == 0) SetContempt();
                    202:       if (strcmp(s,"xwndw") == 0) ChangeXwindow();
                    203:       if (strcmp(s,"test") == 0)
                    204:         {
                    205:           t1 = time(0);
                    206:           cnt = 0;
                    207:           for (i = 0; i < 10000; i++)
                    208:             {
                    209:               MoveList(opponent,2);
                    210:               cnt += TrPnt[3] - TrPnt[2];
                    211:             }
                    212:           t2 = time(0);
                    213:           rate = cnt / (t2-t1);
                    214:           gotoXY(50,24);
                    215:           printz("cnt= %ld  rate= %ld",cnt,rate);
                    216:           ClrEoln();
                    217:         }
                    218:       if (strcmp(s,"p") == 0) ShowPostnValues();
                    219:       if (strcmp(s,"debug") == 0) DoDebug();
                    220:     }
                    221:     
                    222:   ClearMessage();
                    223:   ElapsedTime(1);
                    224:   if (force)
                    225:     {
                    226:       computer = opponent; opponent = otherside[computer];
                    227:     }
                    228:   (void) times(&tmbuf1);
                    229:   signal(SIGINT,TerminateSearch); signal(SIGQUIT,TerminateSearch);
                    230: }
                    231: 
                    232: 
                    233: EditBoard()
                    234: 
                    235: /* 
                    236:    Set up a board position. Pieces are entered by typing the piece 
                    237:    followed by the location. For example, Nf3 will place a knight on 
                    238:    square f3. 
                    239: */
                    240: 
                    241: {
                    242: short a,r,c,sq;
                    243: char s[80];
                    244: 
                    245:   ClrScreen();
                    246:   UpdateDisplay(0,0,1,0);
                    247:   gotoXY(50,2); printz(".   Exit to main");
                    248:   gotoXY(50,3); printz("#   Clear board");
                    249:   gotoXY(49,5); printz("Enter piece & location: ");
                    250:   a = white;
                    251:   do
                    252:   {
                    253:     gotoXY(73,5); ClrEoln(); scanz("%s",s);
                    254:     if (s[0] == '#')
                    255:       {
                    256:         for (sq = 0; sq < 64; sq++)
                    257:           {
                    258:             board[sq] = no_piece; color[sq] = neutral;
                    259:           }
                    260:         UpdateDisplay(0,0,1,0);
                    261:       }
                    262:     if (s[0] == 'c' || s[0] == 'C') a = otherside[a];
                    263:     c = s[1]-'a'; r = s[2]-'1';
                    264:     if ((c >= 0) && (c < 8) && (r >= 0) && (r < 8))
                    265:       {
                    266:         sq = locn[r][c];
                    267:         color[sq] = a;
                    268:         if (s[0] == 'p') board[sq] = pawn;
                    269:         else if (s[0] == 'n') board[sq] = knight;
                    270:         else if (s[0] == 'b') board[sq] = bishop;
                    271:         else if (s[0] == 'r') board[sq] = rook;
                    272:         else if (s[0] == 'q') board[sq] = queen;
                    273:         else if (s[0] == 'k') board[sq] = king;
                    274:         else { board[sq] = no_piece; color[sq] = neutral; }
                    275:         DrawPiece(sq);
                    276:       }
                    277:   }
                    278:   while (s[0] != '.');
                    279:   if (board[4] != king) kingmoved[white] = 10;
                    280:   if (board[60] != king) kingmoved[black] = 10;
                    281:   GameCnt = -1; Game50 = 0; Sdepth = 0;
                    282:   InitializeStats();
                    283:   ClrScreen();
                    284:   UpdateDisplay(0,0,1,0);
                    285: }
                    286: 
                    287: 
                    288: help()
                    289: {
                    290:   ClrScreen();
                    291:   gotoXY(28,1); printz("CHESS command summary");
                    292:   gotoXY(1,3); printz("g1f3      move from g1 to f3");
                    293:   gotoXY(1,4); printz("nf3       move knight to f3");
                    294:   gotoXY(1,5); printz("o-o       castle king side");
                    295:   gotoXY(1,6); printz("o-o-o     castle queen side");
                    296:   gotoXY(1,7); printz("edit      edit board");
                    297:   gotoXY(1,8); printz("switch    sides with computer");
                    298:   gotoXY(1,9); printz("white     computer plays white");
                    299:   gotoXY(1,10); printz("black     computer plays black");
                    300:   gotoXY(1,11); printz("reverse   board display");
                    301:   gotoXY(1,12); printz("both      computer match");
                    302:   gotoXY(1,13); printz("random    randomize play");
                    303:   gotoXY(1,14); printz("undo      undo last move");
                    304:   gotoXY(42,3); printz("level     change level");
                    305:   gotoXY(42,4); printz("depth     set search depth");
                    306:   gotoXY(42,5); printz("post      principle variation");
                    307:   gotoXY(42,6); printz("hint      suggest a move");
                    308:   gotoXY(42,7); printz("bd        redraw board");
                    309:   gotoXY(42,8); printz("force     enter game moves");
                    310:   gotoXY(42,9); printz("list      game to chess.lst");
                    311:   gotoXY(42,10); printz("save      game to file");
                    312:   gotoXY(42,11); printz("get       game from file");
                    313:   gotoXY(42,12); printz("new       start new game");
                    314:   gotoXY(42,13); printz("quit      exit CHESS");
                    315:   gotoXY(10,21); printz("Computer: ");
                    316:   if (computer == white) printz("WHITE"); else printz("BLACK");
                    317:   gotoXY(10,22); printz("Opponent: ");
                    318:   if (opponent == white) printz("WHITE"); else printz("BLACK");
                    319:   gotoXY(10,23); printz("Level: %ld",Level," sec.");
                    320:   gotoXY(10,24); printz("Easy mode: ");
                    321:   if (easy) printz("ON"); else printz("OFF");
                    322:   gotoXY(40,21); printz("Depth: %d",MaxSearchDepth);
                    323:   gotoXY(40,22); printz("Random: "); 
                    324:   if (dither) printz("ON"); else printz("OFF");
                    325:   gotoXY(40,23); printz("Transposition table: ");
                    326:   if (hashflag) printz("ON"); else printz("OFF");
                    327:   refresh();
                    328:   while (getchar() != 27);
                    329:   ClrScreen();
                    330:   UpdateDisplay(0,0,1,0);
                    331: }
                    332: 
                    333: 
                    334: ShowDepth(ch)
                    335: char ch;
                    336: {
                    337:   gotoXY(50,4); printz("Depth= %d%c ",Sdepth,ch); ClrEoln();
                    338: }
                    339: 
                    340: 
                    341: ShowResults(score,bstline,ch)
                    342: short score;
                    343: unsigned short bstline[];
                    344: char ch;
                    345: {
                    346: short d,e,ply;
                    347:   if (post && player == computer)
                    348:     {
                    349:       e = lpost;
                    350:       gotoXY(50,5); printz("Score= %d",score); ClrEoln();
                    351:       d = 8; gotoXY(50,d); ClrEoln();
                    352:       for (ply = 1; bstline[ply] > 0; ply++)
                    353:         {
                    354:           algbr(bstline[ply] >> 8,bstline[ply] & 0xFF,false);
                    355:           if (ply == 5 || ply == 9 || ply == 13 || ply == 17)
                    356:             {
                    357:               gotoXY(50,++d); ClrEoln();
                    358:             }
                    359:           printz("%5s ",mvstr1);
                    360:         }
                    361:       ClrEoln();
                    362:       lpost = d;
                    363:       while (++d <= e)
                    364:         {
                    365:           gotoXY(50,d); ClrEoln();
                    366:         }
                    367:     }
                    368: }
                    369: 
                    370: 
                    371: SearchStartStuff(side)
                    372: short side;
                    373: {
                    374: short i;
                    375:   signal(SIGINT,TerminateSearch); signal(SIGQUIT,TerminateSearch);
                    376:   if (player == computer)
                    377:     for (i = 5; i < 14; i++)
                    378:       {
                    379:         gotoXY(50,i); ClrEoln();
                    380:       }
                    381: }
                    382: 
                    383: 
                    384: OutputMove()
                    385: {
                    386:   if (root->flags & epmask) UpdateDisplay(0,0,1,0);
                    387:   else UpdateDisplay(root->f,root->t,0,root->flags & cstlmask);
                    388:   gotoXY(50,17); printz("My move is: %s",mvstr1);
                    389:   if (beep) putchar(7);
                    390:   ClrEoln();
                    391:   
                    392:   gotoXY(50,24);
                    393:   if (root->flags & draw) printz("Draw game!");
                    394:   else if (root->score == -9999) printz("opponent mates!");
                    395:   else if (root->score == 9998) printz("computer mates!");
                    396:   else if (root->score < -9000) printz("opponent will soon mate!");
                    397:   else if (root->score > 9000)  printz("computer will soon mate!");
                    398:   ClrEoln();
                    399:   
                    400:   if (post)
                    401:     {
                    402:       gotoXY(50,22); printz("Nodes=   %6ld",NodeCnt); ClrEoln();
                    403:       gotoXY(50,23); printz("Nodes/Sec= %4ld",evrate); ClrEoln();
                    404:     }
                    405: }
                    406: 
                    407: 
                    408: ElapsedTime(iop)
                    409: 
                    410: /* 
                    411:    Determine the time that has passed since the search was started. If 
                    412:    the elapsed time exceeds the target (ResponseTime+ExtraTime) then set 
                    413:    timeout to true which will terminate the search. 
                    414: */
                    415: 
                    416: short iop;
                    417: {
                    418:   et = time((long *)0) - time0;
                    419:   if (et < 0) et = 0;
                    420:   ETnodes += 50;
                    421:   if (et > et0 || iop == 1)
                    422:     {
                    423:       if (et > ResponseTime+ExtraTime && Sdepth > 1) timeout = true;
                    424:       et0 = et;
                    425:       if (iop == 1)
                    426:         {
                    427:           time0 = time((long *)0); et0 = 0;
                    428:         }
                    429:       (void) times(&tmbuf2);
                    430:       cputimer = 100*(tmbuf2.tms_utime - tmbuf1.tms_utime) / HZ;
                    431:       if (cputimer > 0) evrate = (100*NodeCnt)/(cputimer+100*ft);
                    432:       else evrate = 0;
                    433:       ETnodes = NodeCnt + 50;
                    434:       UpdateClocks();
                    435:     }
                    436: }
                    437: 
                    438: 
                    439: UpdateClocks()
                    440: {
                    441: short m,s;
                    442:   m = et/60; s = (et - 60*m);
                    443:   if (TCflag)
                    444:     {
                    445:       m = (TimeControl.clock[player] - et) / 60;
                    446:       s = TimeControl.clock[player] - et - 60*m;
                    447:     }
                    448:   if (m < 0) m = 0;
                    449:   if (s < 0) s = 0;
                    450:   if (player == white)
                    451:     if (reverse) gotoXY(20,2); else gotoXY(20,23);
                    452:   else
                    453:     if (reverse) gotoXY(20,23); else gotoXY(20,2);
                    454:   printz("%d:%2d   ",m,s);
                    455:   if (post)
                    456:     {
                    457:       gotoXY(50,22); printz("Nodes=   %6ld",NodeCnt);
                    458:       gotoXY(50,23); printz("Nodes/Sec= %4ld",evrate);
                    459:     }
                    460:   refresh();
                    461: }
                    462: 
                    463: 
                    464: 
                    465: SetTimeControl()
                    466: {
                    467:   if (TCflag)
                    468:     {
                    469:       TimeControl.moves[white] = TimeControl.moves[black] = TCmoves;
                    470:       TimeControl.clock[white] = TimeControl.clock[black] = 60*(long)TCminutes;
                    471:     }
                    472:   else
                    473:     {
                    474:       TimeControl.moves[white] = TimeControl.moves[black] = 0;
                    475:       TimeControl.clock[white] = TimeControl.clock[black] = 0;
                    476:       Level = 60*(long)TCminutes;
                    477:     }
                    478:   et = 0;
                    479:   ElapsedTime(1);
                    480: }
                    481: 
                    482: 
                    483: gotoXY(x,y)
                    484: short x,y;
                    485: {
                    486:   move(y-1,x-1);
                    487: }
                    488: 
                    489: 
                    490: ClrScreen()
                    491: {
                    492:   clear(); refresh();
                    493: }
                    494: 
                    495: 
                    496: ClrEoln()
                    497: {
                    498:   clrtoeol(); refresh();
                    499: }
                    500: 
                    501: 
                    502: DrawPiece(sq)
                    503: short sq;
                    504: {
                    505: short r,c; char x;
                    506:   if (reverse) r = 7-row[sq]; else r = row[sq];
                    507:   if (reverse) c = 7-column[sq]; else c = column[sq];
                    508:   if (color[sq] == black) x = '*'; else x = ' ';
                    509:   gotoXY(5+5*c,5+2*(7-r)); printz("%c%c ",x,pxx[board[sq]]);
                    510: }
                    511: 
                    512: 
                    513: UpdateDisplay(f,t,flag,iscastle)
                    514: short f,t,flag,iscastle;
                    515: {
                    516: short i,l,z; 
                    517:   if (flag)
                    518:     {
                    519:       gotoXY(56,2); printz("CHESS");
                    520:       i = 3;
                    521:       gotoXY(3,++i);
                    522:       printz("|----|----|----|----|----|----|----|----|");
                    523:       while (i<19)
                    524:         {
                    525:           gotoXY(1,++i);
                    526:           if (reverse) z = (i/2)-1; else z = 10-(i/2);
                    527:           printz("%d |    |    |    |    |    |    |    |    |",z);
                    528:           gotoXY(3,++i);
                    529:           if (i < 19)
                    530:             printz("+----+----+----+----+----+----+----+----+");
                    531:         }
                    532:       printz("|----|----|----|----|----|----|----|----|");
                    533:       gotoXY(3,21);
                    534:       if (reverse) printz("  h    g    f    e    d    c    b    a");
                    535:               else printz("  a    b    c    d    e    f    g    h");
                    536:       if (reverse) gotoXY(5,23); else gotoXY(5,2);
                    537:       if (computer == black) printz("Computer"); else printz("Human   ");
                    538:       if (reverse) gotoXY(5,2); else gotoXY(5,23);
                    539:       if (computer == white) printz("Computer"); else printz("Human   ");
                    540:       for (l = 0; l < 64; l++) DrawPiece(l);
                    541:     }
                    542:   else
                    543:     {
                    544:       DrawPiece(f); DrawPiece(t);
                    545:       if (iscastle)
                    546:         if (t > f)
                    547:           { DrawPiece(f+3); DrawPiece(t-1); }
                    548:         else
                    549:           { DrawPiece(f-4); DrawPiece(t+1); }
                    550:     }
                    551:   refresh();
                    552: }
                    553: 
                    554: 
                    555: GetOpenings()
                    556: 
                    557: /*
                    558:    Read in the Opening Book file and parse the algebraic notation for a 
                    559:    move into an unsigned integer format indicating the from and to 
                    560:    square. Create a linked list of opening lines of play, with 
                    561:    entry->next pointing to the next line and entry->move pointing to a 
                    562:    chunk of memory containing the moves. More Opening lines of up to 256 
                    563:    half moves may be added to gnuchess.book. 
                    564: */
                    565: 
                    566: {
                    567: FILE *fd;
                    568: int c,i,j,side;
                    569: struct BookEntry *entry;
                    570: unsigned short mv,*mp,tmp[100];
                    571: 
                    572:   if ((fd = fopen(_PATH_CHESSBOOK,"r")) != NULL)
                    573:     {
                    574:       Book = NULL;
                    575:       i = 0; side = white;
                    576:       while ((c = parse(fd,&mv,side)) >= 0)
                    577:         if (c == 1)
                    578:           {
                    579:             tmp[++i] = mv;
                    580:             side = otherside[side];
                    581:           }
                    582:         else if (c == 0 && i > 0)
                    583:           {
                    584:             entry = (struct BookEntry *)malloc(sizeof(struct BookEntry));
                    585:             mp = (unsigned short *)malloc((i+1)*sizeof(unsigned short));
                    586:             entry->mv = mp;
                    587:             entry->next = Book;
                    588:             Book = entry; 
                    589:             for (j = 1; j <= i; j++) *(mp++) = tmp[j];
                    590:             *mp = 0;
                    591:             i = 0; side = white;
                    592:           }
                    593:       fclose(fd);
                    594:     }
                    595:     else
                    596:       {
                    597:        fprintf(stderr, "\nchess: can't read %s.\n", _PATH_CHESSBOOK);
                    598:        exit(1);
                    599:       }
                    600: }
                    601: 
                    602: 
                    603: int parse(fd,mv,side)
                    604: FILE *fd;
                    605: unsigned short *mv;
                    606: short side;
                    607: {
                    608: int c,i,r1,r2,c1,c2;
                    609: char s[100];
                    610:   while ((c = getc(fd)) == ' ');
                    611:   i = 0; s[0] = c;
                    612:   while (c != ' ' && c != '\n' && c != EOF) s[++i] = c = getc(fd);
                    613:   s[++i] = '\0';
                    614:   if (c == EOF) return(-1);
                    615:   if (s[0] == '!' || i < 3)
                    616:     {
                    617:       while (c != '\n' && c != EOF) c = getc(fd);
                    618:       return(0);
                    619:     }
                    620:   if (s[4] == 'o')
                    621:     if (side == black) *mv = 0x3C3A; else *mv = 0x0402;
                    622:   else if (s[0] == 'o')
                    623:     if (side == black) *mv = 0x3C3E; else *mv = 0x0406;
                    624:   else
                    625:     {
                    626:       c1 = s[0] - 'a'; r1 = s[1] - '1';
                    627:       c2 = s[2] - 'a'; r2 = s[3] - '1';
                    628:       *mv = (locn[r1][c1]<<8) + locn[r2][c2];
                    629:     }
                    630:   return(1);
                    631: }
                    632: 
                    633: 
                    634: GetGame()
                    635: {
                    636: FILE *fd;
                    637: char fname[40];
                    638: int c;
                    639: short sq;
                    640: unsigned short m;
                    641: 
                    642:   ShowMessage("File name: ");
                    643:   scanz("%s",fname);
                    644:   if (fname[0] == '\0') strcpy(fname,"chess.000");
                    645:   if ((fd = fopen(fname,"r")) != NULL)
                    646:     {
                    647:       fscanf(fd,"%hd%hd%hd",&computer,&opponent,&Game50);
                    648:       fscanf(fd,"%hd%hd%hd%hd",
                    649:              &castld[white],&castld[black],
                    650:              &kingmoved[white],&kingmoved[black]);
                    651:       fscanf(fd,"%hd%hd",&TCflag,&OperatorTime);
                    652:       fscanf(fd,"%ld%ld%hd%hd",
                    653:              &TimeControl.clock[white],&TimeControl.clock[black],
                    654:              &TimeControl.moves[white],&TimeControl.moves[black]);
                    655:       for (sq = 0; sq < 64; sq++)
                    656:         {
                    657:           fscanf(fd,"%hd",&m);
                    658:           board[sq] = (m >> 8); color[sq] = (m & 0xFF);
                    659:           if (color[sq] == 0) color[sq] = neutral; else --color[sq];
                    660:         }
                    661:       GameCnt = -1; c = '?';
                    662:       while (c != EOF)
                    663:         {
                    664:           ++GameCnt;
                    665:           c = fscanf(fd,"%hd%hd%hd%ld%hd%hd%hd",&GameList[GameCnt].gmove,
                    666:                      &GameList[GameCnt].score,&GameList[GameCnt].depth,
                    667:                      &GameList[GameCnt].nodes,&GameList[GameCnt].time,
                    668:                      &GameList[GameCnt].piece,&GameList[GameCnt].color);
                    669:           if (GameList[GameCnt].color == 0) GameList[GameCnt].color = neutral;
                    670:           else --GameList[GameCnt].color;
                    671:         }
                    672:       GameCnt--;
                    673:       if (TimeControl.clock[white] > 0) TCflag = true;
                    674:       computer--; opponent--;
                    675:     }
                    676:   fclose(fd);
                    677:   InitializeStats();
                    678:   UpdateDisplay(0,0,1,0);
                    679:   Sdepth = 0;
                    680: }
                    681: 
                    682: 
                    683: SaveGame()
                    684: {
                    685: FILE *fd;
                    686: char fname[40];
                    687: short sq,i,c;
                    688: 
                    689:   ShowMessage("File name: ");
                    690:   scanz("%s",fname);
                    691:   
                    692:   if (fname[0] == '\0' || access(fname,W_OK) == -1) strcpy(fname,"chess.000");
                    693:   fd = fopen(fname,"w");
                    694:   fprintf(fd,"%d %d %d\n",computer+1,opponent+1,Game50);
                    695:   fprintf(fd,"%d %d %d %d\n",
                    696:           castld[white],castld[black],kingmoved[white],kingmoved[black]);
                    697:   fprintf(fd,"%d %d\n",TCflag,OperatorTime);
                    698:   fprintf(fd,"%ld %ld %d %d\n",
                    699:           TimeControl.clock[white],TimeControl.clock[black],
                    700:           TimeControl.moves[white],TimeControl.moves[black]);
                    701:   for (sq = 0; sq < 64; sq++)
                    702:     {
                    703:       if (color[sq] == neutral) c = 0; else c = color[sq]+1;
                    704:       fprintf(fd,"%d\n",256*board[sq] + c);
                    705:     }
                    706:   for (i = 0; i <= GameCnt; i++)
                    707:     {
                    708:       if (GameList[i].color == neutral) c = 0;
                    709:       else c = GameList[i].color + 1;
                    710:       fprintf(fd,"%d %d %d %ld %d %d %d\n",
                    711:               GameList[i].gmove,GameList[i].score,GameList[i].depth,
                    712:               GameList[i].nodes,GameList[i].time,
                    713:               GameList[i].piece,c);
                    714:     }
                    715:   fclose(fd);
                    716: }
                    717: 
                    718: 
                    719: ListGame()
                    720: {
                    721: FILE *fd;
                    722: short i,f,t;
                    723:   fd = fopen("chess.lst","w");
                    724:   fprintf(fd,"\n");
                    725:   fprintf(fd,"       score  depth  nodes  time         ");
                    726:   fprintf(fd,"       score  depth  nodes  time\n");
                    727:   for (i = 0; i <= GameCnt; i++)
                    728:     {
                    729:       f = GameList[i].gmove>>8; t = (GameList[i].gmove & 0xFF);
                    730:       algbr(f,t,false);
                    731:       if ((i % 2) == 0) fprintf(fd,"\n"); else fprintf(fd,"         ");
                    732:       fprintf(fd,"%5s  %5d     %2d %6ld %5d",mvstr1,
                    733:               GameList[i].score,GameList[i].depth,
                    734:               GameList[i].nodes,GameList[i].time);
                    735:     }
                    736:   fprintf(fd,"\n\n");
                    737:   fclose(fd);
                    738: } 
                    739: 
                    740: 
                    741: Undo()
                    742: 
                    743: /*
                    744:    Undo the most recent half-move.
                    745: */
                    746: 
                    747: {
                    748: short f,t;
                    749:   f = GameList[GameCnt].gmove>>8;
                    750:   t = GameList[GameCnt].gmove & 0xFF;
                    751:   if (board[t] == king && distance(t,f) > 1)
                    752:     castle(GameList[GameCnt].color,f,t,2);
                    753:   else
                    754:     {
                    755:       board[f] = board[t]; color[f] = color[t];
                    756:       board[t] = GameList[GameCnt].piece;
                    757:       color[t] = GameList[GameCnt].color;
                    758:       if (board[f] == king) --kingmoved[color[f]];
                    759:     }
                    760:   if (TCflag) ++TimeControl.moves[color[f]];
                    761:   GameCnt--; mate = false; Sdepth = 0;
                    762:   UpdateDisplay(0,0,1,0);
                    763:   InitializeStats();
                    764: }
                    765: 
                    766: 
                    767: ShowMessage(s)
                    768: char *s;
                    769: {
                    770:   gotoXY(50,24); printz("%s",s); ClrEoln();
                    771: }
                    772: 
                    773: ClearMessage()
                    774: {
                    775:   gotoXY(50,24); ClrEoln();
                    776: }
                    777: 
                    778: ShowSidetomove()
                    779: {
                    780:   gotoXY(50,14);
                    781:   if (player == white) printz("%2d:   WHITE",1+(GameCnt+1)/2);
                    782:   else printz("%2d:   BLACK",1+(GameCnt+1)/2);
                    783:   ClrEoln();
                    784: }
                    785: 
                    786: PromptForMove()
                    787: {
                    788:   gotoXY(50,19); printz("Your move is? "); ClrEoln();
                    789: }
                    790: 
                    791: ShowCurrentMove(pnt,f,t)
                    792: short pnt,f,t;
                    793: {
                    794:   algbr(f,t,false);
                    795:   gotoXY(50,7); printz("(%2d) %4s",pnt,mvstr1);
                    796: }
                    797: 
                    798: ChangeAlphaWindow()
                    799: {
                    800:   ShowMessage("window: ");
                    801:   scanz("%hd",&Awindow);
                    802: }
                    803: 
                    804: ChangeBetaWindow()
                    805: {
                    806:   ShowMessage("window: ");
                    807:   scanz("%hd",&Bwindow);
                    808: }
                    809: 
                    810: GiveHint()
                    811: {
                    812: char s[40];
                    813:   algbr((short)(hint>>8),(short)(hint & 0xFF),false);
                    814:   strcpy(s,"try ");
                    815:   strcat(s,mvstr1);
                    816:   ShowMessage(s);
                    817: }
                    818: 
                    819: ChangeSearchDepth()
                    820: {
                    821:   ShowMessage("depth= ");
                    822:   scanz("%hd",&MaxSearchDepth);
                    823: }
                    824: 
                    825: SetContempt()
                    826: {
                    827:   ShowMessage("contempt= ");
                    828:   scanz("%hd",&contempt);
                    829: }
                    830: 
                    831: ChangeXwindow()
                    832: {
                    833:   ShowMessage("xwndw= ");
                    834:   scanz("%hd",&xwndw);
                    835: }
                    836: 
                    837: 
                    838: SelectLevel()
                    839: {
                    840:   ClrScreen();
                    841:   gotoXY(32,2); printz("CHESS");
                    842:   gotoXY(20,4); printz(" 1.   60 moves in   5 minutes");
                    843:   gotoXY(20,5); printz(" 2.   60 moves in  15 minutes");
                    844:   gotoXY(20,6); printz(" 3.   60 moves in  30 minutes");
                    845:   gotoXY(20,7); printz(" 4.   40 moves in  30 minutes");
                    846:   gotoXY(20,8); printz(" 5.   40 moves in  60 minutes");
                    847:   gotoXY(20,9); printz(" 6.   40 moves in 120 minutes");
                    848:   gotoXY(20,10); printz(" 7.   40 moves in 240 minutes");
                    849:   gotoXY(20,11); printz(" 8.    1 move  in  15 minutes");
                    850:   gotoXY(20,12); printz(" 9.    1 move  in  60 minutes");
                    851:   gotoXY(20,13); printz("10.    1 move  in 600 minutes");
                    852:   
                    853:   OperatorTime = 0; TCmoves = 60; TCminutes = 5;
                    854: 
                    855:   gotoXY(20,17); printz("Enter Level: ");
                    856:   refresh();
                    857:   scanz("%ld",&Level);
                    858:   switch (Level)
                    859:     {
                    860:       case 1 : TCmoves = 60; TCminutes = 5; break;
                    861:       case 2 : TCmoves = 60; TCminutes = 15; break;
                    862:       case 3 : TCmoves = 60; TCminutes = 30; break;
                    863:       case 4 : TCmoves = 40; TCminutes = 30; break;
                    864:       case 5 : TCmoves = 40; TCminutes = 60; break;
                    865:       case 6 : TCmoves = 40; TCminutes = 120; break;
                    866:       case 7 : TCmoves = 40; TCminutes = 240; break;
                    867:       case 8 : TCmoves = 1; TCminutes = 15; break;
                    868:       case 9 : TCmoves = 1; TCminutes = 60; break;
                    869:       case 10 : TCmoves = 1; TCminutes = 600; break;
                    870:     }
                    871: 
                    872:   TCflag = (TCmoves > 1);
                    873:   SetTimeControl();
                    874:   ClrScreen();
                    875:   UpdateDisplay(0,0,1,0);
                    876: }
                    877: 
                    878: 
                    879: ShowPostnValues()
                    880: {
                    881: short i,r,c;
                    882:   ExaminePosition();
                    883:   for (i = 0; i < 64; i++)
                    884:     {
                    885:       if (reverse) r = 7-row[i]; else r = row[i];
                    886:       if (reverse) c = 7-column[i]; else c = column[i];
                    887:       gotoXY(4+5*c,5+2*(7-r));
                    888:       c1 = color[i]; c2 = otherside[c1];
                    889:       PC1 = PawnCnt[c1]; PC2 = PawnCnt[c2];
                    890:       atk1 = atak[c1]; atk2 = atak[c2];
                    891:       if (color[i] == neutral) printz("   ");
                    892:       else printz("%3d ",SqValue(i,opponent));
                    893:     }
                    894:   ScorePosition(opponent,&i);
                    895:   gotoXY(50,24);
                    896:   printz("Score= %d",i); ClrEoln();
                    897: }
                    898: 
                    899: 
                    900: DoDebug()
                    901: {
                    902: short k,p,i,r,c,tp,tc;
                    903: char s[40];
                    904:   ExaminePosition();
                    905:   ShowMessage("Enter piece: ");
                    906:   scanz("%s",s);
                    907:   if (s[0] == 'w') k = white; else k = black;
                    908:   if (s[1] == 'p') p = pawn;
                    909:   else if (s[1] == 'n') p = knight;
                    910:   else if (s[1] == 'b') p = bishop;
                    911:   else if (s[1] == 'r') p = rook;
                    912:   else if (s[1] == 'q') p = queen;
                    913:   else if (s[1] == 'k') p = king;
                    914:   else p = no_piece;
                    915:   for (i = 0; i < 64; i++)
                    916:     {
                    917:       if (reverse) r = 7-row[i]; else r = row[i];
                    918:       if (reverse) c = 7-column[i]; else c = column[i];
                    919:       gotoXY(4+5*c,5+2*(7-r));
                    920:       tp = board[i]; tc = color[i];
                    921:       board[i] = p; color[i] = k;
                    922:       c1 = k; c2 = otherside[c1];
                    923:       PC1 = PawnCnt[c1]; PC2 = PawnCnt[c2];
                    924:       atk1 = atak[c1]; atk2 = atak[c2];
                    925:       printz("%3d ",SqValue(i,opponent));
                    926:       board[i] = tp; color[i] = tc;
                    927:     }
                    928:   ScorePosition(opponent,&i);
                    929:   gotoXY(50,24);
                    930:   printz("Score= %d",i); ClrEoln();
                    931: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.