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
]);