home *** CD-ROM | disk | FTP | other *** search
/ Education Sampler 1992 [NeXTSTEP] / Education_1992_Sampler.iso / NeXT / GnuSource / Chess-9 / gnuglue.m < prev    next >
Text File  |  1992-03-07  |  13KB  |  582 lines

  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #include <sys/param.h>
  4. #include <sys/times.h>
  5. #include <sys/file.h>
  6. #include <pwd.h>
  7.  
  8.  
  9. #import <appkit/appkit.h>
  10.  
  11. #import "chess_strings.h"
  12. #import "Chess.h"
  13. #import "gnuchess.h"
  14. #import "gnuglue.h"
  15. #import "Clock.h"
  16. #import "gnuchess.h"
  17. #import "Board.h"
  18. #import "ResponseMeter.h"
  19.  
  20. #define LEFT_CASTLE   0x1
  21. #define RIGHT_CASTLE  0x2
  22.  
  23. extern short GameQueens[240];
  24. extern short PieceList[2][16];
  25. extern short PieceCnt[2];
  26. extern algbr();
  27. extern castle();
  28. /* extern getsectdata(); */
  29. extern distance();
  30. extern InitializeStats();
  31. extern SqAtakd();
  32.  
  33. struct tms tmbuf1,tmbuf2;
  34.  
  35. OutputMove()
  36. {
  37.   int i, r1, c1, r2, c2, castle_flag;
  38. #ifdef NeXT_DEBUG
  39.   printf( "OutputMove:  " );
  40.   printf( "Computer move is %s, ", mvstr1 );
  41.   printf( "mask 0x%04x\n", root->flags );
  42. #endif
  43.   if( root->flags & draw )
  44.     [NXApp setFinished: DRAW_GAME];
  45.  
  46.   if( [[NXApp clockWindow] isVisible] ){  
  47.     if( player == white )
  48.       [[NXApp whiteMeter] displayFilled];
  49.     else
  50.       [[NXApp blackMeter] displayFilled];
  51.   }
  52.  
  53.   if( !*mvstr1 ){
  54. #ifdef NeXT_DEBUG
  55.     printf( "NO COMPUTER MOVE\n" );
  56. #endif
  57.     return;
  58.   }
  59.   
  60.   convert_algbr( mvstr1, &r1, &c1, &r2, &c2, &castle_flag );
  61.   [[NXApp gameBoard] highlightSquareAt: r1 : c1];
  62.   
  63.   [[NXApp gameBoard] slidePieceFrom: r1 : c1 to: r2 : c2];
  64.   [NXApp storePosition: r2 : c2];
  65.   [[NXApp gameBoard] layoutBoard: board color: color];
  66.   [[NXApp gameBoard] display];
  67.   NXPing();
  68.  
  69.   [[NXApp gameBoard] highlightSquareAt: r2 : c2];
  70.  
  71. #ifdef NeXT_DEBUG
  72.   printf( "White has %d pieces\n", PieceCnt[0] );
  73.   for( i = 0; i <= PieceCnt[0]; i++ )
  74.     printf( "%02d ", board[PieceList[0][i]] );
  75.   printf( "\n" );
  76.   printf( "Black has %d pieces\n", PieceCnt[1] );
  77.   for( i = 0; i <= PieceCnt[1]; i++ )
  78.     printf( "%02d ", board[PieceList[1][i]] );
  79.   printf( "\n" );
  80. #endif    
  81. }
  82.   
  83. SetTimeControl()
  84. {
  85. #ifdef NeXT_DEBUG
  86.   printf( "SetTimeControl\n" );
  87. #endif
  88.   if (TCflag)
  89.     {
  90.       TimeControl.moves[white] = TimeControl.moves[black] = TCmoves;
  91.       TimeControl.clock[white] = TimeControl.clock[black] = 60*(long)TCminutes;
  92.     }
  93.   else
  94.     {
  95.       TimeControl.moves[white] = TimeControl.moves[black] = 0;
  96.       TimeControl.clock[white] = TimeControl.clock[black] = 0;
  97.       Level = 60*(long)TCminutes;
  98.     }
  99.   et = 0;
  100.   ElapsedTime(1);
  101. }
  102.  
  103. SelectLevel()
  104. {
  105. }
  106.  
  107. ElapsedTime( short iop ) 
  108. /* 
  109.    Determine the time that has passed since the search was started. If 
  110.    the elapsed time exceeds the target (ResponseTime+ExtraTime) then set 
  111.    timeout to true which will terminate the search. 
  112. */
  113. {
  114.   NXEvent peek_ev, *get_ev;
  115.   
  116.   et = time((long *)0) - time0;
  117.   if (et < 0)
  118.     et = 0;
  119.   ETnodes += 50;
  120.   if( !iop ){
  121.     if( [[NXApp clockWindow] isVisible] ){
  122.       if( player == white )
  123.     [[NXApp whiteMeter] display];
  124.       else
  125.     [[NXApp blackMeter] display];
  126.       NXPing();
  127.     }
  128.   }
  129. #ifdef TIME_STUFF
  130.   printf( "ResponseTime %d, ExtraTime %d, Sdepth %d, iop %d, et %d, et0 %d\n",
  131.         ResponseTime, ExtraTime, Sdepth, iop, et, et0 );
  132. #endif
  133.   if (et > et0 || iop == 1){
  134.     if (et > ResponseTime+ExtraTime && Sdepth > 1){
  135.       timeout = true;
  136.     }
  137.     et0 = et;
  138.     if (iop == 1){
  139.       time0 = time((long *)0);
  140.       et0 = 0;
  141.     }
  142. #ifdef PROFILE    
  143.     (void) times(&tmbuf2);
  144.     cputimer = 100*(tmbuf2.tms_utime - tmbuf1.tms_utime) / HZ;
  145.     if (cputimer > 0) 
  146.       evrate = (100*NodeCnt)/(cputimer+100*ft);
  147.     else
  148.       evrate = 0;
  149. #endif      
  150.     ETnodes = NodeCnt + 50;
  151.     UpdateClocks();
  152.   }
  153.  
  154.   if( [NXApp peekNextEvent: NX_MOUSEDOWNMASK into: &peek_ev] ){
  155.     get_ev = [NXApp getNextEvent: NX_MOUSEDOWNMASK];
  156.     [NXApp sendEvent: get_ev];
  157. #ifdef NeXT_DEBUG
  158.     printf( "mousedown event, sending to application\n" );
  159. #endif
  160.   }
  161. }
  162.  
  163.  
  164. UpdateClocks()
  165. {
  166. }
  167.   
  168.  
  169. ShowResults( short score, unsigned short bstline[], char ch )
  170. {
  171. #ifdef NeXT_DEBUG
  172.   printf( "ShowResults:  " );
  173.   printf("score = %d",score);
  174.   printf("    %5s\n", mvstr1 );
  175. #endif
  176. }
  177.  
  178.  
  179. GameEnd( short score )
  180. {
  181.   NXBeep();
  182.   if( root->flags & draw ){
  183.     [NXApp setFinished: DRAW_GAME];
  184.   }
  185.   else if( score == 9998 ){
  186.     printf( "score %d, winner %d\n", score, winner );
  187.     [NXApp setFinished: winner == black ? BLACK_MATE : WHITE_MATE];
  188.   }
  189.   else if( score == -9999 ){
  190.     if( bothsides ){
  191.       printf( "score %d, winner %d\n", score, winner );
  192.       if( winner != -1 )
  193.     [NXApp setFinished: winner == white ? WHITE_MATE : BLACK_MATE];
  194.       else
  195.         [NXApp setFinished: WHITE_MATE];
  196.     }
  197.     else
  198.       [NXApp setFinished: OPPONENT_MATE ];
  199.   } 
  200. }
  201.  
  202. ClrScreen()
  203. {
  204. }
  205.  
  206. UpdateDisplay( short f, short t, short flag, short iscastle )
  207. {
  208. #ifdef NeXT_DEBUG
  209.   printf( "Update Display:  from %d, to %d, flag 0x%04x, iscastle %d, InChk %d\n",
  210.      f, t, flag, iscastle, InChk );
  211. #endif
  212.   [[NXApp gameBoard] layoutBoard: board color: color];
  213.   [[NXApp gameBoard] display];
  214. }
  215.  
  216. InCheck()
  217. {
  218.   int incheck = -1;
  219.   
  220.   if( SqAtakd( PieceList[computer][0], opponent ) )
  221.     incheck = computer;
  222.   if( SqAtakd( PieceList[opponent][0], computer ) )
  223.     incheck = opponent;
  224.   if( incheck == black )
  225.     ShowMessage( "Black is in check" );
  226.   else if( incheck == 0 )
  227.     ShowMessage( "White is in check" );
  228. }
  229.     
  230. GetOpenings()
  231.  
  232. /*
  233.    Read in the Opening Book file and parse the algebraic notation for a 
  234.    move into an unsigned integer format indicating the from and to 
  235.    square. Create a linked list of opening lines of play, with 
  236.    entry->next pointing to the next line and entry->move pointing to a 
  237.    chunk of memory containing the moves. More Opening lines of up to 256 
  238.    half moves may be added to gnuchess.book. 
  239. */
  240.  
  241. {
  242.   int c,i,j,side;
  243.   struct BookEntry *entry;
  244.   unsigned short mv,*mp,tmp[100];
  245.   int book_size;
  246.   char *book_data;
  247.   NXStream *book_stream;
  248.   
  249.   
  250.   book_data = (char *)getsectdata( "__BOOK", "gnuchess.book", &book_size);
  251.   if( book_data != NULL ){
  252.     book_stream = NXOpenMemory( book_data, book_size, NX_READONLY );
  253.     Book = NULL;
  254.     i = 0; side = white;
  255.     while((c = parse( book_stream, &mv, side)) >= 0 ){
  256.       if(c == 1){
  257.     tmp[++i] = mv;
  258.     side = otherside[side];
  259.       }
  260.       else if (c == 0 && i > 0){
  261.     entry = (struct BookEntry *)malloc(sizeof(struct BookEntry));
  262.     mp = (unsigned short *)malloc((i+1)*sizeof(unsigned short));
  263.     entry->mv = mp;
  264.     entry->next = Book;
  265.     Book = entry; 
  266.     for (j = 1; j <= i; j++) *(mp++) = tmp[j];
  267.     *mp = 0;
  268.     i = 0; side = white;
  269.       }
  270.     }
  271.     NXCloseMemory( book_stream, NX_SAVEBUFFER );
  272.   }
  273. }
  274.  
  275.  
  276. int 
  277. parse( NXStream *book_stream, unsigned short *mv, short side )
  278. {
  279.   int c,i,r1,r2,c1,c2;
  280.   char s[100];
  281.   
  282.   while ((c = NXGetc( book_stream )) == ' ');
  283.   i = 0; s[0] = c;
  284.   while (c != ' ' && c != '\n' && c != EOF)
  285.     s[++i] = c = NXGetc( book_stream );
  286.   s[++i] = '\0';
  287.   if (c == EOF)
  288.     return(-1);
  289.   if (s[0] == '!' || i < 3){
  290.     while (c != '\n' && c != EOF) c = NXGetc( book_stream );
  291.     return(0);
  292.   }
  293.   if (s[4] == 'o'){
  294.     if (side == black)
  295.       *mv = 0x3C3A;
  296.     else
  297.       *mv = 0x0402;
  298.   }
  299.   else if (s[0] == 'o'){
  300.     if (side == black)
  301.       *mv = 0x3C3E;
  302.     else *mv = 0x0406;
  303.   }
  304.   else{
  305.     c1 = s[0] - 'a'; r1 = s[1] - '1';
  306.     c2 = s[2] - 'a'; r2 = s[3] - '1';
  307.     *mv = (locn[r1][c1]<<8) + locn[r2][c2];
  308.   }
  309.   return(1);
  310. }
  311.  
  312. ShowDepth( char ch )
  313. {
  314. #ifdef NeXT_DEBUG_X
  315.   printf( "ShowDepth:  %d%c   max %d\n", Sdepth, ch, MaxSearchDepth );
  316. #endif
  317. }
  318.  
  319. ShowCurrentMove( short pnt, short f, short t )
  320. {
  321. #ifdef NeXT_DEBUG
  322.   printf( "ShowCurrentMove\n" );
  323.   algbr(f,t,false);
  324.   printf("(%2d) %4s",pnt,mvstr1);
  325. #endif
  326. }
  327.  
  328.  
  329. ShowSidetomove()
  330. {
  331. #ifdef NeXT_DEBUG
  332.   printf( "ShowSidetomove\n" );
  333.   if (player == white) 
  334.     printf("%2d:   WHITE\n",1+(GameCnt+1)/2);
  335.   else 
  336.     printf("%2d:   BLACK\n",1+(GameCnt+1)/2);
  337. #endif
  338. }
  339.  
  340. ShowMessage( char *s )
  341. {
  342. #ifdef NeXT_DEBUG
  343.   printf( "ShowMessage:  %s\n", s );
  344. #endif
  345.   [NXApp setTitleMessage: s];
  346. }
  347.  
  348. void
  349. ExitChess()
  350. {
  351.   [NXApp terminate: NXApp];
  352.   exit(0);
  353. }
  354.  
  355. extern char playing;
  356.  
  357. void
  358. Die()
  359. {
  360.   if( NXRunAlertPanel( 0, "Do you want to exit chess?", "Yes", "No", 0 ) ){
  361.     signal(SIGINT,SIG_IGN);
  362.     signal(SIGQUIT,SIG_IGN);
  363.     ExitChess();
  364.   }
  365. }
  366.  
  367. void
  368. TerminateSearch()
  369. {
  370.   signal(SIGINT,SIG_IGN);
  371.   signal(SIGQUIT,SIG_IGN);
  372.   timeout = true;
  373.   if( bothsides )
  374.     playing = 0;
  375.   signal( SIGINT, Die ); 
  376.   signal( SIGQUIT, Die );
  377. }
  378.  
  379. SearchStartStuff( short side )
  380. {
  381.   signal(SIGINT,TerminateSearch);
  382.   signal(SIGQUIT,TerminateSearch);
  383. }
  384.  
  385. static char convert_buf[8];
  386. char *
  387. convert_rc( int row, int col, int row2, int col2, int type )
  388. {
  389.   
  390.   if( type == king && col == 4){
  391.     if( col2 == 6 ){
  392.       strcpy( convert_buf, "o-o" );
  393.       return( convert_buf );
  394.     }
  395.     else if( col2 == 2 ){
  396.       strcpy( convert_buf, "o-o-o" );
  397.       return( convert_buf );
  398.     }
  399.   }      
  400.  
  401.   convert_buf[0] = 'a' + col;
  402.   convert_buf[1] = '0' + row+1;
  403.   convert_buf[2] = 'a' + col2;
  404.   convert_buf[3] = '0' + row2+1;
  405.   convert_buf[4] = 0;
  406.  
  407.   return( convert_buf );
  408. }
  409.  
  410. convert_algbr(char *algbr, int *r1, int *c1, int *r2, int *c2,int *castle_flag)
  411. {
  412.   int type;
  413.   
  414.   *castle_flag = 0;
  415.   if( strcmp( algbr, "o-o" ) == 0 )
  416.     *castle_flag = RIGHT_CASTLE;
  417.   else if( strcmp( algbr, "o-o-o" ) == 0 )
  418.     *castle_flag = LEFT_CASTLE;
  419.   else{
  420.     *c1 = algbr[0] - 'a';
  421.     *r1 = algbr[1] - '0' - 1;
  422.     *c2 = algbr[2] - 'a';
  423.     *r2 = algbr[3] - '0' - 1;
  424.   }
  425.   type = [[NXApp gameBoard] typeAt: *r1 : *c1];
  426.   if( type ){
  427.  
  428. #ifdef NeXT_DEBUG
  429.     printf( "type: %d\n", type );
  430. #endif
  431.     if( type == king ){
  432.       if( *c1 == 4 && *c2 == 6 )
  433.     *castle_flag = RIGHT_CASTLE;
  434.       else if( *c1 == 4 && *c2 == 2 )
  435.     *castle_flag = LEFT_CASTLE;
  436.     }
  437.   }    
  438.   return;
  439. }
  440.  
  441. GetGame( const char *fname )
  442. {
  443. FILE *fd;
  444. int r, c;
  445. short sq;
  446. unsigned short m;
  447.  
  448.   if ((fd = fopen(fname,"r")) != NULL){
  449.     fscanf(fd,"%hd%hd%hd",&computer,&opponent,&Game50);
  450.     fscanf(fd,"%hd%hd%hd%hd",
  451.        &castld[white],&castld[black],
  452.        &kingmoved[white],&kingmoved[black]);
  453.     fscanf(fd,"%hd%hd",&TCflag,&OperatorTime);
  454.     fscanf(fd,"%ld%ld%hd%hd",
  455.        &TimeControl.clock[white],&TimeControl.clock[black],
  456.        &TimeControl.moves[white],&TimeControl.moves[black]);
  457.     for (sq = 0; sq < 64; sq++){
  458.       fscanf(fd,"%hd",&m);
  459.       board[sq] = (m >> 8);
  460.       color[sq] = (m & 0xFF);
  461.       if(color[sq] == 0) 
  462.     color[sq] = neutral;
  463.       else
  464.     --color[sq];
  465.     }
  466.     [[NXApp gameBoard] layoutBoard: board color: color];
  467.     [[NXApp gameBoard] display];
  468.     GameCnt = -1; c = '?';
  469.     while (c != EOF)
  470.       {
  471.     ++GameCnt;
  472.     c = fscanf(fd,"%hd%hd%hd%ld%hd%hd%hd",&GameList[GameCnt].gmove,
  473.            &GameList[GameCnt].score,&GameList[GameCnt].depth,
  474.            &GameList[GameCnt].nodes,&GameList[GameCnt].time,
  475.            &GameList[GameCnt].piece,&GameList[GameCnt].color);
  476.     if (GameList[GameCnt].color == 0) GameList[GameCnt].color = neutral;
  477.     else --GameList[GameCnt].color;
  478.       }
  479.     GameCnt--;
  480.     if (TimeControl.clock[white] > 0) TCflag = true;
  481.     computer--; opponent--;
  482.   }
  483.   fclose(fd);
  484.   InitializeStats();
  485.   UpdateDisplay(0,0,1,0);
  486.   Sdepth = 0;
  487. }
  488.  
  489.  
  490. SaveGame( const char *fname )
  491. {
  492.   FILE *fd;
  493.   short sq,i,c;
  494.  
  495.   fd = fopen(fname,"w");
  496.   if( !fd )
  497.     return( 0 );
  498.     
  499.   fprintf(fd,"%d %d %d\n",computer+1,opponent+1,Game50);
  500.   fprintf(fd,"%d %d %d %d\n",
  501.           castld[white],castld[black],kingmoved[white],kingmoved[black]);
  502.   fprintf(fd,"%d %d\n",TCflag,OperatorTime);
  503.   fprintf(fd,"%ld %ld %d %d\n",
  504.           TimeControl.clock[white],TimeControl.clock[black],
  505.           TimeControl.moves[white],TimeControl.moves[black]);
  506.   for (sq = 0; sq < 64; sq++)
  507.     {
  508.       if (color[sq] == neutral) c = 0; else c = color[sq]+1;
  509.       fprintf(fd,"%d\n",256*board[sq] + c);
  510.     }
  511.   for (i = 0; i <= GameCnt; i++)
  512.     {
  513.       if (GameList[i].color == neutral) c = 0;
  514.       else c = GameList[i].color + 1;
  515.       fprintf(fd,"%d %d %d %ld %d %d %d\n",
  516.               GameList[i].gmove,GameList[i].score,GameList[i].depth,
  517.               GameList[i].nodes,GameList[i].time,
  518.               GameList[i].piece,c);
  519.     }
  520.   fclose(fd);
  521.   return( 1 );
  522. }
  523.  
  524. ListGame( const char *filename )
  525. {
  526.   FILE *fd;
  527.   short i,f,t;
  528.   
  529.   fd = fopen(filename,"w");
  530.   if( !fd )
  531.     return( 0 );
  532.     
  533.   fprintf(fd,"\n");
  534.   fprintf(fd,"       score  depth  nodes  time         ");
  535.   fprintf(fd,"       score  depth  nodes  time\n");
  536.   for (i = 0; i <= GameCnt; i++){
  537.     f = GameList[i].gmove>>8; t = (GameList[i].gmove & 0xFF);
  538.     algbr(f,t,false);
  539.     if ((i % 2) == 0)
  540.       fprintf(fd,"\n");
  541.     else
  542.       fprintf(fd,"         ");
  543.     fprintf(fd,"%5s  %5d     %2d %6ld %5d",mvstr1,
  544.         GameList[i].score,GameList[i].depth,
  545.         GameList[i].nodes,GameList[i].time);
  546.   }
  547.   fprintf(fd,"\n\n");
  548.   fclose(fd);
  549.   return( 1 );
  550.  
  551.  
  552. Undo()
  553. /*
  554.    Undo the most recent half-move.
  555. */
  556. {
  557. short f,t;
  558.   f = GameList[GameCnt].gmove>>8;
  559.   t = GameList[GameCnt].gmove & 0xFF;
  560.   if (board[t] == king && distance(t,f) > 1) {
  561.     castle(GameList[GameCnt].color,f,t,2);
  562.   } else {
  563.       board[f] = board[t];
  564.       color[f] = color[t];
  565.       board[t] = GameList[GameCnt].piece;
  566.       color[t] = GameList[GameCnt].color;
  567.       if ( GameQueens[GameCnt] ) {
  568.       board[f] = GameQueens[GameCnt];
  569.       }
  570.       if (board[f] == king) --kingmoved[color[f]];
  571.   }
  572.   if (TCflag) ++TimeControl.moves[color[f]];
  573.   GameCnt--; mate = false; Sdepth = 0;
  574.   if ( [NXApp finished] ) {
  575.       [NXApp setFinished: false];
  576.   }
  577.   UpdateDisplay(0,0,1,0);
  578.   InitializeStats();
  579. }
  580.  
  581.