2 * nondsp.c - UNIX & MSDOS AND NON-DISPLAY interface for GNU SHOGI
4 * Copyright (c) 1993, 1994, 1995 Matthias Mutz
6 * GNU SHOGI is based on GNU CHESS
8 * Copyright (c) 1988,1989,1990 John Stanback
9 * Copyright (c) 1992 Free Software Foundation
11 * This file is part of GNU SHOGI.
13 * GNU Shogi is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 1, or (at your option)
18 * GNU Shogi is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with GNU Shogi; see the file COPYING. If not, write to
25 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
39 #include <sys/param.h>
40 #include <sys/types.h>
42 #include <sys/ioctl.h>
43 void TerminateSearch (int), Die (int);
50 short int debuglevel = 1024;
52 unsigned short int MV[MAXDEPTH];
65 extern short int pscore[];
71 #if defined XSHOGI && !defined THINK_C && !defined MSDOS
75 setvbuf (stdout, NULL, _IOLBF, BUFSIZ);
77 printf ("GNU Shogi %sp%s\n", version, patchlevel);
80 if (!TCflag && (MaxResponseTime == 0))
81 MaxResponseTime = 15L*100L;
88 signal (SIGTERM, SIG_IGN);
94 #ifndef MSDOS /* never called!!! */
100 ShowMessage (CP[31]); /*Abort?*/
102 if (strcmp (s, CP[210]) == 0) /*yes*/
109 TerminateSearch (int sig)
112 sig++; /* shut up the compiler */
114 #ifdef INTERRUPT_TEST
115 ElapsedTime(INIT_INTERRUPT_MODE);
118 flag.back = true; /* previous: flag.timeout = true; */
119 flag.bothsides = false;
121 printf("Terminate Search\n");
132 /*printz ("SHOGI command summary\n");*/
134 printz ("----------------------------------------------------------------\n");
135 /*printz ("7g7f move from 7g to 7f quit Exit Shogi\n");*/
137 /*printz ("S6h move silver to 6h beep turn %s\n", (flag.beep) ? "off" : "on");*/
138 printz (CP[86], (flag.beep) ? CP[92] : CP[93]);
139 /*printz ("2d2c+ move from 2d to 2c and promote\n");*/
140 printz (CP[128], (flag.material) ? CP[92] : CP[93]);
141 /*printz ("P*5e drop pawn to 5e easy turn %s\n", (flag.easy) ? "off" : "on");*/
142 printz (CP[173], (flag.easy) ? CP[92] : CP[93]);
143 /*printz (" hash turn %s\n", (flag.hash) ? "off" : "on");*/
144 printz (CP[174], (flag.hash) ? CP[92] : CP[93]);
145 /*printz ("bd redraw board reverse board display\n");*/
147 /*printz ("list game to shogi.lst book turn %s used %d of %d\n", (Book) ? "off" : "on", bookcount);*/
148 printz (CP[170], (Book) ? CP[92] : CP[93], bookcount,booksize);
149 /*printz ("undo undo last ply remove take back a move\n");*/
151 /*printz ("edit edit board force enter game moves\n");*/
153 /*printz ("switch sides with computer both computer match\n");*/
155 /*printz ("black computer plays black white computer plays white\n");*/
157 /*printz ("depth set search depth clock set time control\n");*/
159 /*printz ("post principle variation hint suggest a move\n");*/
161 /*printz ("save game to file get game from file\n");*/
163 printz ("xsave pos. to xshogi file xget pos. from xshogi file\n");
164 /*printz ("random randomize play new start new game\n");*/
166 printz ("----------------------------------------------------------------\n");
167 /*printz ("Computer: %-12s Opponent: %s\n",*/
169 ColorStr[computer], ColorStr[opponent]);
170 /*printz ("Depth: %-12d Response time: %d sec\n",*/
172 MaxSearchDepth, MaxResponseTime/100);
173 /*printz ("Random: %-12s Easy mode: %s\n",*/
175 (dither) ? CP[93] : CP[92], (flag.easy) ? CP[93] : CP[92]);
176 /*printz ("Beep: %-12s Transposition file: %s\n",*/
178 (flag.beep) ? CP[93] : CP[92], (flag.hash) ? CP[93] : CP[92]);
179 /*printz ("Tsume: %-12s Force: %s\n")*/
181 (flag.tsume) ? CP[93] : CP[92], (flag.force) ? CP[93] : CP[92]);
182 /*printz ("Time Control %s %d moves %d seconds %d opr %d depth\n", (TCflag) ? "ON" : "OFF",*/
183 printz (CP[110], (TCflag) ? CP[93] : CP[92],
184 TimeControl.moves[black], TimeControl.clock[black] / 100, TCadd/100, MaxSearchDepth);
185 signal (SIGINT, TerminateSearch);
186 #if !defined MSDOS && !defined THINK_C
187 signal (SIGQUIT, TerminateSearch);
196 * Set up a board position. Pieces are entered by typing the piece followed
197 * by the location. For example, Nf3 will place a knight on square f3.
201 short a, r, c, sq, i, found;
204 flag.regularstart = true;
207 UpdateDisplay (0, 0, 1, 0);
208 /*printz (". exit to main\n");*/
210 /*printz ("# clear board\n");*/
212 /*printz ("c change sides\n");*/
214 /*printz ("enter piece & location: \n");*/
222 if (s[0] == CP[28][0]) /*#*/
224 for (sq = 0; sq < NO_SQUARES; sq++)
226 board[sq] = no_piece;
231 if (s[0] == CP[136][0]) /*c*/
235 for ( i = pawn; i <= king; i++)
236 if ((s[0] == pxx[i]) || (s[0] == qxx[i]))
250 if ((c >= 0) && (c < NO_COLS) && (r >= 0) && (r < NO_ROWS))
254 board[sq] = no_piece;
255 for (i = no_piece; i <= king; i++)
256 if ((s[0] == pxx[i]) || (s[0] == qxx[i]))
259 board[sq] = promoted[i];
265 if (found==0) color[sq] = neutral;
267 } while (s[0] != CP[29][0]);
268 for (sq = 0; sq < NO_SQUARES; sq++)
269 Mvboard[sq] = ((board[sq] != Stboard[sq]) ? 10 : 0);
276 UpdateDisplay (0, 0, 1, 0);
283 * Set up a board position.
284 * Nine lines of nine characters are used to setup the board. 9a-1a is the
285 * first line. White pieces are represented by uppercase characters.
295 gets (s); /* skip "setup" command */
296 for (r = NO_ROWS-1; r >= 0; r--)
299 for (c = 0; c <= (NO_COLS-1); c++)
304 board[sq] = no_piece;
305 for (i = no_piece; i <= king; i++)
312 else if (ch == qxx[i])
320 for (sq = 0; sq < NO_SQUARES; sq++)
321 Mvboard[sq] = ((board[sq] != Stboard[sq]) ? 10 : 0);
324 UpdateDisplay (0, 0, 1, 0);
325 /*printz ("Setup successful\n");*/
333 ch++; /* shut up the compiler */
335 #if !defined BAREBONES
336 printz (CP[53], Sdepth, ch); /*Depth= %d%c*/
345 printz("stage = %d\n",stage);
346 printz("balance[black] = %d balance[white] = %d\n",balance[black],balance[white]);
351 ShowLine (short unsigned int *bstline)
355 for (i = 1; bstline[i] > 0; i++)
357 if ((i > 1) && (i % 8 == 1))
359 algbr ((short) (bstline[i] >> 8), (short) (bstline[i] & 0xFF), false);
360 printf ("%5s ", mvstr[0]);
366 ShowResults (short int score, short unsigned int *bstline, char ch)
371 printf ("%2d%c %6d %4ld %8ld ", Sdepth, ch, score, et / 100, NodeCnt);
377 ShowPatternCount (short side, short n)
381 printz("%s matches %d pattern(s)\n",ColorStr[side],n);
386 ShowResponseTime (void)
391 printz("RT=%ld TCC=%d TCL=%ld EX=%ld ET=%ld TO=%d\n",
392 ResponseTime,TCcount,TCleft,ExtraTime,et,flag.timeout);
402 printz("%c vs. %c\n",GameType[black],GameType[white]);
407 SearchStartStuff (short int side)
409 signal (SIGINT, TerminateSearch);
410 #if !defined MSDOS && !defined THINK_C
411 signal (SIGQUIT, TerminateSearch);
417 ResponseTime, TimeControl.clock[side]);
427 extern unsigned short int PrVar[];
430 D = fopen ("/tmp/DEBUGA", "a+");
431 fprintf (D, "inout move is %s\n", mvstr[0]);
432 strcpy (d, mvstr[0]);
433 for (i = 1; PrVar[i] > 0; i++)
435 algbr ((short) (PrVar[i] >> 8), (short) (PrVar[i] & 0xFF), false);
436 fprintf (D, "%5s ", mvstr[0]);
439 fprintf_current_board (D);
441 strcpy (mvstr[0], d);
444 if (flag.illegal) {printf("%s\n",CP[225]);return;}
445 if (mvstr[0][0] == '\0') goto nomove;
447 /* add remaining time in milliseconds to xshogi */
448 printz ("%d. ... %s %ld\n", ++mycnt1, mvstr[0], (TimeControl.clock[player]-et)*10);
450 printz ("%d. ... %s\n", ++mycnt1, mvstr[0]);
452 #ifdef notdef /* optional pass best line to frontend with move */
457 printz (" %6d%c ", MSCORE, MV[30]);
458 for (i = 1; MV[i] > 0; i++)
460 algbr ((short) (MV[i] >> 8), (short) (MV[i] & 0xFF), false);
461 printz ("%5s ", mvstr[0]);
467 if ((root->flags & draw)||(root->score == -(SCORE_LIMIT+999))||
468 (root->score == (SCORE_LIMIT+998))) goto summary;
478 if (Tree[t].f || Tree[t].t)
484 /*printf ("Nodes %ld Tree %d Eval %ld Rate %ld RS high %ld low %ld\n",*/
485 printf (CP[89],GenCnt,NodeCnt,t,EvalNodes,(et>100)?(NodeCnt/(et/100)):0,EADD,EGET,reminus,replus);
486 /*printf ("Hin/Hout/Coll/Fin/Fout = %ld/%ld/%ld/%ld/%ld\n",*/
488 HashAdd, HashCnt, THashCol, HashCol,FHashCnt, FHashAdd);
490 UpdateDisplay (root->f, root->t, 0, root->flags);
493 /*printf ("My move is: %s\n", mvstr[0]);*/
494 printf (CP[83], mvstr[0]);
499 if (root->flags & draw)
500 /* printf ("Drawn game!\n");*/
502 else if (root->score == -(SCORE_LIMIT+999))
503 printf("%s mates!\n",ColorStr[opponent]);
504 else if (root->score == (SCORE_LIMIT+998))
505 printf("%s mates!\n",ColorStr[computer]);
506 #if !defined BAREBONES
508 else if (root->score < -SCORE_LIMIT)
509 printf("%s has a forced mate in %d moves!\n",
510 ColorStr[opponent], SCORE_LIMIT+999 + root->score - 1);
511 else if (root->score > SCORE_LIMIT)
512 printf("%s has a forced mate in %d moves!\n",
513 ColorStr[computer], SCORE_LIMIT+998 - root->score - 1);
515 #endif /* BAREBONES */
521 #if !defined BAREBONES
527 UpdateDisplay (short int f, short int t, short int redraw, short int isspec)
532 if (redraw && !xshogi)
535 r = (short)(TimeControl.clock[black] / 6000);
536 c = (short)((TimeControl.clock[black] % 6000) / 100);
537 l = (short)(TimeControl.clock[white] / 6000);
538 m = (short)((TimeControl.clock[white] % 6000) / 100);
539 /*printz ("Black %d:%02d White %d:%02d\n", r, c, l, m);*/
540 printz (CP[116], r, c, l, m);
542 for (r = (NO_ROWS-1); r >= 0; r--)
544 for (c = 0; c <= (NO_COLS-1); c++)
546 l = ((flag.reverse) ? locn ((NO_ROWS-1) - r, (NO_COLS-1) - c) : locn (r, c));
547 pc = (is_promoted[board[l]] ? '+' : ' ');
548 if (color[l] == neutral)
550 else if (color[l] == black)
551 printz ("%c%c", pc, qxx[board[l]]);
553 printz ("%c%c", pc, pxx[board[l]]);
560 for (side = black; side <= white; side++)
562 printz((side==black)?"black ":"white ");
563 for (piece = pawn; piece <= king; piece++)
564 if (c = Captured[side][piece])
565 printz("%i%c ",c,pxx[piece]);
573 ShowMessage (char *s)
579 ShowSidetoMove (void)
586 #if !defined BAREBONES
587 /*printz ("\nYour move is? ");*/
589 #endif /* BAREBONES */
594 ShowCurrentMove (short int pnt, short int f, short int t)
599 pnt++; /* shut up the compiler */
604 ChangeAlphaWindow (void)
606 printz ("WAwindow: ");
607 scanz ("%hd", &WAwindow);
608 printz ("BAwindow: ");
609 scanz ("%hd", &BAwindow);
613 ChangeBetaWindow (void)
615 printz ("WBwindow: ");
616 scanz ("%hd", &WBwindow);
617 printz ("BBwindow: ");
618 scanz ("%hd", &BBwindow);
626 algbr ((short) (hint >> 8), (short) (hint & 0xFF), false);
627 printf(CP[72], mvstr[0]); /*hint*/
634 SelectLevel (char *sx)
637 char T[NO_SQUARES], *p, *q;
639 if ( (p = strstr(sx,CP[169])) != NULL )
640 p += strlen(CP[169]);
641 else if ( (p = strstr(sx,CP[217])) != NULL )
642 p += strlen(CP[217]);
645 for(;*p != 'X';*q++ = *p++);
647 /* line empty ask for input */
648 if(!T[0]){ printz (CP[61]); gets(T); strcat(T,"XX"); }
649 /* skip blackspace */
650 for (p = T; *p == ' '; p++) ;
651 /* could be moves or a fischer clock */
652 if(*p == 'f') { /* its a fischer clock game */
654 TCminutes = (short)strtol(p,&q,10);
655 TCadd = (short)strtol(q,NULL,10) *100;
658 } else { /* regular game */
660 TCmoves = (short)strtol (p, &q, 10);
661 TCminutes = (short)strtol (q, &q, 10);
663 TCseconds = (short)strtol (q + 1, (char **) NULL, 10);
668 scanz ("%hd", &OperatorTime);
672 MaxResponseTime = TCminutes*60L*100L + TCseconds*100L;
673 TCminutes = TCseconds = 0;
679 TimeControl.clock[black] = TimeControl.clock[white] = 0;
682 printz ("Clocks: %ld %ld\n",TimeControl.clock[black]*10,TimeControl.clock[white]*10);
691 scanz ("%hd", &debuglevel);
697 ChangeSearchDepth (void)
700 scanz ("%hd", &MaxSearchDepth);
701 TCflag = !(MaxSearchDepth > 0);
705 ChangeHashDepth (void)
707 printz ("hashdepth= ");
708 scanz ("%hd", &HashDepth);
709 printz ("MoveLimit= ");
710 scanz ("%hd", &HashMoveLimit);
716 printz ("contempt= ");
717 scanz ("%hd", &contempt);
724 scanz ("%hd", &xwndw);
728 ShowPostnValue (short int sq)
731 * must have called ExaminePosition() first
736 score = ScorePosition (color[sq]);
737 if (color[sq] != neutral){
738 #if defined SAVE_SVALUE
739 printz ("???%c ", (color[sq] == white)?'b':'w');}
741 printz ("%3d%c ", svalue[sq],(color[sq] == white)?'b':'w');}
750 short c, p, sq, tp, tc, tsq, score,j,k;
753 ExaminePosition (opponent);
754 ShowMessage (CP[65]);
757 if (s[0] == CP[9][0] || s[0] == CP[9][1]) /* w W*/ c = black;
758 if (s[0] == CP[9][2] || s[0] == CP[9][3]) /*b B*/ c = white;
759 for (p = king; p > no_piece; p--)
760 if ((s[1] == pxx[p]) || (s[1] == qxx[p])) break;
762 for(j=(NO_ROWS-1);j>=0;j--){
763 for(k=0;k<(NO_COLS);k++){
769 tsq = PieceList[c][1];
770 PieceList[c][1] = sq;
772 PieceList[c][1] = tsq;
778 score = ScorePosition (opponent);
779 for(j=(NO_ROWS-1);j>=0;j--){
780 for(k=0;k<(NO_COLS);k++){
782 if (color[sq] != neutral){
783 #if defined SAVE_SVALUE
784 printz ("%?????%c ", (color[sq] == white)?'b':'w');}
786 printz ("%5d%c ", svalue[sq],(color[sq] == white)?'b':'w');}
793 printz("stage = %d\n",stage);
794 printz (CP[103], score,
795 mtl[computer], pscore[computer], GameType[computer],
796 mtl[opponent], pscore[opponent], GameType[opponent]);
800 DoTable (short table[NO_SQUARES])
803 ExaminePosition (opponent);
804 for(j=(NO_ROWS-1);j>=0;j--){
805 for(k=0;k<NO_COLS;k++){
807 printz ("%3d ", table[sq]);
814 ShowPostnValues (void)
817 ExaminePosition (opponent);
818 for(j=(NO_ROWS-1);j>=0;j--){
819 for(k=0;k<NO_COLS;k++){
825 score = ScorePosition (opponent);
826 printz (CP[103], score,
827 mtl[computer], pscore[computer], GameType[computer],
828 mtl[opponent], pscore[opponent], GameType[opponent]);
829 printz("\nhung black %d hung white %d\n",hung[black],hung[white]);