From mipos3!intelca!amd!amdcad!ames!ll-xn!husc6!mit-eddie!uw-beaver!tektronix!tekgen!tekred!games-request Wed Jul 1 07:24:56 PDT 1987 Article 8 of comp.sources.games: Path: td2cad!mipos3!intelca!amd!amdcad!ames!ll-xn!husc6!mit-eddie!uw-beaver!tektronix!tekgen!tekred!games-request From: games-request@tekred.TEK.COM Newsgroups: comp.sources.games Subject: v01i060: kriegspiel - A Chess Variant, Part01/04 Message-ID: <1350@tekred.TEK.COM> Date: 29 Jun 87 18:19:34 GMT Expires: 29 Jul 87 18:14:10 GMT Sender: billr@tekred.TEK.COM Lines: 2038 Approved: billr@tekred.TEK.COM Submitted by: Steve Schoch Comp.sources.games: Volume 1, Issue 60 Archive-name: kriegspiel/Part01 [Starting with this posting, all postings to comp.sources.games will go out with a expiration date of 1 month from the date of posting. With network delays, some articles were arriving at sites just as it was time to expire the article (2 week default). This should allow it to around long enough for most regualr readers to see, yet not so long as to hoard disk space. -br] #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh README <<'END_OF_README' X XKriegspiel written by David Wolfe based on a program by Bert Enderton X May 5, 1986 X XModified to work with X window system by Steve Schoch . XI also fixed the protocol to be more ARPA-like. X May 19, 1987 X X1) First adjust the first to constants in constants.h X2) If your machine does not have malloc (), then see comment in externs.h X3) type 'make' X If you don't have X, type "make ks" to make the curses version only. X XIf anyone on the arpanet wants to play a game with me, give a shout to Xschoch@ames.arpa. END_OF_README if test 532 -ne `wc -c MANIFEST <<'END_OF_MANIFEST' X File Name Archive # Description X----------------------------------------------------------- X MANIFEST 1 This shipping list X Makefile 1 X README 1 X README.protocol 2 X README2 4 X bishop.h 3 X bishop_mask.h 2 X check.c 3 X connect.c 2 X constants.h 3 X error.c 4 X externs.h 2 X help 1 X help.nroff 2 X icon.h 3 X init.c 2 X input.c 1 X king.h 3 X king_mask.h 3 X knight.h 3 X knight_mask.h 3 X legalmove.c 3 X list.c 3 X main.c 2 X makemove.c 3 X mate.c 3 X movecycle.c 2 X options.c 3 X output.c 3 X pawn.h 3 X pawn_mask.h 3 X pawntries.c 1 X piecemoves.c 3 X queen.h 3 X queen_mask.h 3 X review.c 3 X rook.h 3 X rook_mask.h 3 X screen.c 2 X traps.c 2 X xboard.c 2 X xinput.c 1 X xmain.c 2 X xmove.c 3 X xoutput.c 3 X xpieces.c 2 X xscreen.c 1 END_OF_MANIFEST if test 1524 -ne `wc -c Makefile <<'END_OF_Makefile' X# Kriegspiel written by David Wolfe based on a program by Bert Enderton X# May 5, 1986 X# X# on machines without alloca () `#define alloca malloc' in externs.h X XCFLAGS = -O XXFLAGS = -DXKS X# curses .o files XOBJ = init.o input.o movecycle.o \ X output.o output.o main.o \ X legalmove.o error.o traps.o screen.o review.o X X# curses .c files XCFILES = check.c init.c input.c list.c mate.c makemove.c movecycle.c \ X output.c pawntries.c piecemoves.c legalmove.c main.c \ X connect.c error.c review.c traps.c screen.c options.c X X# separate X .c files XXCFILES = xmain.c xpieces.c xscreen.c xinput.c xboard.c \ X xmove.c xoutput.c X X# corresponding .o files XXOBJS = xmain.o xpieces.o xscreen.o xinput.o xboard.o \ X xmove.o xoutput.o X X# common .o files XCOMMON = connect.o check.o list.o mate.o pawntries.o options.o makemove.o \ X piecemoves.o legalmove.o X X# Common sources, but need separate compiles XXCOMMON = error.o review.o init.o movecycle.o XXC = xerror.o xreview.o xinit.o xmovecycle.o X X.DEFAULT: X co $< X Xall: ks xks X touch all X Xks: $(OBJ) $(COMMON) Makefile X cc -o ks $(OBJ) $(COMMON) -lcurses -ltermcap X X$(XCOMMON): X cc -c ${CFLAGS} ${XFLAGS} $*.c X mv $*.o x$*.o X cc -c ${CFLAGS} $*.c X Xxks: $(XOBJS) $(COMMON) $(XCOMMON) X cc -o xks $(XOBJS) $(COMMON) $(XC) -lX X X$(XOBJS): X cc -c $(CFLAGS) $(XFLAGS) $*.c X Xtags: ${CFILES} ${XCFILES} X ctags ${CFILES} ${XCFILES} X Xdepend: X cc -M ${CFLAGS} ${CFILES} | \ X awk ' { if ($$1 != prev) { print rec; rec = $$0; prev = $$1; } \ X else { if (length(rec $$2) > 78) { print rec; rec = $$0; } \ X else rec = rec " " $$2 } } \ X END { print rec } ' > makedep X cc -M ${CFLAGS} ${XFLAGS} $(XCFILES) | \ X awk ' { if ($$1 != prev) { print rec; rec = $$0; prev = $$1; } \ X else { if (length(rec $$2) > 78) { print rec; rec = $$0; } \ X else rec = rec " " $$2 } } \ X END { print rec } ' | sed '/^$$/d' >> makedep X echo '/^# DO NOT DELETE THIS LINE/+1,$$d' > eddep X echo '$$r makedep' >> eddep X echo 'w' >> eddep X cp Makefile Makefile.bak X ex - Makefile < eddep X rm eddep makedep X Xclean: X rm -f ks xks *.o X X# DO NOT DELETE THIS LINE -- make depend uses it X Xcheck.o: check.c ./externs.h ./constants.h /usr/include/stdio.h Xcheck.o: /usr/include/curses.h /usr/include/stdio.h /usr/include/sgtty.h Xcheck.o: /usr/include/sys/ioctl.h /usr/include/sys/ttychars.h Xcheck.o: /usr/include/sys/ttydev.h /usr/include/errno.h Xcheck.o: /usr/include/sys/types.h Xinit.o: init.c ./externs.h ./constants.h /usr/include/stdio.h Xinit.o: /usr/include/curses.h /usr/include/stdio.h /usr/include/sgtty.h Xinit.o: /usr/include/sys/ioctl.h /usr/include/sys/ttychars.h Xinit.o: /usr/include/sys/ttydev.h /usr/include/errno.h /usr/include/sys/types.h Xinit.o: /usr/include/ctype.h Xinput.o: input.c ./externs.h ./constants.h /usr/include/stdio.h Xinput.o: /usr/include/curses.h /usr/include/stdio.h /usr/include/sgtty.h Xinput.o: /usr/include/sys/ioctl.h /usr/include/sys/ttychars.h Xinput.o: /usr/include/sys/ttydev.h /usr/include/errno.h Xinput.o: /usr/include/sys/types.h /usr/include/ctype.h /usr/include/strings.h Xinput.o: /usr/include/sys/time.h /usr/include/time.h Xlist.o: list.c ./constants.h Xmate.o: mate.c ./externs.h ./constants.h /usr/include/stdio.h Xmate.o: /usr/include/curses.h /usr/include/stdio.h /usr/include/sgtty.h Xmate.o: /usr/include/sys/ioctl.h /usr/include/sys/ttychars.h Xmate.o: /usr/include/sys/ttydev.h /usr/include/errno.h /usr/include/sys/types.h Xmakemove.o: makemove.c ./externs.h ./constants.h /usr/include/stdio.h Xmakemove.o: /usr/include/curses.h /usr/include/stdio.h /usr/include/sgtty.h Xmakemove.o: /usr/include/sys/ioctl.h /usr/include/sys/ttychars.h Xmakemove.o: /usr/include/sys/ttydev.h /usr/include/errno.h Xmakemove.o: /usr/include/sys/types.h Xmovecycle.o: movecycle.c ./externs.h ./constants.h /usr/include/stdio.h Xmovecycle.o: /usr/include/curses.h /usr/include/stdio.h /usr/include/sgtty.h Xmovecycle.o: /usr/include/sys/ioctl.h /usr/include/sys/ttychars.h Xmovecycle.o: /usr/include/sys/ttydev.h /usr/include/errno.h Xmovecycle.o: /usr/include/sys/types.h Xoutput.o: output.c ./externs.h ./constants.h /usr/include/stdio.h Xoutput.o: /usr/include/curses.h /usr/include/stdio.h /usr/include/sgtty.h Xoutput.o: /usr/include/sys/ioctl.h /usr/include/sys/ttychars.h Xoutput.o: /usr/include/sys/ttydev.h /usr/include/errno.h Xoutput.o: /usr/include/sys/types.h /usr/include/strings.h Xpawntries.o: pawntries.c ./externs.h ./constants.h /usr/include/stdio.h Xpawntries.o: /usr/include/curses.h /usr/include/stdio.h /usr/include/sgtty.h Xpawntries.o: /usr/include/sys/ioctl.h /usr/include/sys/ttychars.h Xpawntries.o: /usr/include/sys/ttydev.h /usr/include/errno.h Xpawntries.o: /usr/include/sys/types.h Xpiecemoves.o: piecemoves.c ./externs.h ./constants.h /usr/include/stdio.h Xpiecemoves.o: /usr/include/curses.h /usr/include/stdio.h /usr/include/sgtty.h Xpiecemoves.o: /usr/include/sys/ioctl.h /usr/include/sys/ttychars.h Xpiecemoves.o: /usr/include/sys/ttydev.h /usr/include/errno.h Xpiecemoves.o: /usr/include/sys/types.h Xlegalmove.o: legalmove.c ./externs.h ./constants.h /usr/include/stdio.h Xlegalmove.o: /usr/include/curses.h /usr/include/stdio.h /usr/include/sgtty.h Xlegalmove.o: /usr/include/sys/ioctl.h /usr/include/sys/ttychars.h Xlegalmove.o: /usr/include/sys/ttydev.h /usr/include/errno.h Xlegalmove.o: /usr/include/sys/types.h Xmain.o: main.c ./externs.h ./constants.h /usr/include/stdio.h Xmain.o: /usr/include/curses.h /usr/include/stdio.h /usr/include/sgtty.h Xmain.o: /usr/include/sys/ioctl.h /usr/include/sys/ttychars.h Xmain.o: /usr/include/sys/ttydev.h /usr/include/errno.h /usr/include/sys/types.h Xmain.o: /usr/include/ctype.h /usr/include/signal.h /usr/include/strings.h Xconnect.o: connect.c ./externs.h ./constants.h /usr/include/stdio.h Xconnect.o: /usr/include/curses.h /usr/include/stdio.h /usr/include/sgtty.h Xconnect.o: /usr/include/sys/ioctl.h /usr/include/sys/ttychars.h Xconnect.o: /usr/include/sys/ttydev.h /usr/include/errno.h Xconnect.o: /usr/include/sys/types.h /usr/include/sys/types.h Xconnect.o: /usr/include/sys/socket.h /usr/include/sys/param.h Xconnect.o: /usr/include/machine/machparam.h /usr/include/signal.h Xconnect.o: /usr/include/sys/types.h /usr/include/netinet/in.h Xconnect.o: /usr/include/netdb.h /usr/include/pwd.h /usr/include/errno.h Xerror.o: error.c ./externs.h ./constants.h /usr/include/stdio.h Xerror.o: /usr/include/curses.h /usr/include/stdio.h /usr/include/sgtty.h Xerror.o: /usr/include/sys/ioctl.h /usr/include/sys/ttychars.h Xerror.o: /usr/include/sys/ttydev.h /usr/include/errno.h Xerror.o: /usr/include/sys/types.h /usr/include/errno.h /usr/include/signal.h Xreview.o: review.c ./externs.h ./constants.h /usr/include/stdio.h Xreview.o: /usr/include/curses.h /usr/include/stdio.h /usr/include/sgtty.h Xreview.o: /usr/include/sys/ioctl.h /usr/include/sys/ttychars.h Xreview.o: /usr/include/sys/ttydev.h /usr/include/errno.h Xreview.o: /usr/include/sys/types.h /usr/include/sys/time.h /usr/include/time.h Xtraps.o: traps.c ./externs.h ./constants.h /usr/include/stdio.h Xtraps.o: /usr/include/curses.h /usr/include/stdio.h /usr/include/sgtty.h Xtraps.o: /usr/include/sys/ioctl.h /usr/include/sys/ttychars.h Xtraps.o: /usr/include/sys/ttydev.h /usr/include/errno.h Xtraps.o: /usr/include/sys/types.h /usr/include/signal.h Xscreen.o: screen.c ./externs.h ./constants.h /usr/include/stdio.h Xscreen.o: /usr/include/curses.h /usr/include/stdio.h /usr/include/sgtty.h Xscreen.o: /usr/include/sys/ioctl.h /usr/include/sys/ttychars.h Xscreen.o: /usr/include/sys/ttydev.h /usr/include/errno.h Xscreen.o: /usr/include/sys/types.h /usr/include/ctype.h Xoptions.o: options.c ./externs.h ./constants.h /usr/include/stdio.h Xoptions.o: /usr/include/curses.h /usr/include/stdio.h /usr/include/sgtty.h Xoptions.o: /usr/include/sys/ioctl.h /usr/include/sys/ttychars.h Xoptions.o: /usr/include/sys/ttydev.h /usr/include/errno.h Xoptions.o: /usr/include/sys/types.h /usr/include/strings.h Xxmain.o: xmain.c /usr/include/strings.h /usr/include/ctype.h Xxmain.o: /usr/include/sys/signal.h /usr/include/errno.h ./externs.h Xxmain.o: ./constants.h /usr/include/stdio.h /usr/include/X/Xlib.h Xxmain.o: /usr/include/X/mit-copyright.h /usr/include/X/X.h Xxmain.o: /usr/include/X/mit-copyright.h /usr/include/errno.h Xxmain.o: /usr/include/sys/types.h Xxpieces.o: xpieces.c ./externs.h ./constants.h /usr/include/stdio.h Xxpieces.o: /usr/include/X/Xlib.h /usr/include/X/mit-copyright.h Xxpieces.o: /usr/include/X/X.h /usr/include/X/mit-copyright.h Xxpieces.o: /usr/include/errno.h /usr/include/sys/types.h ./pawn.h ./pawn_mask.h Xxpieces.o: ./bishop.h ./bishop_mask.h ./queen.h ./queen_mask.h ./king.h Xxpieces.o: ./king_mask.h ./rook.h ./rook_mask.h ./knight.h ./knight_mask.h Xxpieces.o: ./icon.h Xxscreen.o: xscreen.c ./externs.h ./constants.h /usr/include/stdio.h Xxscreen.o: /usr/include/X/Xlib.h /usr/include/X/mit-copyright.h Xxscreen.o: /usr/include/X/X.h /usr/include/X/mit-copyright.h Xxscreen.o: /usr/include/errno.h /usr/include/sys/types.h Xxinput.o: xinput.c ./externs.h ./constants.h /usr/include/stdio.h Xxinput.o: /usr/include/X/Xlib.h /usr/include/X/mit-copyright.h Xxinput.o: /usr/include/X/X.h /usr/include/X/mit-copyright.h Xxinput.o: /usr/include/errno.h /usr/include/sys/types.h /usr/include/ctype.h Xxinput.o: /usr/include/strings.h /usr/include/sys/signal.h Xxboard.o: xboard.c ./externs.h ./constants.h /usr/include/stdio.h Xxboard.o: /usr/include/X/Xlib.h /usr/include/X/mit-copyright.h Xxboard.o: /usr/include/X/X.h /usr/include/X/mit-copyright.h Xxboard.o: /usr/include/errno.h /usr/include/sys/types.h Xxmove.o: xmove.c ./externs.h ./constants.h /usr/include/stdio.h Xxmove.o: /usr/include/X/Xlib.h /usr/include/X/mit-copyright.h Xxmove.o: /usr/include/X/X.h /usr/include/X/mit-copyright.h /usr/include/errno.h Xxmove.o: /usr/include/sys/types.h Xxoutput.o: xoutput.c ./externs.h ./constants.h /usr/include/stdio.h Xxoutput.o: /usr/include/X/Xlib.h /usr/include/X/mit-copyright.h Xxoutput.o: /usr/include/X/X.h /usr/include/X/mit-copyright.h Xxoutput.o: /usr/include/errno.h /usr/include/sys/types.h /usr/include/strings.h END_OF_Makefile if test 9937 -ne `wc -c help <<'END_OF_help' X X X XKRIEGSPIEL(1) UNIX Programmer's Manual KRIEGSPIEL(1) X X X XNAME X kriegspiel - A Chess Variant X XSYNOPSIS X ks [{+-}[bwcaprsdh]] user[@machine] X xks [{+-}[bwcaprs]] [display] [=geometry] user[@machine] X XDESCRIPTION X _K_r_i_e_g_s_p_i_e_l is a chess variant in which each player cannot X see his opponents pieces. The computer acts as a judge for X two players. The rules of Kriegspiel are discussed at the X end of this document. X X The game must be invoked separately by two users. Various X options may be chosen in the command line; conflicting X options (such as if both players choose white) are resolved X with a flip of a coin. X X Moves may be specified in either algebraic or descriptive X notation. Most standard methods will work. For example, X all of the following are legal (and equivalent) for white's X first move: p-k4, p/k2-k4, e2-e4, e4, pe4. In descriptive X notation, use an 'x' for pawn takes (such as pxkb4), but do X not use an 'x' when taking using other pieces. Castling can X be done with o-o (king side) and o-o-o (queen side), or by X moving the king two squares. X X The other commands available are: X X resign I resign. X draw Offer a draw. X help Give examples of legal commands. X any Can I take with any of my pawns? X say _s_t_r_i_n_g Send message to opponent. X _C_o_n_t_r_o_l-_L Redraw the screen (when typed at any time). X X _X_k_s is an version of the game for the X window system. X Pieces are moved with the left mouse button. Other commands X are single letters on the keyboard. Type 'h' for help after X game starts. X X Under the default options, you will be informed of the fol- X lowing information when applicable: X (1) your opponent tries an illegal move X (2) you or your opponent is in check from the appropriate direction X (3) your piece is taken (but not your opponent's piece is taken) X (4) your opponent asks `any', and the response X X The game ends if either player is checkmated or stalemated, X if both players have insufficient material, if either player X resigns, if both players agree on a draw, or the game can X end due to hardware error. (But not if the same position X X X X2 May 1986 INTEGRATED SOLUTIONS 4.2 BSD 1 X X X X X X XKRIEGSPIEL(1) UNIX Programmer's Manual KRIEGSPIEL(1) X X X X comes up three times or if the game goes 50 consecutive X moves without a piece take or pawn capture, as in ordinary X chess). X X XOPTIONS X Some options preceded by a `-' will turn the option off. If X the players choose conflicting option, then the option will X be chosen by a flip of a coin. X X -w I wish to be white. Negated by opponent X choosing options `c' or `w' X -b I wish to be black. Negated by opponent X choosing options `c' or `b' X -c Force color to be chosen randomly. This is X the default if neither person chooses a X color. X [+-]a Announce to both players when a piece is X taken, revealing also whether it was a pawn X or a major piece that was taken. Also X announce if a pawn ever promotes. X [+-]p Announce to both players how many possible X ways the player to move can take with his X pawns (if he can at all). The player to move X can only try three moves which take with his X pawns. If, after exhausting these three X tries, the player's only legal move is to X take with his pawn, then the player is check- X mated or stalemated as appropriate. If the X player tries the same take twice, this will X not be counted against him. The `any' com- X mand is ignored under this option. X -r Reverse the direction from which algebraic X moves are accepted if I am black. (Thus, X e2-e4 on black's first move would move the X pawn in front of your king up two squares. X Without this option set, the move would be X entered as d7-d5 in algebaic) X -d Dumb terminal: Use this option if the graph- X ics don't seem to be working well. This may X help. X -h Print out this help file. X [+-]s Make me the server. This option should only X be used as a last resort. Invisibly to the X user, one player is the server, and one is X the client. These are usually chosen by the X program by a protocol. If you're having X troubles connecting with your opponent, then X try the following: One player invoke the X program with the `+s' option, and one with X the `-s' option. X _n A number between one and a thousand to be X X X X2 May 1986 INTEGRATED SOLUTIONS 4.2 BSD 2 X X X X X X XKRIEGSPIEL(1) UNIX Programmer's Manual KRIEGSPIEL(1) X X X X used as the port. This option should only be X used if you are having troubles connecting. X Both players should select the same number X between 1 and 1000 to be used to compute the X port on which they communicate. X XRULES X Kriegspiel is a chess variation dating back at least before X WWII. It requires three people: two players and a judge. X The players sit back to back, each with a board with only X their own pieces. The judge has a board between the X players, with the entire position. Each player in his turn X tries different moves. For each illegal move tried, the X judge says `illegal' aloud. If a player is put into check, X this fact is said out loud, along with the direction from X which he/she is in check: Check along the file, rank, short X diagonal, long diagonal (from the point of view of the X king), and knight. When the player makes a legal move, that X is the move he must play. X X Beyond this, the ammount of information the judge should X reveal is controversial. The author prefers the following. X If a piece is taken, the judge (quietly) removes the piece X from the injured party's board. On her/his turn, a person X may ask `any?', meaning `Are there any ways of taking any of X my opponent's pieces with any of my pawns?' The judge X answers aloud `yes' or `no', as appropriate. The reason X this rule is included is to speed up the game; otherwise X each player would try all possible pawn takes at the start X of each turn. The disadvantage with asking `any?' is that X the opponent also finds out the answer; the advantage is X that the player is under no obligation to actually take a X piece with one of his pawns, even if the answer is yes. X (Thus, he has gained information for free.) X X Some people prefer to play that takes are announced out X loud, along with whether the piece taken was a pawn or not, X allowing the players to have an idea how well their doing. X Furthermore, that it should be announced not only whether a X person has any available pawn tries, but also how many on X every move. This extra information, it is said, makes the X game less chaotic and random, and keeps it from becoming X like Battleship. However, the extra information is somewhat X tempered by the fact that a person may only try to take in X three different ways with his pawns, after which a pawn take X becomes illegal. X XAUTHOR X David Wolfe X XBUGS X There is no way of saving a game in progress. This is X X X X2 May 1986 INTEGRATED SOLUTIONS 4.2 BSD 3 X X X X X X XKRIEGSPIEL(1) UNIX Programmer's Manual KRIEGSPIEL(1) X X X X particularly frustrating if you are playing on an unreliable X network: If the network goes down, give it up... X X Other bugs, unknown. Please notify Steve Schoch X or David Wolfe X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X2 May 1986 INTEGRATED SOLUTIONS 4.2 BSD 4 X X X END_OF_help echo shar: 28 control characters may be missing from \"help\" if test 8601 -ne `wc -c input.c <<'END_OF_input.c' X#ifndef lint Xstatic char rcsid[] = "$Header: input.c,v 1.3 87/05/19 18:46:55 schoch Exp $"; X#endif X X#include "externs.h" X#include X#include X#include X Xchar instr [128]; Xstatic int opponent; X Xentermove (pstart, pend, color, pawntries) X int *pstart, *pend, color, pawntries; X{ X int i, readfds; X int counter = 0; X struct timeval timeout; X char c; X char *cp; X X timeout.tv_sec = (long int) 1; X timeout.tv_usec = (long int) 0; X wclear (win [OPPONENT]); X while (TRUE) { X drawok [color] = FALSE; X if (color == ourcolor) { X printf ("\007"); /* ring bell */ X if (drawok [1 - color]) { X waddstr (win [MESSAGE], "draw offered"); X wclear (win [MESSAGE]); X } X wclear (win [INPUT]); X waddstr (win [INPUT], ": "); X waddstr (win [PROMPT], "your move"); X i = 0; X while (TRUE) { X move (win [INPUT]->_cury + win [INPUT]->_begy, X win [INPUT]->_curx + win [INPUT]->_begx); X refresh (); X instr [i] = getchar (); X if (instr [i] == '\n' X || instr [i] == '\r') X break; X else if (instr [i] == '\f') { /* ^L */ X redraw(); X continue; X } else if (instr [i] == '\b' /* ^H */ X || instr [i] == '\177') { /* delete */ X if (i > 0) { X --i; X wmove( win [INPUT], X win [INPUT]->_cury, X win [INPUT]->_curx - 1); X wdelch (win [INPUT]); X } X continue; X } else if (instr [i] == '\030' /* ^X */ X || instr [i] == '\025') { /* ^U */ X wclear (win [INPUT]); X waddstr (win [INPUT], ": "); X i = 0; X continue; X } else if (isupper (instr [i])) X tolower (instr [i]); X wclear (win [LEGAL]); X if (isprint (instr [i])) X waddch (win [INPUT], instr [i++]); X } X instr [i] = '\000'; X wclear (win [INPUT]); X opponent = FALSE; X } else { X i = 0; X wclear (win [MESSAGE]); X waddstr (win [MESSAGE], X "waiting for\nopponent's\nmove"); X refresh (); X while (TRUE) { X readfds = 1 + (1 << fileno(inp)); X while (select (fileno(inp)+1, &readfds, (int *) X NULL, (int *) NULL, X &timeout) < 0) X if (errno != EINTR) X error ("select in entermove"); X if (! (readfds & (1 << fileno(inp)))) { X wclear (win [CLOCK]); X if (counter++ % 2 == 1) X waddch (win [CLOCK],'/'); X else X waddch (win [CLOCK],'\\'); X move (win [CLOCK]->_begy, X win [CLOCK]->_begx); X refresh(); X if (readfds & 1) { X c = getch(); X if (c == '\f' /* ^L */) X redraw(); X } X } X else X break; X wclear (win [LEGAL]); X } X wclear (win [LEGAL]); X if (fgets(instr, sizeof instr, inp) == NULL) { X if (ferror(inp)) X error("read in entermove"); X dead = TRUE; X if (state == PLAYING) X state = OVER; X } else { X if (cp = index(instr, '\n')) X *cp = '\0'; X if (cp = index(instr, '\r')) X *cp = '\0'; X } X opponent = TRUE; X } X wclear (win [PROMPT]); X *pstart = *pend = 0; X if (!strcmp (instr, "draw")) { X drawok [color] = TRUE; X if (!opponent) X fputs("draw\r\n", out); X break; X } else if (!strcmp (instr, "resign")) { X resign = TRUE; X state = OVER; X if (!opponent) X fputs("resign\r\n", out); X break; X } else if (drawok [1 - color]) { X if (!strcmp (instr, "yes")) { X drawok [color] = TRUE; X state = OVER; X if (!opponent) X fputs("yes\r\n", out); X break; X } else if (!strcmp (instr, "no")) { X if (ourcolor != color) X waddstr (win[MESSAGE], "draw refused"); X if (!opponent) X fputs("no\r\n", out); X break; X } else { X wclear (win [MESSAGE]); X waddstr (win [MESSAGE], X "draw offered\ntype yes or no\n"); X } X } else if (!strcmp (instr, "o-o-o") X && kingloc [color] % 10 == 5) { X *pstart = kingloc [color]; X *pend = kingloc [color] - 2; X if (!opponent) X send_move(*pstart, *pend); X break; X } else if (!strcmp (instr, "o-o") X && kingloc [color] % 10 == 5) { X *pstart = kingloc [color]; X *pend = kingloc [color] + 2; X if (!opponent) X send_move(*pstart, *pend); X break; X } else if ((!strncmp (instr, "help", 4) || !strcmp (instr,"")) X && color == ourcolor) { X wclear (win [MESSAGE]); X waddstr (win [MESSAGE], X "eg. qe4, p-k4\npxkb3, o-o-o\n"); X waddstr (win [MESSAGE], X "draw, resign\nsay you'll lose"); X } else if (!strncmp (instr, "say", 3)) { X if (opponent) { X wclear (win [OPPONENT]); X waddstr (win [OPPONENT], "message:\n"); X waddstr (win [OPPONENT], instr + 3); X waddch (win [OPPONENT], '\n'); X } else X fprintf(out, "say %s\r\n", instr+3); X } else if ((!option [ANNOUNCEPAWNS]) X && (!strcmp (instr, "any"))) X if (pawntries) X waddstr (win [PAWNTRIES], "pawntries\r"); X else X waddstr (win [PAWNTRIES], "no pawntries\r"); X else { X if ((i = parse_algebraic_move(pstart,pend,color)) X == NOWAY) X i = parse_descriptive_move (pstart,pend,color); X if (i == TRUE) { X if (!opponent) X send_move(*pstart, *pend); X break; X } else X illegal (i, color); X } X } X} X X#define boardpos(col, row) ((9 - (row)) * 10 + (col)) X#define RIGHT_SIDE 2 X#define RIGHT_FILE 1 X X/* parse an algebraic move (e2-e4), and return TRUE for non error */ X/* opponent is true if this move is from the opponent. Moves set across X * the network are standardized whether reverse is set or not. */ Xparse_algebraic_move (pstart, pend, color) X int *pstart, *pend, color; X{ X int foundpiece = FALSE, i, j, piece, spot; X LIST piecemoves (), lmember (); X X if (strlen (instr) == 5) X if (instr [0] >= 'a' && instr [0] <= 'h' X && instr [1] >= '1' && instr [1] <= '8' X && instr [3] >= 'a' && instr [3] <= 'h' X && instr [4] >= '1' && instr [4] <= '8') { X *pstart = boardpos (instr[0]-'a'+1, instr[1]-'0'); X *pend = boardpos (instr[3]-'a'+1, instr[4]-'0'); X if (reverse && !opponent) { X *pstart = 99 - *pstart; X *pend = 99 - *pend; X } X return TRUE; X } else X X return NOWAY; X else if (strlen (instr) == 4) X if (instr [0] >= 'a' && instr [0] <= 'h' X && instr [1] >= '1' && instr [1] <= '8' X && instr [2] >= 'a' && instr [2] <= 'h' X && instr [3] >= '1' && instr [3] <= '8') { X *pstart = boardpos (instr[0]-'a'+1, instr[1]-'0'); X *pend = boardpos (instr[2]-'a'+1, instr[3]-'0'); X if (reverse && !opponent) { X *pstart = 99 - *pstart; X *pend = 99 - *pend; X } X return TRUE; X } else X X return NOWAY; X else if (strlen (instr) == 2) { X if (instr [0] < 'a' || instr [0] > 'h') X return NOWAY; X else if (instr [1] >= 'a' && instr [1] <= 'h') { X /* pawn take */ X for (i = 2; i <= 7 ; i++) { X spot = boardpos (instr[0]-'a'+1, i); X if (reverse && !opponent) X spot = 99 - spot; X if (whose [spot] == color X && occupant [spot] == PAWN) X if (foundpiece) X return AMBIGUOUS; X else X foundpiece = spot; X } X if (foundpiece) { X *pstart = foundpiece; X if (reverse && !opponent) X *pend = boardpos ('i'-instr[1], X 9 - foundpiece / 10) X + pawndir [color]; X else X *pend = boardpos (instr[1]-'a'+1, X 9 - foundpiece / 10) X + pawndir [color]; X return TRUE; X } else X return NOWAY; X } else if (instr [1] >= '1' && instr [1] <= '8') { X /* pawn move */ X *pend = boardpos (instr[0]-'a'+1, instr[1]-'0'); X if (reverse && !opponent) X *pend = 99 - *pend; X if (((ourcolor == BLACK) && (*pend <= 28)) X || ((ourcolor == WHITE) && (*pend >= 71))) X return NOWAY; X if ((whose [*pstart= *pend - pawndir [color]] == color X && occupant [*pstart] == PAWN) X || (whose [*pstart= *pstart - pawndir [color]] == color X && occupant [*pstart] == PAWN)) X return TRUE; X else X return NOWAY; X } else X return NOWAY; X } else if (strlen (instr) == 3) { /* eg. nc6 */ X if ((piece = piecetype(instr [0])) == ILLEGAL_PIECE) X return NOWAY; X if (instr [1] < 'a' || instr [1] > 'h' X || instr [2] < '0' || instr [2] >'h') X return NOWAY; X *pend = boardpos (instr [1] - 'a' + 1, instr [2] - '0'); X if (reverse && !opponent) X *pend = 99 - *pend; X for (i = 1; i <= 8; i++) { X for (j = 1; j <= 8; j++) { X *pstart = boardpos (i, j); X if (whose [*pstart] != color X || occupant [*pstart] != piece X || !lmember (*pend, piecemoves(*pstart,TRUE))) X continue; X if (foundpiece) X return AMBIGUOUS; X foundpiece = *pstart; X } X } X if (*pstart = foundpiece) X return TRUE; X else X return NOWAY; X } X return NOWAY; /* shoud never be reached */ X} X X/* parse a descriptive move (n-kb3), return TRUE for non error */ Xparse_descriptive_move (pstart, pend, color) X int *pstart, *pend, color; X{ X char *sfrom, *sto, *alloca(), *index(), *afterslash; X int nlegalbyfile = 0, nlegalbyside = 0, fromlegal = 0, frombyfile X , frombyside, pawntake = FALSE, piece; X LIST tryto, targets, piecemoves (); X int i, j, spot, tobyfile, tobyside; X struct { X int row; X int col; X int goodness; X } xfrom[100]; X X /* sfrom is from string, sto is to string */ X sfrom = alloca (strlen (instr) + 1); X strcpy(sfrom, instr); X if ((sto = index (sfrom, '-')) == NULL) X if ((sto = index (sfrom, 'x')) != NULL) X pawntake = TRUE; X else X return NOWAY; X *sto++ = '\0'; X if ((afterslash = index (sfrom, '/')) != NULL) X *afterslash++ = '\0'; X if ((piece = piecetype(sfrom [strlen (sfrom) - 1])) == ILLEGAL_PIECE) X return NOWAY; X pawntake = pawntake && piece == PAWN; X sfrom [strlen (sfrom) - 1] = '\0'; X X /* build a list of legal from moves */ X for (i = 1; i <= 8; i++) { X for (j = 1; j <= 8; j++) { X spot = (9 - i) * 10 + j; X if (whose [spot] != color) X continue; X if (occupant [spot] != piece) X continue; X xfrom [fromlegal].goodness = RIGHT_FILE; X if (afterslash) { X switch (xfrom [fromlegal].goodness X = matchpos(afterslash, spot, color)) { X case FALSE: X continue; X case ILLEGAL: X return NOWAY; X case RIGHT_SIDE: X case RIGHT_FILE: X break; X } X } X if (*sfrom) { X switch (xfrom [fromlegal].goodness X = matchpos(sfrom, spot, color)) { X case FALSE: X continue; X case ILLEGAL: X return NOWAY; X case RIGHT_SIDE: X case RIGHT_FILE: X break; X } X } X xfrom[fromlegal].row = i; X xfrom[fromlegal].col = j; X fromlegal++; X } X } X X /* find all the consistent 'to' moves for those 'from' moves */ X for (i = 0; i < fromlegal; i++) { X spot = (9 - xfrom [i].row) * 10 + xfrom [i].col; X targets = piecemoves (spot, TRUE); X for (tryto = targets; tryto != NULL; tryto = tryto->n) { X switch (matchpos(sto, tryto->i, color)) { X case RIGHT_FILE: X if (xfrom [i].goodness == RIGHT_FILE) { X if (piece == PAWN X && pawntake == ((tryto->i % 10) X == (xfrom[i].col))) X continue; X frombyfile = i; X tobyfile = tryto -> i; X nlegalbyfile++; X } X /* fall through */ X case RIGHT_SIDE: X if (piece == PAWN X && pawntake X == ((tryto->i % 10) == (xfrom[i].col))) X continue; X frombyside = i; X tobyside = tryto -> i; X nlegalbyside++; X break; X case FALSE: X continue; X case ILLEGAL: X return NOWAY; X } X } X } X X /* complain if there are too many or if there are none */ X if (nlegalbyside != 1 && nlegalbyfile != 1) { X if (nlegalbyside > 1) X return AMBIGUOUS; X else X return NOWAY; X } X X if (nlegalbyside == 1) { X /* frombyside and tobyside now define the unique legal move */ X *pstart = (9 - xfrom[frombyside].row) * 10 X + xfrom[frombyside].col; X *pend = tobyside; X } else if (nlegalbyfile == 1) { X /* frombyfile and tobyfile now define the unique legal move */ X *pstart = (9 - xfrom[frombyfile].row) * 10 X + xfrom[frombyfile].col; X *pend = tobyfile; X } X return TRUE; X} X X/* matchpos -- tells whether a square number matches the description X desc is of the form b4 or qb4 or just b or 4 */ Xstatic Xmatchpos(desc, squareno, color) X char *desc; X int squareno, color; X{ X static char *piececol = "rnbqkbnr"; X char side = FALSE, piece, rownum; X int row, col; X X /* get row and col with player's king on (4,1) */ X /* (black's board is reflected) */ X row = 9 - squareno / 10; X col = squareno % 10; X if (color == BLACK) X row = 9 - row; X X if (desc [0] == 'k' || desc [0] == 'q') { X side = desc [0]; X if (!isdigit(desc[1])) X desc++; X } X if (isalpha (desc [0])) { X piece = desc [0]; X desc++; X } else X piece = side; X if (rownum = isdigit (desc [0])) X rownum = desc++ [0]; X if (( piece && index(piececol, piece) == NULL) X || ( rownum && index("12345678", rownum) == NULL) X || desc [0] != '\0') X return ILLEGAL; X else if ((side == 'k' && col <= 4) || (side == 'q' && col >= 5) X || (rownum && row != rownum - '0') X || (piece && piececol [col - 1] != piece)) X return FALSE; X else if (side && !piece && piececol [col - 1] != side) X return RIGHT_SIDE; /* eg. b/q-n2 when b is on queen side */ X else X return RIGHT_FILE; /* eg. b/q-n2 when b is in queen file */ X} X Xstatic piecetype(letter) X char letter; X{ X switch (letter) { X case 'p': X return PAWN; X case 'r': X return ROOK; X case 'n': X return KNIGHT; X case 'b': X return BISHOP; X case 'q': X return QUEEN; X case 'k': X return KING; X default: X return ILLEGAL_PIECE; X } X} X X/* X * Send the move to the opponent */ Xsend_move(from, to) X{ X fprintf(out, "%1c%1d-%1c%1d\r\n", from%10-1+'a', 9-from/10, X to%10-1+'a', 9-to/10); X} END_OF_input.c if test 13117 -ne `wc -c pawntries.c <<'END_OF_pawntries.c' X#ifndef lint Xstatic char rcsid[] = "$Header: pawntries.c,v 1.3 87/02/12 13:23:56 schoch Exp $"; X#endif X X/* "pawntries.c */ X#include "externs.h" X Xcountpawntries (color) Xu_char color; X{ X LIST l, moves, piecemoves (); X int tries, /* move,*/ start, end; X X tries = 0; X l = piecelocs [color]; X while (l != NIL) { X start = l->i; X l = l->n; X if (occupant [start] != PAWN) X continue; X moves = piecemoves (start, FALSE); X while (moves != NIL) { X end = moves->i; X moves = moves->n; X if (start % 10 == end % 10) X continue; X if (moveintocheck (start, end)) X continue; X tries++; X } X } X return tries; X} X X Xfindvictim (from, to) X int from, to; X{ X if (occupant [from] == PAWN) { X if (from % 10 == to % 10) X return FALSE; X if (whose [to] == 1 - whose [from]) X return to; X else X return (to - pawndir [whose [from]]); /* en passent */ X } else { X if (whose [to] == 1 - whose[from]) X return to; X else X return FALSE; X } X} END_OF_pawntries.c if test 938 -ne `wc -c xinput.c <<'END_OF_xinput.c' X#ifndef lint Xstatic char rcsid[] = "$Header: xinput.c,v 1.8 87/05/19 18:46:30 schoch Exp $"; X#endif X X#include "externs.h" X#include X#include X#include X Xbool note_on; Xbool isiconic; X Xhandle_input() X{ X XEvent event; X XKeyOrButtonEvent *ke; X static x = -1, y = -1; X static pos = -1; X char *cp; X auto int n; X X XNextEvent(&event); X switch (event.type) { X case ExposeWindow: X case ExposeRegion: X if (event.window == iconwindow) { X redraw_icon(color == ourcolor); X isiconic = TRUE; X } else { X if (event.type == ExposeRegion) { X XExposeRegionEvent *xe = (XExposeRegionEvent *)&event; X X redraw_region(xe->x, xe->y, xe->width, xe->height); X } else X redraw(); X isiconic = FALSE; X } X break; X X case ButtonPressed: X ke = (XKeyOrButtonEvent *)&event; X switch(ke->detail & 0xff) { X case RightButton: X break; X case MiddleButton: X break; X case LeftButton: X x = ke->x; y = ke->y; X pos = xytopos(x, y); X startmove(pos, x, y); X break; X default: X printf("Unknown Button pressed.\n"); X break; X } X break; X case ButtonReleased: X ke = (XKeyOrButtonEvent *)&event; X switch(ke->detail & 0xff) { X case LeftButton: X if (move) X stopmove(pos, x, y); X break; X } X break; X X case LeaveWindow: X if (pos == -1) X break; X pos = -1; X if (move) X stopmove(pos, x, y); X x = -1; X y = -1; X break; X X case MouseMoved: X ke = (XKeyOrButtonEvent *)&event; X pos = xytopos(ke->x, ke->y); X if (move) X piecemove(x, y, ke->x, ke->y); X x = ke->x; y = ke->y; X break; X X case KeyPressed: X ke = (XKeyOrButtonEvent *)&event; X cp = XLookupMapping(ke, &n); X key_func(cp, n); X break; X X default: X fprintf(stderr, "Unknown event type %d\n", event.type); X break; X } X} X Xhandle_sock() X{ X char instr[BUFSIZ]; X char *cp; X int pstart, pend, i; X X if (fgets(instr, sizeof instr, inp) == NULL) { X message("Connection closed.", MESSAGE); X dead = 1; X state = OVER; X return 1; X } X if (cp = index(instr, '\n')) X *cp = '\0'; X if (cp = index(instr, '\r')) X *cp = '\0'; X i = parse_move(&pstart, &pend, theircolor, instr); X if (i < 0) /* Message */ X return 0; X if (i != TRUE) X pstart = pend = 0; X if (movetry(pstart, pend, theircolor) == 0) { X XFeep(0); X if (isiconic) X flash_icon(); X } X return 0; X} X X/* Takes window coordinates and returns a board position from 0-99. X * returns -1 if point is not on board. */ Xxytopos(x, y) X{ X x += 64; y += 64-TOPSPACE; X if (y < 0 || x < 0) X return -1; X x /= 64; X y /= 64; X if (x > 9 || y > 9) X return -1; X if (reverse) { X y = 9 - y; X x = 9 - x; X } X return (y * 10) + x; X} X Xparse_move(pstart, pend, color, instr) Xint *pstart, *pend; Xu_char color; Xchar *instr; X{ X char buf[BUFSIZ]; X extern pawntries; /* in xmovetry.c */ X X if (!strcmp (instr, "draw")) { X drawok [color] = TRUE; X return FALSE; X } X if (!strcmp (instr, "resign")) { X resign = TRUE; X return FALSE; X } X if (drawok [1 - color]) { X if (!strcmp (instr, "yes")) { X drawok [color] = TRUE; X } else if (!strcmp (instr, "no")) { X ; X } else { X printf("error: should get yes or no.\n"); X } X return FALSE; X } X if (!strncmp (instr, "say", 3)) { X sprintf(buf, "%s:%s", colorname[color], instr+3); X if (note_on) X message(buf, CHECK); X else X message(buf, MESSAGE); X return -1; X } X if ((!option [ANNOUNCEPAWNS]) X && (!strcmp (instr, "any"))) { X if (pawntries) X message ("pawntries", PAWNTRIES); X else X message ("no pawntries", PAWNTRIES); X return -1; X } X if (parse_algebraic_move(pstart,pend,instr) == TRUE) X return TRUE; X X printf("Invalid input: %s\n", instr); X return FALSE; X} X X#define boardpos(col, row) ((9 - (row)) * 10 + (col)) X#define RIGHT_SIDE 2 X#define RIGHT_FILE 1 X X/* parse an algebraic move (e2-e4), and return TRUE for non error */ Xparse_algebraic_move (pstart, pend, instr) X int *pstart, *pend; Xchar *instr; X{ X X if (instr[2] != '-') X return FALSE; X if (instr [0] >= 'a' && instr [0] <= 'h' X && instr [1] >= '1' && instr [1] <= '8' X && instr [3] >= 'a' && instr [3] <= 'h' X && instr [4] >= '1' && instr [4] <= '8') { X *pstart = boardpos (instr[0]-'a'+1, instr[1]-'0'); X *pend = boardpos (instr[3]-'a'+1, instr[4]-'0'); X return TRUE; X } else X return FALSE; X} X Xkey_func(s, n) Xchar *s; X{ X if (n == 0) X return; X if (note_on) { X if (do_note(s, n)) X note_on = 0; X return; X } X switch(*s) { X case 'r': X case 'R': X replay(); X break; X case 's': X case 'S': X stop_replay(); X break; X case 'd': X case 'D': X draw(); X break; X case 'q': X case 'Q': X do_resign(); X break; X case 'y': X case 'Y': X yes(); X break; X case 'n': X case 'N': X no(); X break; X case 'm': X case 'M': X send_note(s, n); X break; X case 'x': X case 'X': X xit(); X break; X case 'a': X case 'A': X any(); X break; X case '?': X case 'h': X case 'H': X help(); X break; X } X} X Xsend_note(s, n) Xchar *s; X{ X if (dead) { X message("Your opponent is gone.", MESSAGE); X return; X } X note_on = TRUE; X s++; n--; X start_note(); X if (n > 0) X if (do_note(s, n)) X note_on = 0; X} X Xdraw() X{ X if (state != PLAYING) { X message("The game is over!", MESSAGE); X return; X } X if (color != ourcolor) { X message("Wait for your turn.", MESSAGE); X return; X } X drawok[ourcolor] = TRUE; X fputs("draw\r\n", out); X movetry(0, 0, ourcolor); X} X Xyes() X{ X if (state != PLAYING) { X message("The game is over!", MESSAGE); X return; X } X if (drawok[theircolor] != TRUE) X return; X drawok[ourcolor] = TRUE; X fputs("yes\r\n", out); X movetry(0, 0, ourcolor); X} X Xno() X{ X if (state != PLAYING) { X message("The game is over!", MESSAGE); X return; X } X if (drawok[theircolor] != TRUE) X return; X drawok[ourcolor] = FALSE; X fputs("no\r\n", out); X movetry(0, 0, ourcolor); X} X Xdo_resign() X{ X if (state != PLAYING) { X message("The game is over!", MESSAGE); X return; X } X fputs("resign\r\n", out); X resign = TRUE; X movetry(0, 0, ourcolor); X} X Xxit() X{ X if (state == PLAYING) { X message("Type Q (resign) or D (draw) first.", MESSAGE); X return; X } X exit(0); X} X Xhelp() X{ X if (state == REVIEW) X message("Type S (stop review), X (exit), or M (message)", MESSAGE); X else if (state == OVER) X message("Type R (review), or X (exit), or M (message)", MESSAGE); X else if (drawok[theircolor] && !drawok[ourcolor]) X message("Type Y (accept draw), N (no), or M (message)", MESSAGE); X else X message("Type Q (resign), D (draw), or M (message)", MESSAGE); X} X Xreplay() X{ X if (state == PLAYING) { X message("You have to resign first!", MESSAGE); X } else X review(); X} X Xany() X{ X if (state != PLAYING) { X message("The game is over!", MESSAGE); X return; X } X if (color != ourcolor) { X message("It's not your turn.", MESSAGE); X return; X } X if (option[ANNOUNCEPAWNS]) { X message("The \"announce pawntries\" option is on!", MESSAGE); X return; X } X if (pawntries) X message ("pawntries", PAWNTRIES); X else X message ("no pawntries", PAWNTRIES); X fputs("any\r\n", out); X} X Xstop_replay() X{ X if (state == REVIEW) X state = OVER; X} X Xflash_icon() X{ X onalrm(SIGALRM); X} X Xonalrm(sig) X{ X static reverse = FALSE; X X if (color != ourcolor || !isiconic) { X reverse = FALSE; X return; X } X signal(sig, onalrm); X reverse = !reverse; X redraw_icon(reverse); X alarm(1); X} END_OF_xinput.c if test 7456 -ne `wc -c xscreen.c <<'END_OF_xscreen.c' X#ifndef lint Xstatic char rcsid[] = "$Header: xscreen.c,v 1.7 87/05/19 18:46:22 schoch Exp $"; X#endif X X#include "externs.h" X Xstatic Pixmap white, black; Xstatic FontInfo info; X X#define tile_width 64 X#define tile_height 64 Xstatic short white_bits[] = { X 0xdddd, 0xdddd, 0xdddd, 0xdddd, X 0xeeee, 0xeeee, 0xeeee, 0xeeee, X 0xbbbb, 0xbbbb, 0xbbbb, 0xbbbb, X 0x7777, 0x7777, 0x7777, 0x7777, X 0xdddd, 0xdddd, 0xdddd, 0xdddd, X 0xeeee, 0xeeee, 0xeeee, 0xeeee, X 0xbbbb, 0xbbbb, 0xbbbb, 0xbbbb, X 0x7777, 0x7777, 0x7777, 0x7777, X 0xdddd, 0xdddd, 0xdddd, 0xdddd, X 0xeeee, 0xeeee, 0xeeee, 0xeeee, X 0xbbbb, 0xbbbb, 0xbbbb, 0xbbbb, X 0x7777, 0x7777, 0x7777, 0x7777, X 0xdddd, 0xdddd, 0xdddd, 0xdddd, X 0xeeee, 0xeeee, 0xeeee, 0xeeee, X 0xbbbb, 0xbbbb, 0xbbbb, 0xbbbb, X 0x7777, 0x7777, 0x7777, 0x7777, X 0xdddd, 0xdddd, 0xdddd, 0xdddd, X 0xeeee, 0xeeee, 0xeeee, 0xeeee, X 0xbbbb, 0xbbbb, 0xbbbb, 0xbbbb, X 0x7777, 0x7777, 0x7777, 0x7777, X 0xdddd, 0xdddd, 0xdddd, 0xdddd, X 0xeeee, 0xeeee, 0xeeee, 0xeeee, X 0xbbbb, 0xbbbb, 0xbbbb, 0xbbbb, X 0x7777, 0x7777, 0x7777, 0x7777, X 0xdddd, 0xdddd, 0xdddd, 0xdddd, X 0xeeee, 0xeeee, 0xeeee, 0xeeee, X 0xbbbb, 0xbbbb, 0xbbbb, 0xbbbb, X 0x7777, 0x7777, 0x7777, 0x7777, X 0xdddd, 0xdddd, 0xdddd, 0xdddd, X 0xeeee, 0xeeee, 0xeeee, 0xeeee, X 0xbbbb, 0xbbbb, 0xbbbb, 0xbbbb, X 0x7777, 0x7777, 0x7777, 0x7777, X 0xdddd, 0xdddd, 0xdddd, 0xdddd, X 0xeeee, 0xeeee, 0xeeee, 0xeeee, X 0xbbbb, 0xbbbb, 0xbbbb, 0xbbbb, X 0x7777, 0x7777, 0x7777, 0x7777, X 0xdddd, 0xdddd, 0xdddd, 0xdddd, X 0xeeee, 0xeeee, 0xeeee, 0xeeee, X 0xbbbb, 0xbbbb, 0xbbbb, 0xbbbb, X 0x7777, 0x7777, 0x7777, 0x7777, X 0xdddd, 0xdddd, 0xdddd, 0xdddd, X 0xeeee, 0xeeee, 0xeeee, 0xeeee, X 0xbbbb, 0xbbbb, 0xbbbb, 0xbbbb, X 0x7777, 0x7777, 0x7777, 0x7777, X 0xdddd, 0xdddd, 0xdddd, 0xdddd, X 0xeeee, 0xeeee, 0xeeee, 0xeeee, X 0xbbbb, 0xbbbb, 0xbbbb, 0xbbbb, X 0x7777, 0x7777, 0x7777, 0x7777, X 0xdddd, 0xdddd, 0xdddd, 0xdddd, X 0xeeee, 0xeeee, 0xeeee, 0xeeee, X 0xbbbb, 0xbbbb, 0xbbbb, 0xbbbb, X 0x7777, 0x7777, 0x7777, 0x7777, X 0xdddd, 0xdddd, 0xdddd, 0xdddd, X 0xeeee, 0xeeee, 0xeeee, 0xeeee, X 0xbbbb, 0xbbbb, 0xbbbb, 0xbbbb, X 0x7777, 0x7777, 0x7777, 0x7777, X 0xdddd, 0xdddd, 0xdddd, 0xdddd, X 0xeeee, 0xeeee, 0xeeee, 0xeeee, X 0xbbbb, 0xbbbb, 0xbbbb, 0xbbbb, X 0x7777, 0x7777, 0x7777, 0x7777, X 0xdddd, 0xdddd, 0xdddd, 0xdddd, X 0xeeee, 0xeeee, 0xeeee, 0xeeee, X 0xbbbb, 0xbbbb, 0xbbbb, 0xbbbb, X 0x7777, 0x7777, 0x7777, 0x7777}; X Xstatic short black_bits[] = { X 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, X 0x5555, 0x5555, 0x5555, 0x5555, X 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, X 0x5555, 0x5555, 0x5555, 0x5555, X 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, X 0x5555, 0x5555, 0x5555, 0x5555, X 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, X 0x5555, 0x5555, 0x5555, 0x5555, X 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, X 0x5555, 0x5555, 0x5555, 0x5555, X 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, X 0x5555, 0x5555, 0x5555, 0x5555, X 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, X 0x5555, 0x5555, 0x5555, 0x5555, X 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, X 0x5555, 0x5555, 0x5555, 0x5555, X 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, X 0x5555, 0x5555, 0x5555, 0x5555, X 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, X 0x5555, 0x5555, 0x5555, 0x5555, X 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, X 0x5555, 0x5555, 0x5555, 0x5555, X 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, X 0x5555, 0x5555, 0x5555, 0x5555, X 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, X 0x5555, 0x5555, 0x5555, 0x5555, X 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, X 0x5555, 0x5555, 0x5555, 0x5555, X 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, X 0x5555, 0x5555, 0x5555, 0x5555, X 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, X 0x5555, 0x5555, 0x5555, 0x5555, X 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, X 0x5555, 0x5555, 0x5555, 0x5555, X 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, X 0x5555, 0x5555, 0x5555, 0x5555, X 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, X 0x5555, 0x5555, 0x5555, 0x5555, X 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, X 0x5555, 0x5555, 0x5555, 0x5555, X 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, X 0x5555, 0x5555, 0x5555, 0x5555, X 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, X 0x5555, 0x5555, 0x5555, 0x5555, X 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, X 0x5555, 0x5555, 0x5555, 0x5555, X 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, X 0x5555, 0x5555, 0x5555, 0x5555, X 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, X 0x5555, 0x5555, 0x5555, 0x5555, X 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, X 0x5555, 0x5555, 0x5555, 0x5555, X 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, X 0x5555, 0x5555, 0x5555, 0x5555, X 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, X 0x5555, 0x5555, 0x5555, 0x5555, X 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, X 0x5555, 0x5555, 0x5555, 0x5555, X 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, X 0x5555, 0x5555, 0x5555, 0x5555, X 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, X 0x5555, 0x5555, 0x5555, 0x5555, X 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, X 0x5555, 0x5555, 0x5555, 0x5555}; X X Xscreen_init() X{ X Bitmap bm; X X bm = XStoreBitmap(tile_width, tile_height, white_bits); X white = XMakePixmap(bm, WhitePixel, BlackPixel); X XFreeBitmap(bm); X bm = XStoreBitmap(tile_width, tile_height, black_bits); X black = XMakePixmap(bm, WhitePixel, BlackPixel); X XFreeBitmap(bm); X XQueryFont(font, &info); X} X Xredraw() X{ X int i, j; X Pixmap tile; X X for (i = 0; i <= 8; i++) X XLine(window, i*64, TOPSPACE, i*64, 64*8+TOPSPACE, X 1, 1, BlackPixel, GXcopy, 1); X for (i = 0; i <= 8; i++) X XLine(window, 0, i*64+TOPSPACE, 64*8, i*64+TOPSPACE, X 1, 1, BlackPixel, GXcopy, 1); X for (i = 0; i < 8; i++) X for (j = 0; j < 8; j++) { X if ((i + j) & 1) X tile = black; X else X tile = white; X XPixmapPut(window, 1, 1, i*64+1, j*64+1+TOPSPACE, 63, 63, tile, GXcopy, 1); X } X redraw_pieces(); X redraw_message(0); X XFlush(); X} X Xredraw_region(x, y, width, height) X{ X int pos; X register tx, ty; X register endx, endy; X X endy = y+height; X endx = x+width; X if (y < TOPSPACE-64) { X redraw_message(1); X y = TOPSPACE-64; X } X if (endy >= TOPSPACE+64*9) { X redraw_message(2); X endy = TOPSPACE+64*9; X } X /* WARNING! Magic numbers present! */ X endy = (endy-18+63 & ~63) + 18; X endx = (endx+63) & ~63; X if (y < TOPSPACE) { /* Do captured pieces */ X tx = (x+width+31) / 32; X for(ty = (x / 64) * 2; ty < tx; ty += 2) X redraw_captured(reverse ? ty + 16 : ty); X for(ty = x < 32 ? 1 : x / 32 - 1 | 1; ty < tx; ty += 2) X redraw_captured(reverse ? ty + 16 : ty); X } X if (endy > TOPSPACE+64*8) { X pos = x / 32; X tx = (x+width+31) / 32; X for(ty = (x / 64) * 2; ty < tx; ty += 2) X redraw_captured(reverse ? ty : ty + 16); X for(ty = x < 32 ? 1 : x / 32 - 1 | 1; ty < tx; ty += 2) X redraw_captured(reverse ? ty : ty + 16); X } X for (ty = y; ty < endy; ty += 64) X for (tx = x; tx < endx; tx += 64) { X pos = xytopos(tx, ty); X if (pos < 0 || whose[pos] == OFFBOARD) X continue; X redraw_pos(pos); X if (state == PLAYING && ghost[pos]) X redraw_ghost(pos); X else if (whose[pos] == ourcolor || X (state != PLAYING && whose[pos] != EMPTY)) X redraw_piece(pos); X } X} X Xredraw_pos(pos) X{ X int x, y; X Pixmap tile; X X if (reverse) { X x = 8-pos%10; X y = 8-pos/10; X } else { X x = pos%10-1; X y = pos/10-1; X } X if (whose[pos] == OFFBOARD) { /* Captured area */ X XPixSet(window, x*64+1, y*64+1+TOPSPACE, 64, 64, BlackPixel); X return; X } X if ((x+y) & 1) X tile = black; X else X tile = white; X XPixmapPut(window, 1, 1, x*64+1, y*64+1+TOPSPACE, 63, 63, tile, GXcopy, 1); X} X Xstatic struct w { X int x, y, len; X char buf[128]; X} w[] = X{ { 0, 0, 48}, /* MESSAGE */ X { 0, 64*9+1+TOPSPACE, 48}, /* CHECK */ X { 0, 64*9+1+TOPSPACE+18, 24}, /* LEGAL */ X { 64*4,64*9+1+TOPSPACE+18, 24}, /* CAPTURE */ X { 0, 64*9+1+TOPSPACE+18*2, 24}, /* TOMOVE */ X { 64*4,64*9+1+TOPSPACE+18*2, 24}, /* PAWNTRIES */ X}; X Xmessage(line, where) Xchar *line; X{ X char blank[80]; X X strncpy(blank, line, sizeof blank); X line = blank + strlen(blank); X while (line < &blank[sizeof blank]) X *line++ = ' '; X *--line = '\0'; X strcpy(w[where].buf, blank); X XText(window, w[where].x, w[where].y, blank, w[where].len, X font, WhitePixel, BlackPixel); X} X Xmclear(where) X{ X char blank[80]; X char *cp = blank; X X while (cp < &blank[sizeof blank]) X *cp++ = ' '; X *--cp = '\0'; X strcpy(w[where].buf, blank); X XText(window, w[where].x, w[where].y, blank, w[where].len, X font, WhitePixel, BlackPixel); X} X X/* which is 0 for all, 1 for stuff on top, and 2 for messages on bottom */ Xredraw_message(which) X{ X register struct w *m; X X if (which) X switch (which) { X case 1: X m = w; X XText(window, m->x, m->y, m->buf, m->len, X font, WhitePixel, BlackPixel); X return; X case 2: X for (m = &w[1]; m < &w[sizeof w / sizeof (struct w)]; m++) X XText(window, m->x, m->y, m->buf, m->len, X font, WhitePixel, BlackPixel); X return; X } X for (m = w; m < &w[sizeof w / sizeof (struct w)]; m++) { X XText(window, m->x, m->y, m->buf, m->len, X font, WhitePixel, BlackPixel); X } X} X Xstatic char *nextchar; X#define start_char (&w[MESSAGE].buf[9]) X#define end_char (&w[MESSAGE].buf[sizeof (w[MESSAGE].buf) - 1]) X Xstart_note() X{ X message("Message:", MESSAGE); X nextchar = start_char; X} X Xdo_note(s, n) Xchar *s; X{ X char c; X X while (n-- > 0) { X switch(*s) { X case '\b': X case '\0177': /* DELETE */ X if (nextchar > start_char) { X nextchar--; X put_char(' '); X } X break; X X case '\027': /* Control-W */ X c = *nextchar; X while (nextchar > start_char && c == ' ') { X c = *nextchar--; X put_char(' '); X } X while (nextchar > start_char && c != ' ') { X c = *nextchar--; X put_char(' '); X } X break; X X case '\030': /* control-X */ X case '\025': /* control-U */ X while (nextchar > start_char) { X nextchar--; X put_char(' '); X } X break; X X case '\n': X case '\r': X *nextchar = '\0'; X fprintf(out, "say %s\r\n", start_char); X return TRUE; X X case '\t': /* Tab */ X *s = ' '; X /* FALLTHROUGH */ X default: X if (*s < ' ') X continue; X if (nextchar >= end_char) X continue; X put_char(*s); X *nextchar++ = *s; X break; X X } X s++; X } X return FALSE; X} X Xput_char(c) Xchar c; X{ X register struct w *m = &w[MESSAGE]; X int x; X X *nextchar = '\0'; X x = XStringWidth(m->buf, &info, 0, 0); X XText(window, m->x+x, m->y, &c, 1, font, WhitePixel, BlackPixel); X} X Xrefresh() X{ X XFlush(); X} END_OF_xscreen.c if test 10284 -ne `wc -c