This is gnuglue.m in view mode; [Download] [Up]
#include <stdio.h> #include <ctype.h> #include <sys/param.h> #include <sys/times.h> #include <sys/file.h> #include <pwd.h> #import <appkit/appkit.h> #import "chess_strings.h" #import "Chess.h" #import "gnuchess.h" #import "gnuglue.h" #import "Clock.h" #import "gnuchess.h" #import "Board.h" #import "ResponseMeter.h" #define LEFT_CASTLE 0x1 #define RIGHT_CASTLE 0x2 extern short GameQueens[240]; extern short PieceList[2][16]; extern short PieceCnt[2]; extern algbr(); extern castle(); /* extern getsectdata(); */ extern distance(); extern InitializeStats(); extern SqAtakd(); struct tms tmbuf1,tmbuf2; OutputMove() { int i, r1, c1, r2, c2, castle_flag; #ifdef NeXT_DEBUG printf( "OutputMove: " ); printf( "Computer move is %s, ", mvstr1 ); printf( "mask 0x%04x\n", root->flags ); #endif if( root->flags & draw ) [NXApp setFinished: DRAW_GAME]; if( [[NXApp clockWindow] isVisible] ){ if( player == white ) [[NXApp whiteMeter] displayFilled]; else [[NXApp blackMeter] displayFilled]; } if( !*mvstr1 ){ #ifdef NeXT_DEBUG printf( "NO COMPUTER MOVE\n" ); #endif return; } convert_algbr( mvstr1, &r1, &c1, &r2, &c2, &castle_flag ); [[NXApp gameBoard] highlightSquareAt: r1 : c1]; [[NXApp gameBoard] slidePieceFrom: r1 : c1 to: r2 : c2]; [NXApp storePosition: r2 : c2]; [[NXApp gameBoard] layoutBoard: board color: color]; [[NXApp gameBoard] display]; NXPing(); [[NXApp gameBoard] highlightSquareAt: r2 : c2]; #ifdef NeXT_DEBUG printf( "White has %d pieces\n", PieceCnt[0] ); for( i = 0; i <= PieceCnt[0]; i++ ) printf( "%02d ", board[PieceList[0][i]] ); printf( "\n" ); printf( "Black has %d pieces\n", PieceCnt[1] ); for( i = 0; i <= PieceCnt[1]; i++ ) printf( "%02d ", board[PieceList[1][i]] ); printf( "\n" ); #endif } SetTimeControl() { #ifdef NeXT_DEBUG printf( "SetTimeControl\n" ); #endif if (TCflag) { TimeControl.moves[white] = TimeControl.moves[black] = TCmoves; TimeControl.clock[white] = TimeControl.clock[black] = 60*(long)TCminutes; } else { TimeControl.moves[white] = TimeControl.moves[black] = 0; TimeControl.clock[white] = TimeControl.clock[black] = 0; Level = 60*(long)TCminutes; } et = 0; ElapsedTime(1); } SelectLevel() { } ElapsedTime( short iop ) /* Determine the time that has passed since the search was started. If the elapsed time exceeds the target (ResponseTime+ExtraTime) then set timeout to true which will terminate the search. */ { NXEvent peek_ev, *get_ev; et = time((long *)0) - time0; if (et < 0) et = 0; ETnodes += 50; if( !iop ){ if( [[NXApp clockWindow] isVisible] ){ if( player == white ) [[NXApp whiteMeter] display]; else [[NXApp blackMeter] display]; NXPing(); } } #ifdef TIME_STUFF printf( "ResponseTime %d, ExtraTime %d, Sdepth %d, iop %d, et %d, et0 %d\n", ResponseTime, ExtraTime, Sdepth, iop, et, et0 ); #endif if (et > et0 || iop == 1){ if (et > ResponseTime+ExtraTime && Sdepth > 1){ timeout = true; } et0 = et; if (iop == 1){ time0 = time((long *)0); et0 = 0; } #ifdef PROFILE (void) times(&tmbuf2); cputimer = 100*(tmbuf2.tms_utime - tmbuf1.tms_utime) / HZ; if (cputimer > 0) evrate = (100*NodeCnt)/(cputimer+100*ft); else evrate = 0; #endif ETnodes = NodeCnt + 50; UpdateClocks(); } if( [NXApp peekNextEvent: NX_MOUSEDOWNMASK into: &peek_ev] ){ get_ev = [NXApp getNextEvent: NX_MOUSEDOWNMASK]; [NXApp sendEvent: get_ev]; #ifdef NeXT_DEBUG printf( "mousedown event, sending to application\n" ); #endif } } UpdateClocks() { } ShowResults( short score, unsigned short bstline[], char ch ) { #ifdef NeXT_DEBUG printf( "ShowResults: " ); printf("score = %d",score); printf(" %5s\n", mvstr1 ); #endif } GameEnd( short score ) { NXBeep(); if( root->flags & draw ){ [NXApp setFinished: DRAW_GAME]; } else if( score == 9998 ){ printf( "score %d, winner %d\n", score, winner ); [NXApp setFinished: winner == black ? BLACK_MATE : WHITE_MATE]; } else if( score == -9999 ){ if( bothsides ){ printf( "score %d, winner %d\n", score, winner ); if( winner != -1 ) [NXApp setFinished: winner == white ? WHITE_MATE : BLACK_MATE]; else [NXApp setFinished: WHITE_MATE]; } else [NXApp setFinished: OPPONENT_MATE ]; } } ClrScreen() { } UpdateDisplay( short f, short t, short flag, short iscastle ) { #ifdef NeXT_DEBUG printf( "Update Display: from %d, to %d, flag 0x%04x, iscastle %d, InChk %d\n", f, t, flag, iscastle, InChk ); #endif [[NXApp gameBoard] layoutBoard: board color: color]; [[NXApp gameBoard] display]; } InCheck() { int incheck = -1; if( SqAtakd( PieceList[computer][0], opponent ) ) incheck = computer; if( SqAtakd( PieceList[opponent][0], computer ) ) incheck = opponent; if( incheck == black ) ShowMessage( "Black is in check" ); else if( incheck == 0 ) ShowMessage( "White is in check" ); } GetOpenings() /* Read in the Opening Book file and parse the algebraic notation for a move into an unsigned integer format indicating the from and to square. Create a linked list of opening lines of play, with entry->next pointing to the next line and entry->move pointing to a chunk of memory containing the moves. More Opening lines of up to 256 half moves may be added to gnuchess.book. */ { int c,i,j,side; struct BookEntry *entry; unsigned short mv,*mp,tmp[100]; int book_size; char *book_data; NXStream *book_stream; book_data = (char *)getsectdata( "__BOOK", "gnuchess.book", &book_size); if( book_data != NULL ){ book_stream = NXOpenMemory( book_data, book_size, NX_READONLY ); Book = NULL; i = 0; side = white; while((c = parse( book_stream, &mv, side)) >= 0 ){ if(c == 1){ tmp[++i] = mv; side = otherside[side]; } else if (c == 0 && i > 0){ entry = (struct BookEntry *)malloc(sizeof(struct BookEntry)); mp = (unsigned short *)malloc((i+1)*sizeof(unsigned short)); entry->mv = mp; entry->next = Book; Book = entry; for (j = 1; j <= i; j++) *(mp++) = tmp[j]; *mp = 0; i = 0; side = white; } } NXCloseMemory( book_stream, NX_SAVEBUFFER ); } } int parse( NXStream *book_stream, unsigned short *mv, short side ) { int c,i,r1,r2,c1,c2; char s[100]; while ((c = NXGetc( book_stream )) == ' '); i = 0; s[0] = c; while (c != ' ' && c != '\n' && c != EOF) s[++i] = c = NXGetc( book_stream ); s[++i] = '\0'; if (c == EOF) return(-1); if (s[0] == '!' || i < 3){ while (c != '\n' && c != EOF) c = NXGetc( book_stream ); return(0); } if (s[4] == 'o'){ if (side == black) *mv = 0x3C3A; else *mv = 0x0402; } else if (s[0] == 'o'){ if (side == black) *mv = 0x3C3E; else *mv = 0x0406; } else{ c1 = s[0] - 'a'; r1 = s[1] - '1'; c2 = s[2] - 'a'; r2 = s[3] - '1'; *mv = (locn[r1][c1]<<8) + locn[r2][c2]; } return(1); } ShowDepth( char ch ) { #ifdef NeXT_DEBUG_X printf( "ShowDepth: %d%c max %d\n", Sdepth, ch, MaxSearchDepth ); #endif } ShowCurrentMove( short pnt, short f, short t ) { #ifdef NeXT_DEBUG printf( "ShowCurrentMove\n" ); algbr(f,t,false); printf("(%2d) %4s",pnt,mvstr1); #endif } ShowSidetomove() { #ifdef NeXT_DEBUG printf( "ShowSidetomove\n" ); if (player == white) printf("%2d: WHITE\n",1+(GameCnt+1)/2); else printf("%2d: BLACK\n",1+(GameCnt+1)/2); #endif } ShowMessage( char *s ) { #ifdef NeXT_DEBUG printf( "ShowMessage: %s\n", s ); #endif [NXApp setTitleMessage: s]; } void ExitChess() { [NXApp terminate: NXApp]; exit(0); } extern char playing; void Die() { if( NXRunAlertPanel( 0, "Do you want to exit chess?", "Yes", "No", 0 ) ){ signal(SIGINT,SIG_IGN); signal(SIGQUIT,SIG_IGN); ExitChess(); } } void TerminateSearch() { signal(SIGINT,SIG_IGN); signal(SIGQUIT,SIG_IGN); timeout = true; if( bothsides ) playing = 0; signal( SIGINT, Die ); signal( SIGQUIT, Die ); } SearchStartStuff( short side ) { signal(SIGINT,TerminateSearch); signal(SIGQUIT,TerminateSearch); } static char convert_buf[8]; char * convert_rc( int row, int col, int row2, int col2, int type ) { if( type == king && col == 4){ if( col2 == 6 ){ strcpy( convert_buf, "o-o" ); return( convert_buf ); } else if( col2 == 2 ){ strcpy( convert_buf, "o-o-o" ); return( convert_buf ); } } convert_buf[0] = 'a' + col; convert_buf[1] = '0' + row+1; convert_buf[2] = 'a' + col2; convert_buf[3] = '0' + row2+1; convert_buf[4] = 0; return( convert_buf ); } convert_algbr(char *algbr, int *r1, int *c1, int *r2, int *c2,int *castle_flag) { int type; *castle_flag = 0; if( strcmp( algbr, "o-o" ) == 0 ) *castle_flag = RIGHT_CASTLE; else if( strcmp( algbr, "o-o-o" ) == 0 ) *castle_flag = LEFT_CASTLE; else{ *c1 = algbr[0] - 'a'; *r1 = algbr[1] - '0' - 1; *c2 = algbr[2] - 'a'; *r2 = algbr[3] - '0' - 1; } type = [[NXApp gameBoard] typeAt: *r1 : *c1]; if( type ){ #ifdef NeXT_DEBUG printf( "type: %d\n", type ); #endif if( type == king ){ if( *c1 == 4 && *c2 == 6 ) *castle_flag = RIGHT_CASTLE; else if( *c1 == 4 && *c2 == 2 ) *castle_flag = LEFT_CASTLE; } } return; } GetGame( const char *fname ) { FILE *fd; int r, c; short sq; unsigned short m; if ((fd = fopen(fname,"r")) != NULL){ fscanf(fd,"%hd%hd%hd",&computer,&opponent,&Game50); fscanf(fd,"%hd%hd%hd%hd", &castld[white],&castld[black], &kingmoved[white],&kingmoved[black]); fscanf(fd,"%hd%hd",&TCflag,&OperatorTime); fscanf(fd,"%ld%ld%hd%hd", &TimeControl.clock[white],&TimeControl.clock[black], &TimeControl.moves[white],&TimeControl.moves[black]); for (sq = 0; sq < 64; sq++){ fscanf(fd,"%hd",&m); board[sq] = (m >> 8); color[sq] = (m & 0xFF); if(color[sq] == 0) color[sq] = neutral; else --color[sq]; } [[NXApp gameBoard] layoutBoard: board color: color]; [[NXApp gameBoard] display]; GameCnt = -1; c = '?'; while (c != EOF) { ++GameCnt; c = fscanf(fd,"%hd%hd%hd%ld%hd%hd%hd",&GameList[GameCnt].gmove, &GameList[GameCnt].score,&GameList[GameCnt].depth, &GameList[GameCnt].nodes,&GameList[GameCnt].time, &GameList[GameCnt].piece,&GameList[GameCnt].color); if (GameList[GameCnt].color == 0) GameList[GameCnt].color = neutral; else --GameList[GameCnt].color; } GameCnt--; if (TimeControl.clock[white] > 0) TCflag = true; computer--; opponent--; } fclose(fd); InitializeStats(); UpdateDisplay(0,0,1,0); Sdepth = 0; } SaveGame( const char *fname ) { FILE *fd; short sq,i,c; fd = fopen(fname,"w"); if( !fd ) return( 0 ); fprintf(fd,"%d %d %d\n",computer+1,opponent+1,Game50); fprintf(fd,"%d %d %d %d\n", castld[white],castld[black],kingmoved[white],kingmoved[black]); fprintf(fd,"%d %d\n",TCflag,OperatorTime); fprintf(fd,"%ld %ld %d %d\n", TimeControl.clock[white],TimeControl.clock[black], TimeControl.moves[white],TimeControl.moves[black]); for (sq = 0; sq < 64; sq++) { if (color[sq] == neutral) c = 0; else c = color[sq]+1; fprintf(fd,"%d\n",256*board[sq] + c); } for (i = 0; i <= GameCnt; i++) { if (GameList[i].color == neutral) c = 0; else c = GameList[i].color + 1; fprintf(fd,"%d %d %d %ld %d %d %d\n", GameList[i].gmove,GameList[i].score,GameList[i].depth, GameList[i].nodes,GameList[i].time, GameList[i].piece,c); } fclose(fd); return( 1 ); } ListGame( const char *filename ) { FILE *fd; short i,f,t; fd = fopen(filename,"w"); if( !fd ) return( 0 ); fprintf(fd,"\n"); fprintf(fd," score depth nodes time "); fprintf(fd," score depth nodes time\n"); for (i = 0; i <= GameCnt; i++){ f = GameList[i].gmove>>8; t = (GameList[i].gmove & 0xFF); algbr(f,t,false); if ((i % 2) == 0) fprintf(fd,"\n"); else fprintf(fd," "); fprintf(fd,"%5s %5d %2d %6ld %5d",mvstr1, GameList[i].score,GameList[i].depth, GameList[i].nodes,GameList[i].time); } fprintf(fd,"\n\n"); fclose(fd); return( 1 ); } Undo() /* Undo the most recent half-move. */ { short f,t; f = GameList[GameCnt].gmove>>8; t = GameList[GameCnt].gmove & 0xFF; if (board[t] == king && distance(t,f) > 1) { castle(GameList[GameCnt].color,f,t,2); } else { board[f] = board[t]; color[f] = color[t]; board[t] = GameList[GameCnt].piece; color[t] = GameList[GameCnt].color; if ( GameQueens[GameCnt] ) { board[f] = GameQueens[GameCnt]; } if (board[f] == king) --kingmoved[color[f]]; } if (TCflag) ++TimeControl.moves[color[f]]; GameCnt--; mate = false; Sdepth = 0; if ( [NXApp finished] ) { [NXApp setFinished: false]; } UpdateDisplay(0,0,1,0); InitializeStats(); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.