[comp.sources.games] v12i084: mgt2 - display/edit Smart-Go Game Records

billr@saab.CNA.TEK.COM (Bill Randle) (06/05/91)

Submitted-by: adrian@milton.u.washington.edu (Adrian Mariano)
Posting-number: Volume 12, Issue 84
Archive-name: mgt2/Part02
Supersedes: mgt: Volume 8, Issue 88-92
Environment: Unix, MSDOS, VMS, curses


#! /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 <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 2 (of 4)."
# Contents:  asc_ibm.inc ascii.c doit.c mgt.6 parse.c
# Wrapped by billr@saab on Tue Jun  4 12:33:07 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'asc_ibm.inc' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'asc_ibm.inc'\"
else
echo shar: Extracting \"'asc_ibm.inc'\" \(3041 characters\)
sed "s/^X//" >'asc_ibm.inc' <<'END_OF_FILE'
X/* "mgt" Copyright (c) 1991 Shodan  */
X
X
Xchar envAscii[] = "q><.,eb}{][gkijuwzxv!lm#^cdns&prf123467890X\376O=.\370\372"
X".\263\304\332\277\300\331";
X
X#include <conio.h>
X#include <dos.h>
X
X#define move(Y, X) gotoxy((X)+1, (Y)+1)
X#define mvaddstr(Y, X, STRING) gotoxy((X)+1, (Y)+1), cputs(STRING)
X#define mvprintw(Y, X, STRING) gotoxy((X)+1, (Y)+1), cputs(STRING)
X#define mvaddch(Y, X, CHAR) gotoxy((X)+1, (Y)+1), putch(CHAR)
X#define addch(CHAR) putch(CHAR)
X#define printw cprintf
X#define clrtoeol() clreol()
X#define clear() clrscr()
X#define getKey() getch()
X#define refresh()
X#define endwin() normvideo()
X#define wrefresh(win)
X#define wmove(win,y,x) move(y,x)
X#define waddch(win,c) addch(c)
X#define mvwaddch(win,y,x,c) mvaddch(y,x,c)
X#define waddstr(win,c) cputs(c)
X#define wclreol(win) clreol()
X#define closewin() window(1,1,80,25)
X#define xpos(w) (wherex()-1)
X#define ypos(w) (wherey()-1)
X#define NEWLINE "\r\n"
X#define openwin() notifyMessageAscii(EDHELP),window(WINLEFT+1,WINTOP+1,WINRIGHT+1,WINBOT+2),clear()
X#define fixcursor() if (ypos(win)>WINHIGH) wmove(win,WINHIGH,WINWIDE);
X#define preserveScreen() char screen[160][25];gettext(1,1,80,25,&screen)
X#define restoreScreen() puttext(1,1,80,25,&screen)
X#define normalize(c) (c)
X#define set_inverse()
X#define unset_inverse()
X
X
Xstatic void saveScreen()
X{
X   char screen[25][160];
X   int i, j, k;
X   char filename[33];
X   FILE *ft;
X
X   gettext(1, 1, 80, 25, &screen);
X   if (!(getLine("Save screen as? ", filename, 32) &&
X	 (ft = fopen(filename, "at"))))
X      getLine("Error opening file.  Hit return.", filename, 1);
X   else {
X      for (i = 0; i < 25; i++) {
X	 for (j = 79; (screen[i][j << 1] == 32) && j; j--);
X	 for (k = 0; k <= j; k++)
X	    fputc(screen[i][k << 1], ft);
X	 fputc('\n', ft);
X      }
X      fclose(ft);
X   }
X}
X
X
Xstatic void initboard()
X{
X   if (inverseFlag)
X      textattr(0x70);
X   else
X      textattr(0x07);
X   clrscr();
X}
X
X
Xstatic void initAscii()
X{
X
X   textmode(C80);
X#if 0
X   if (*((char far *) 0x484) != 24) {	/* If not in 25 line mode, switch */
X      _AX = 3;			/* This aparently can't be done   */
X      geninterrupt(0x10);	/* by the library functions.      */
X   }
X#endif
X}
X
X
X
Xstatic void plotMarkAscii(b, i, j)
X    pBoard b;
X    int i, j;
X{
X   void plotPieceAscii();
X
X   textattr(0x60);
X   plotPieceAscii(b, i, j);
X   if (inverseFlag)
X      textattr(0x70);
X   else
X      textattr(0x07);
X}
X
X
X
Xstatic command specialKeysIdle(c)
X    char c;
X{
X   if (!c) {
X      c = getKey();
X      switch (c) {
X      case 77:
X	 return C_DOWN;
X      case 75:
X	 return C_UP;
X      case 80:
X	 return C_DOWNFORK;
X      case 72:
X	 return C_UPFORK;
X      case 81:
X	 return C_SEARCHCOMMENT;
X      case 73:
X	 return C_SEARCHBACKCOMMENT;
X      default:
X	 return (command) 0;
X      }
X   } else
X      return (command) 0;
X}
X
X
Xstatic char specialKeysEdit(c)
X    char c;
X{
X   if (c)
X      return c;
X   c = getKey();
X   switch (c) {
X   case 77:
X      return CRIGHT;
X   case 75:
X      return CLEFT;
X   case 80:
X      return DOWN;
X   case 72:
X      return CUP;
X   default:
X      return 0;
X   }
X}
END_OF_FILE
if test 3041 -ne `wc -c <'asc_ibm.inc'`; then
    echo shar: \"'asc_ibm.inc'\" unpacked with wrong size!
fi
# end of 'asc_ibm.inc'
fi
if test -f 'ascii.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ascii.c'\"
else
echo shar: Extracting \"'ascii.c'\" \(18194 characters\)
sed "s/^X//" >'ascii.c' <<'END_OF_FILE'
X/* "mgt" Copyright (c) 1991 Shodan  */
X
X#include <ctype.h>
X#include "mgt.h"
X
X#define TOP 2
X#define LEFT 4
X#define RIGHT 79
X#define ASCII_ENV_STR "ASCII:"
X#define ASC_ENV_COM   "ASCCOM:"
X#define ASC_ENV_CHAR  "ASCCHAR:"
X#define ASC_INV       "ASCINV"
X#define STATUS_X 45
X#define STATUS_Y 0
X#define STATUS_WIDE (RIGHT-STATUS_X)
X#define COMMENT_X 46
X#define COMMENT_Y 2
X#define COMMENT_WIDE (RIGHT-COMMENT_X)
X#define COMMENT_HIGH (14-COMMENT_Y)
X#define TREE_X COMMENT_X
X#define TREE_Y 15
X#define TREEWIDE (RIGHT-TREE_X)
X#define TREEHIGH 6
X#define COMMAND_X TREE_X
X#define COMMAND_Y (TREE_Y+TREEHIGH)
X#define WINLEFT   COMMENT_X
X#define WINRIGHT  (RIGHT-1)
X#define WINTOP    2
X#define WINBOT    13
X#define WINHIGH   (WINBOT-WINTOP)
X#define WINWIDE   (WINRIGHT-WINLEFT)
X#define CUP    ('P'-64)
X#define DOWN  ('N'-64)
X#define CRIGHT ('F'-64)
X#define CLEFT ('B'-64)
X#define CTRLX ('X'-64)
X#define CTRLC ('C'-64)
X#define CTRLD ('D'-64)
X#define ESC   27
X#define EDHELP "^D - Done, save   ^X - Exit, no save"
X
Xenum {
X   ASC_CHAR_BLACK = C_REDRAW + 1, ASC_CHAR_WHITE,
X   ASC_CHAR_DAME,
X   ASC_CHAR_BLACKTERR, ASC_CHAR_WHITETERR,
X   ASC_CHAR_NOTHING,
X   ASC_CHAR_HANDICAP,
X   ASC_CHAR_VERT, ASC_CHAR_HORIZ,
X   ASC_CHAR_UPLEFT, ASC_CHAR_UPRIGHT,
X   ASC_CHAR_DOWNLEFT, ASC_CHAR_DOWNRIGHT,
X   ASC_NUMENVS
X};
X
X
Xstatic boolean commentExists;
Xstatic int commentLine;
Xstatic int treeLine;
Xstatic int inverseFlag = 0;
Xstatic char boardPiece();
Xstatic int getLine();
Xstatic void drawPiece();
X
Xchar *xAxisChars = "ABCDEFGHJKLMNOPQRSTUVWXYZ";
X
X#ifdef MGT_IBM
X#include "asc_ibm.inc"
X#endif
X
X#if (MGT_UNIX || vms)
X#include "asc_unix.inc"
X#endif
X
X
Xstatic void printCmdSet()
X{
X   commandIndex i, j;
X
X   mvaddstr(COMMAND_Y, COMMAND_X, "Commands:");
X   for (j = i = (int) C_QUIT; i != (int) C_DOWNLEFT; j++, i++) {
X
X      if (j + COMMAND_X + sizeof("Commands:") == 79)
X	 j = 0;
X      move(COMMAND_Y + ((j != i) ? 1 : 0), j + COMMAND_X + sizeof("Commands:"));
X      addch(envAscii[i]);
X   }
X   mvaddstr(COMMAND_Y + 1, COMMENT_X + COMMENT_WIDE - sizeof("? for help)"), "(? for help)");
X   refresh();
X}
X
Xstatic void notifyMessageAscii(s)
X    char *s;
X{
X   mvaddstr(23, 1, s);
X   refresh();
X}
X
Xstatic void clearScreenAscii()
X{
X   clear();
X}
X
Xstatic void notifyClearAscii()
X{
X   move(23, 1);
X   clrtoeol();
X}
X
Xstatic void printstatus(mesg)
X    char *mesg;
X{
X   int i;
X   move(STATUS_Y, STATUS_X);
X   for (i = 0; i < STATUS_WIDE && mesg[i]; i++)
X      addch(mesg[i]);
X}
X
X
Xstatic int getLine(query, dst, maxLen)	/* char *, char *, int */
X    char *query, *dst;
X    int maxLen;
X{
X   int qLen, dLen;
X   char c;
X   mvaddstr(23, 1, query);
X   clrtoeol();
X   dLen = 0;
X   qLen = strlen(query);
X   do {
X      move(23, qLen + 1 + dLen);
X      refresh();
X      c = getKey();
X      if (isprint(c) && dLen < maxLen) {
X	 move(23, qLen + dLen + 1);
X	 refresh();
X	 addch(c);
X	 dst[dLen++] = c;
X      } else if (dLen && (c == '\b' || c == '\177')) {
X	 dLen--;
X	 move(23, qLen + dLen + 1);
X	 addch(' ');
X      }
X   }
X   while (c != '\n' && c != '\r');
X   dst[dLen] = 0;
X   move(23, 1);
X   clrtoeol();
X   return dLen;
X}
X
X
Xstatic int askYNAscii(query, def)
X    char *query;
X    int def;
X{
X   static char *yn[] =
X   {" (y/N)? ", " (Y/n)? "};
X   char line[80];
X   char buf[3];
X
X   strcpy(line, query);
X   strcat(line, yn[def]);
X   if (getLine(line, buf, 2)) {
X      if (*buf == 'Y' || *buf == 'y')
X	 return 1;
X      if (*buf == 'N' || *buf == 'n')
X	 return 0;
X   }
X   return def;;
X}
X
X
Xstatic void setCursor(x, y)
X    int x, y;
X{
X   move(TOP + y, LEFT + 2 * x);
X}
X
X
Xstatic void printNStr(s, n)
X    char *s;
X    int n;
X{
X   int i;
X   for (i = 0; i < n && s[i]; i++)
X      addch(s[i]);
X}
X
X
Xstatic void drawTreeAscii0(n)
X    nodep n;
X{
X   property *p;
X
X   move(TREE_Y, TREE_X + 1);
X   printw(" Node #%d: ", n->nodeNum);
X   if (p = getprop(n, t_Name)) {
X      int num, width;
X
X      width = TREEWIDE - 10;
X      num = n->nodeNum;
X      do {
X	 num /= 10;
X	 width--;
X      } while (num);
X      printNStr((char *) p->d, width);
X   }
X   clrtoeol();
X   {
X      int temp;
X      if (treeLine < 0)
X	 treeLine = 0;
X      else {
X	 temp = treeCountSiblings(n) - TREEHIGH + 1;
X	 temp = MAX(temp, 0);
X	 treeLine = treeLine > temp ? temp : treeLine;
X      }
X   }
X   {
X      nodep ch;
X      int index;
X      index = 0;
X      ch = nthChild(n, treeLine);
X      while (ch && index < TREEHIGH - 1) {
X	 move(index + TREE_Y + 1, TREE_X);
X	 printw("%c:", 'A' + index + treeLine);
X	 clrtoeol();
X	 if (p = getprop(ch, t_Name))
X	    printNStr((char *) p->d, 80 - (TREE_X + 3));
X	 ch = ch->nextSibling;
X	 index++;
X      }
X      while (index < TREEHIGH - 1) {
X	 move(index++ + TREE_Y + 1, TREE_X);
X	 clrtoeol();
X      }
X      move(TREE_Y + TREEHIGH - 1, TREE_X - 1);
X      addch(ch ? '+' : ' ');
X      move(TREE_Y + 1, TREE_X - 1);
X      addch(treeLine ? '-' : ' ');
X   }
X   refresh();
X}
X
X
X/* draw the tree children when node currently is at n */
Xstatic void drawTreeAscii(n)
X    nodep n;
X{
X   treeLine = 0;
X   drawTreeAscii0(n);
X}
X
X
Xstatic void closeAscii()
X{
X   endwin();
X}
X
X
Xstatic void refreshAscii()
X{
X   refresh();
X}
X
Xstatic char boardPiece(x, y)
X    int x, y;
X{
X   return ((x == 3 || x == 9 || x == 15) && (y == 3 || y == 9 || y == 15))
X      ? envAscii[(int) ASC_CHAR_HANDICAP] : envAscii[(int) ASC_CHAR_NOTHING];
X}
X
X
Xstatic void drawPiece(i, j, c)
X    int i, j;
X    char c;
X{
X   move(TOP + j, LEFT + 2 * i);
X   set_inverse();
X   addch(c);
X   unset_inverse();
X}
X
X
Xstatic void plotPieceAscii(b, i, j)
X    pBoard b;
X    int i, j;
X{
X   piece p;
X   char c;
X   p = boardGet(b, i, j);
X   switch (p) {
X   case P_NOTHING:
X      c = boardPiece(i, j);
X      break;
X   case P_BLACK:
X      c = envAscii[(int) ASC_CHAR_BLACK];
X      break;
X   case P_WHITE:
X      c = envAscii[(int) ASC_CHAR_WHITE];
X      break;
X   case P_DAME:
X      c = envAscii[(int) ASC_CHAR_DAME];
X      break;
X   case P_BLACKTERR:
X      c = envAscii[(int) ASC_CHAR_BLACKTERR];
X      break;
X   case P_WHITETERR:
X      c = envAscii[(int) ASC_CHAR_WHITETERR];
X      break;
X   }
X   drawPiece(i, j, c);
X}
X
X
Xstatic void drawPrisoners()
X{
X   extern int prisoners[];
X   char a, b, c, d;
X   if (curPlayer == t_Black) {
X      a = '>';
X      b = '<';
X      c = d = ' ';
X   } else {
X      a = b = ' ';
X      c = '>';
X      d = '<';
X   }
X   move(23, 46);
X   printw("%c %c: %d %c    %c %c: %d %c", a, envAscii[(int)
X					  ASC_CHAR_BLACK], prisoners[0], b, c,
X	  envAscii[(int) ASC_CHAR_WHITE], prisoners[1], d);
X   clrtoeol();
X}
X
X
Xstatic void highlightAscii(x, y, movenum, turn)
X    int x, y, movenum, turn;
X{
X   if (movenum > 0 && x >= 0) {
X      move(23, 1);
X      printw("%s #%d at '%c%d'  ",
X	     turn ? "White" : "Black",
X	     movenum, xAxisChars[x], boardsize - y);
X   } else {
X      move(23, 1);
X      clrtoeol();
X   }
X   drawPrisoners();
X   refresh();
X}
X
Xstatic void showCommentAscii(i)	/* display from line i onward */
X    int i;
X{
X   short line;
X
X   /* line = MIN(commentLines() - i, COMMENT_HIGH); / */
X   line = COMMENT_HIGH;
X
X   move(COMMENT_Y, COMMENT_X - 1);
X   addch(i ? '-' : ' ');
X   move(COMMENT_Y + COMMENT_HIGH - 1, COMMENT_X - 1);
X   addch(commentLines() - i > COMMENT_HIGH ? '+' : ' ');
X
X   while (line--) {
X      mvaddstr(line + COMMENT_Y, COMMENT_X, commentGet(line + i));
X      clrtoeol();
X   }
X   refresh();
X}
X
Xstatic void clearCommentAscii()
X{
X   int line;
X
X   commentExists = false;
X   for (line = COMMENT_Y; line < COMMENT_Y + COMMENT_HIGH; line++)
X      move(line, COMMENT_X), clrtoeol();
X   move(COMMENT_Y, COMMENT_X - 1);
X   addch(' ');
X   move(COMMENT_Y + COMMENT_HIGH - 1, COMMENT_X - 1);
X   addch(' ');
X   refresh();
X}
X
Xstatic void displayCommentAscii(s)
X    char *s;
X{
X   commentExists = true;
X   commentLine = 0;
X   formatComment(s, COMMENT_WIDE);
X   showCommentAscii(0);
X   refresh();
X}
X
Xstatic void clearBoardAscii(b)
X    pBoard b;
X{
X   int i, j;
X   initboard();
X   for (i = boardsize; i--;) {
X      /* left */
X      move(TOP + i, LEFT - 3);
X      printw("%2d", boardsize - i);
X      set_inverse();
X      addch(envAscii[(int) ASC_CHAR_VERT]);
X
X      /* right */
X      move(TOP + i, LEFT + boardsize * 2 - 1);
X      addch(envAscii[(int) ASC_CHAR_VERT]);
X      unset_inverse();
X      printw("%2d%c", boardsize - i, envAscii[(int) ASC_CHAR_VERT]);
X
X      /* top */
X      move(TOP - 2, LEFT + i * 2);
X      addch(xAxisChars[i]);
X      move(TOP - 1, LEFT + i * 2 - 1);
X      set_inverse();
X      printw("%c%c", envAscii[(int) ASC_CHAR_HORIZ], envAscii[(int) ASC_CHAR_HORIZ]);
X
X      /* bottom */
X      move(TOP + boardsize, LEFT + i * 2 - 1);
X      printw("%c%c", envAscii[(int) ASC_CHAR_HORIZ], envAscii[(int) ASC_CHAR_HORIZ]);
X      unset_inverse();
X      move(TOP + boardsize + 1, LEFT + i * 2);
X      addch(xAxisChars[i]);
X      for (j = boardsize; j--;) {
X	 setPiece(b, i, j, P_NOTHING);
X      }
X   }
X   set_inverse();
X   move(TOP - 1, LEFT - 1);
X   addch(envAscii[(int) ASC_CHAR_UPLEFT]);
X   move(TOP - 1, LEFT + boardsize * 2 - 1);
X   addch(envAscii[(int) ASC_CHAR_UPRIGHT]);
X   move(TOP + boardsize, LEFT - 1);
X   addch(envAscii[(int) ASC_CHAR_DOWNLEFT]);
X   move(TOP + boardsize, LEFT + boardsize * 2 - 1);
X   addch(envAscii[(int) ASC_CHAR_DOWNRIGHT]);
X   unset_inverse();
X   printCmdSet();
X   printstatus(name_buf);
X}
X
Xstatic commandIndex charToIndex(c)
X    char c;
X{
X   int i;
X   if ((c == ESC) || (c == CTRLC))
X      return (commandIndex) C_QUIT;
X   for (i = (int) ASC_CHAR_BLACK; i--;) {
X      if (c == envAscii[i])
X	 break;
X   }
X   return i;			/* -1 = not found */
X}
X
X
Xstatic int getPointAscii()
X{
X   char c;
X
X   setCursor(xcur, ycur);
X   refresh();
X   while (1) {
X      c = getKey();
X      if ((c == ESC) || (c == envAscii[(int) C_QUIT]))
X	 return (int) C_QUIT;
X      if (c == 014)
X	 return (int) C_REDRAW;
X      if ((c == '\r') || (c == '\n'))
X	 return (int) C_SCORE;
X      if ((c == ' ') || (c == envAscii[(int) C_MOVE]))
X	 return (int) C_NOTHING;
X      switch (charToIndex(c)) {
X      case C_CURLEFT:
X	 xcur = (xcur - 1 + boardsize) % boardsize;
X	 setCursor(xcur, ycur);
X	 refresh();
X	 break;
X      case C_CURRIGHT:
X	 xcur = (xcur + 1) % boardsize;
X	 setCursor(xcur, ycur);
X	 refresh();
X	 break;
X      case C_CURUP:
X	 ycur = (ycur - 1 + boardsize) % boardsize;
X	 setCursor(xcur, ycur);
X	 refresh();
X	 break;
X      case C_CURDOWN:
X	 ycur = (ycur + 1) % boardsize;
X	 setCursor(xcur, ycur);
X	 refresh();
X	 break;
X      case C_UPLEFT:
X	 ycur = (ycur - 1 + boardsize) % boardsize;
X	 xcur = (xcur - 1 + boardsize) % boardsize;
X	 setCursor(xcur, ycur);
X	 refresh();
X	 break;
X      case C_UPRIGHT:
X	 xcur = (xcur + 1) % boardsize;
X	 ycur = (ycur - 1 + boardsize) % boardsize;
X	 setCursor(xcur, ycur);
X	 refresh();
X	 break;
X      case C_DOWNLEFT:
X	 xcur = (xcur - 1 + boardsize) % boardsize;
X	 ycur = (ycur + 1) % boardsize;
X	 setCursor(xcur, ycur);
X	 refresh();
X	 break;
X      case C_DOWNRIGHT:
X	 xcur = (xcur + 1) % boardsize;
X	 ycur = (ycur + 1) % boardsize;
X	 setCursor(xcur, ycur);
X	 refresh();
X	 break;
X      }
X   }
X}
X
X
X
Xstatic char *edhelp[] =
X{
X   "                Comment Editor Help",
X   "",
X   " Cursor control as in emacs:",
X   "    ^P: Previous line         ^N: Next line",
X   "    ^B: Back one character    ^F: Forward one character",
X   "",
X   " Press ^D or ESC to exit and save your comment",
X   " Press ^X to exit and discard any changes you have made",
X   "",
X   "  (Warning:  comments longer than the comment window",
X   "             will be truncated if edited)",
X   "",
X   "               Hit any key to return"
X};
X
X
X
X
X
Xstatic void helpAscii()
X{
X   int i;
X   extern char *helpStr[];
X   char ch;
X   /* don't put anything here */
X   preserveScreen();
X   clear();
X   move(1, 33);
X   printw("MGT Version %s", VERSION);
X   move(2, 12);
X   printw("Written by Greg Hale        Enhancements by Adrian Mariano");
X   move(3, 11);
X   printw("(hale@scam.Berkely.edu)     (adrian@milton.u.washington.edu)");
X   move(4, 2 + 6);
X   printw("%c or ESC: Quit mgt", envAscii[(int) C_QUIT]);
X   for (i = 6 - 5; i < 21 - 4; i++) {
X      move(i + 4, 2 + 6);
X      printw("%c: %s", envAscii[i], helpStr[i]);
X   }
X   move(21, 2 + 6);
X   printw("Ctrl-F: Save image of screen");
X   move(22, 2 + 6);
X   printw("Uppercase letters %s", helpStr[(int) C_CHOSECHILD]);
X   for (; i <= (int) C_NEXTFILE; i++) {
X      move(i - 13, 40 + 6);
X      printw("%c: %s", envAscii[i], helpStr[i]);
X   }
X   move(20, 40 + 6);
X   printw("Space or %c: %s", envAscii[(int) C_MOVE], helpStr[(int) C_MOVE]);
X   move(21, 40 + 6);
X   printw("Ctrl-L: Refresh display");
X   move(22, 40 + 6);
X   for (i = (int) C_DOWNLEFT; i <= (int) C_UPRIGHT; i++)
X      addch(envAscii[i]);
X   printw(": Cursor movement");
X   move(23, 21);
X   printw("Hit return to return, any key to continue");
X   refresh();
X   ch = getKey();
X   if (ch != '\r' && ch != '\n') {
X      clear();
X      for (i = 0; i < sizeof(edhelp) / sizeof(char *); i++)
X	 mvaddstr(i + 3, 10, edhelp[i]);
X      refresh();
X      getKey();
X   }
X   restoreScreen();
X}
X
X
X
Xstatic int idleAscii(curnode)
X    nodep curnode;
X{
X   char c;
X   command r;
X   commandIndex com;
X
X   highlightLast();
X   setCursor(xcur, ycur);
X   refresh();
X
X   c = getKey();
X   if (r = specialKeysIdle(c))
X      return (int) r;
X   r = C_NOTHING;
X   if (c >= 'A' && c <= 'Z') {
X      r = (command) ((char) C_CHOSECHILD + (c - 'A'));
X   } else
X      switch (c) {
X      case 014:		/* do redraw ^L 2/21/90 */
X	 return (int) C_REDRAW;
X      case 06:			/* save screen ^F 3/10/90 */
X	 saveScreen();
X	 return (int) C_NOTHING;
X      case ' ':
X	 return (int) C_MOVE;
X      case '?':
X	 helpAscii();
X	 return (int) C_NOTHING;
X      default:
X	 com = charToIndex(c);
X	 switch (com) {
X	 case C_QUIT:
X	    {
X	       char buf[5];
X	       if (c != ESC) {
X		  getLine("Quit (y/N)?", buf, 1);
X		  if (buf[0] == 'y')
X		     r = C_QUIT;
X	       } else
X		  r = C_QUIT;
X	    }
X	    break;
X	 case C_VIDEO:
X	    inverseFlag = !inverseFlag;
X	    return (int) C_REDRAW;
X	 case C_COMMENTSCROLLDOWN:
X	    {
X	       if (commentLine < commentLines() - COMMENT_HIGH)
X		  commentLine += COMMENT_HIGH - 1;
X	       showCommentAscii(commentLine);
X	    }
X	    break;
X	 case C_COMMENTSCROLLUP:
X	    if (commentLine) {
X	       commentLine -= COMMENT_HIGH - 1;
X	       showCommentAscii(commentLine);
X	    }
X	    break;
X	 case C_TREESCROLLDOWN:
X	    treeLine++;
X	    drawTreeAscii0(curnode);
X	    break;
X	 case C_TREESCROLLUP:
X	    treeLine--;
X	    drawTreeAscii0(curnode);
X	    break;
X	 default:
X	    r = (command) com;
X	 }
X      }
X   return (int) r;
X}
X
X
Xstatic void readEnvAscii(env)
X    char **env;
X{
X   if (!strncmp((*env), ASCII_ENV_STR, strlen(ASCII_ENV_STR))) {
X      (*env) += strlen(ASCII_ENV_STR);
X      strncpy(envAscii, (*env), (int) ASC_NUMENVS);
X   } else if (!strncmp((*env), ASC_ENV_COM, strlen(ASC_ENV_COM))) {
X      (*env) += strlen(ASC_ENV_COM);
X      strncpy(envAscii, (*env), (int) ASC_CHAR_BLACK);
X   } else if (!strncmp((*env), ASC_ENV_CHAR, strlen(ASC_ENV_CHAR))) {
X      (*env) += strlen(ASC_ENV_CHAR);
X      strncpy(&envAscii[(int) ASC_CHAR_BLACK], (*env), (int) ASC_NUMENVS - (int) ASC_CHAR_BLACK);
X   } else if (!strncmp((*env), ASC_INV, strlen(ASC_INV))) {
X      (*env) += strlen(ASC_INV);
X      inverseFlag = 1;
X   }
X}
X
X
X
Xstatic void edit(inp, out)
X    char *inp, **out;
X{
X   int x, y;
X   char c;
X   char screen[WINHIGH + 1][WINWIDE + 1];
X   char str[2000];
X   char *s;
X   /* don't put any statements before openwin() */
X   openwin();
X
X   for (y = 0; y < WINHIGH + 1; y++)
X      for (x = 0; x < WINWIDE + 1; x++)
X	 screen[y][x] = 0;
X   if (inp)
X      for (s = inp, x = y = 0; *s && (x <= WINWIDE) && (y <= WINHIGH); s++) {
X	 screen[y][x] = *s;
X	 wmove(win, y, x);
X	 waddch(win, *s);
X	 if (*s == '\n') {
X	    x = 0;
X	    y++;
X	 } else if (x < WINWIDE)
X	    x++;
X	 else {
X	    x = 0;
X	    y++;
X	 }
X      }
X   wrefresh(win);
X   do {
X      fixcursor();
X      c = getKey();
X      c = specialKeysEdit(c);
X      if ((c >= ' ') && (c < 127)) {
X	 screen[ypos(win)][xpos(win)] = c;
X	 waddch(win, c);
X	 wrefresh(win);
X      }
X      if ((c == '\n') || (c == '\r')) {
X	 screen[ypos(win)][xpos(win)] = '\n';
X	 waddstr(win, NEWLINE);
X	 wrefresh(win);
X      }
X      if (((c == '\b') || (c == '\177')) && ((y = ypos(win)) || (xpos(win)))) {
X	 x = xpos(win);
X	 if (x)
X	    x--;
X	 else {
X	    y--;
X	    for (x = WINWIDE; !screen[y][x]; x--);
X	 }
X	 wmove(win, y, x);
X	 waddch(win, ' ');
X	 wmove(win, y, x);
X	 screen[y][x] = 0;
X	 wrefresh(win);
X      }
X      if ((c == CUP) && (y = ypos(win))) {
X	 y--;
X	 for (x = xpos(win); (x == -1) || !screen[y][x]; x--)
X	    screen[y][x] = ' ';
X	 x = xpos(win);
X	 wmove(win, y, x);
X	 wrefresh(win);
X      }
X      if ((c == DOWN) && (ypos(win) < WINHIGH)) {
X	 y = ypos(win);
X	 y++;
X	 for (x = xpos(win); (x == -1) || !screen[y][x]; x--)
X	    screen[y][x] = ' ';
X	 x = xpos(win);
X	 wmove(win, y, x);
X	 wrefresh(win);
X      }
X      if ((c == CLEFT) && ((y = ypos(win)) || (xpos(win)))) {
X	 x = xpos(win);
X	 if (x)
X	    x--;
X	 else {
X	    y--;
X	    for (x = WINWIDE; !screen[y][x]; x--)
X	       screen[y][x] = ' ';
X	    x = WINWIDE;
X	 }
X	 wmove(win, y, x);
X	 wrefresh(win);
X      }
X      if ((c == CRIGHT) && !((xpos(win) == WINWIDE) && (ypos(win) == WINHIGH))) {
X	 x = xpos(win);
X	 y = ypos(win);
X	 if (!screen[y][x])
X	    screen[y][x] = ' ';
X	 if (x != WINWIDE)
X	    x++;
X	 else {
X	    y++;
X	    x = 0;
X	 }
X	 if (!screen[y][x])
X	    screen[y][x] = ' ';
X	 wmove(win, y, x);
X	 wrefresh(win);
X      }
X   }
X   while (c != ESC && c != CTRLX && c != CTRLD);
X   closewin();
X   notifyClearAscii();
X   if (c == CTRLX)
X      *out = inp;
X   else {
X      strcpy(str, "");
X      s = str;
X      for (y = 0; screen[y][0] && (y <= WINHIGH); y++)
X	 for (x = 0; (x < WINWIDE + 1) && (screen[y][x]); x++, s++)
X	    if (screen[y][x])
X	       *s = screen[y][x];
X	    else
X	       *s = ' ';
X      *s = 0;
X      if (inp)
X	 free(inp);
X      *out = dupStr(str);
X   }
X
X}
X
X
X
X
Xinterface asciiInterface =
X{
X   (char *) 0,
X   (char *) 0,
X   (char *) 0,
X   (pfi) initAscii,
X   (pfi) closeAscii,
X   (pfi) refreshAscii,
X   (pfi) plotPieceAscii,
X   (pfi) displayCommentAscii,
X   (pfi) clearCommentAscii,
X   (pfi) clearBoardAscii,
X   (pfi) clearScreenAscii,
X   idleAscii,
X   (pfi) drawTreeAscii,
X   (pfi) highlightAscii,
X   (pfi) readEnvAscii,
X   (pfi) notifyMessageAscii,
X   (pfi) notifyClearAscii,
X   getLine,
X   (pfi) setCursor,
X   (pfi) plotMarkAscii,
X   (pfi) drawPiece,
X   getPointAscii,
X   (pfi) edit,
X   askYNAscii
X};
END_OF_FILE
if test 18194 -ne `wc -c <'ascii.c'`; then
    echo shar: \"'ascii.c'\" unpacked with wrong size!
fi
# end of 'ascii.c'
fi
if test -f 'doit.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'doit.c'\"
else
echo shar: Extracting \"'doit.c'\" \(12794 characters\)
sed "s/^X//" >'doit.c' <<'END_OF_FILE'
X/* "mgt" Copyright (c) 1991 Shodan  */
X
X#include "mgt.h"
X
Xint xcur, ycur;
XToken curPlayer;
Xint change;
Xint madechanges;
Xint searchNodeNum;
X
XFUNCTION int okChange()
X{
X   if ((!change) && ((*io->askYN) ("Modify tree", 0)))
X      change = 1;
X   if (change)
X      madechanges = 1;
X   return change;
X}
X
X
X
XFUNCTION int okExit(root)
X    nodep root;
X{
X   if (mailFlag) {
X      if (madechanges) {
X	 if (!(*io->askYN) ("Save", 1)) {
X	    retVal = 1;
X	    return 1;
X	 }
X	 if (writeTree(saveName, root))
X	    return 0;
X	 return 1;
X      }
X      retVal = 1;
X      return 1;
X   }
X   if (madechanges) {
X      if ((*io->askYN) ("Unsaved changes.  Exit without saving", 0))
X	 return 1;
X      return 0;
X   }
X   return 1;
X}
X
X
X
XFUNCTION nodep search(n, bSearch)
X    nodep n;
X    boolean bSearch;
X{
X   nodep s;
X   if (!n || n->nodeNum == searchNodeNum)
X      return n;
X   s = search(child(n), false);
X   if (s && s->nodeNum == searchNodeNum)
X      return bSearch ? search(child(n), bSearch) : s;
X   s = search(nextSibling(n), false);
X   if (s && s->nodeNum == searchNodeNum)
X      return bSearch ? search(nextSibling(n), bSearch) : s;
X   return n;
X}
X
XFUNCTION void step(n, b)
X    nodep n;
X    pBoard b;
X{
X   board temp;
X   buildTree(n, &temp);
X   updateBoard(b, &temp);
X   (*io->drawTree) (n);
X   (*io->refreshIO) ();
X   highlightLast();
X}
X
XFUNCTION void stepDown(n, b)
X    nodep n;
X    pBoard b;
X{
X   board temp;
X   (*io->clearComment) ();
X   copyBoard(b, &temp);
X   doProps(n->p, &temp);
X   doPropComment(n);
X   updateBoard(b, &temp);
X   (*io->drawTree) (n);
X   (*io->refreshIO) ();
X   highlightLast();
X};
X
X
Xstatic char *color[] =
X{
X   "Black", "White"
X};
X
X
XFUNCTION void doScore(b, curNode)
X    pBoard b;
X    nodep curNode;
X{
X   extern int prisoners[];
X   int savepris[2];
X   char out[200];
X   command c;
X   property *p;
X   board new, old, back;
X   int score[2], i, j;
X   savepris[1] = prisoners[1];
X   savepris[0] = prisoners[0];
X   copyBoard(b, &old);
X   copyBoard(b, &back);
X   copyBoard(b, &new);
X   (*io->notifyClear) ();
X   (*io->clearComment) ();
X   (*io->displayComment) (
X    "Press return to score\n\nspace to remove dead stones\n\nq to abort\n\n");
X   do {
X      c = (command) (*io->getPoint) ();
X      if (c == C_NOTHING) {
X	 removeStones(&new, xcur, ycur);
X	 updateBoard(b, &new);
X      }
X   }
X   while (c == C_NOTHING);
X   if (c == C_SCORE) {
X
X      scoreBoard(&new, score);
X
X      updateBoard(b, &new);
X      sprintf(out,
X	      "Black: %d + %d = %d\n\nWhite: %d + %d = %d\n\n%s wins by %d.",
X	      score[0], prisoners[1], score[0] + prisoners[1],
X	      score[1], prisoners[0], score[1] + prisoners[0],
X	   color[(score[0] + prisoners[1] > score[1] + prisoners[0]) ? 0 : 1],
X	      abs(score[0] + prisoners[1] - score[1] - prisoners[0]));
X      (*io->clearComment) ();
X      (*io->displayComment) (out);
X      if ((*io->askYN) ("Keep comment", 1) && okChange())
X	 replaceComment(curNode, out);
X      else {
X	 (*io->clearComment) ();
X	 if (p = getprop(curNode, t_Comment))
X	    (*io->displayComment) ((char *) p->d);
X      }
X   }
X   prisoners[0] = savepris[0];
X   prisoners[1] = savepris[1];
X
X   updateBoard(b, &old);
X   if (c == C_QUIT) {
X      (*io->clearComment) ();
X      if (p = getprop(curNode, t_Comment))
X	 (*io->displayComment) ((char *) p->d);
X   }
X}
X
X
X
X
XFUNCTION void doit()
X{
X   int quitflg, i;
X   nodep root, curNode;
X   board theBoard;
X   extern coord *lastletters;
X
X   curPlayer = t_Black;
X   xcur = ycur = quitflg = 0;
X   root = 0;
X   madechanges = 0;
X   change = 1;
X   if (input != stdin) {
X      root = parse(0);
X      fclose(input);
X      change = 0;
X   }
X   if (!root)
X      root = newNode();
X   curNode = root;
X   boardClear(&theBoard);
X   (*io->clearBoard) (&theBoard);
X   (*io->setCursor) (xcur, ycur);
X   (*io->refreshIO) ();
X   if (mailFlag) {
X      while (curNode->child)
X	 curNode = treeDown(curNode);
X      change = 1;
X   }
X   step(curNode, &theBoard);
X   while (!quitflg) {
X      nodep tNode;
X      command c;
X      c = (command) (*io->idle) (curNode);
X
X      if ((int) c >= (int) C_CHOSECHILD && (int) c < (int) C_NEXTCMD) {
X	 nodep new;
X	 new = nthChild(curNode, (int) c - (int) C_CHOSECHILD);
X	 if (new) {
X	    curNode = nthChild(curNode, (int) c - (int) C_CHOSECHILD);
X	    step(curNode, &theBoard);
X	 }
X      } else
X	 switch (c) {
X	 case C_LOAD:
X	    if (okExit(root)) {
X	       char filename[50];
X	       if ((*io->queryStr) ("Load file? ", filename, 48)) {
X		  openfile(filename);
X		  if (input) {
X		     madechanges = 0;
X		     freeNode(root);
X		     initNodes();
X		     readInit();
X		     root = parse(0);
X		     fclose(input);
X		     if (!root)
X			root = newNode();
X		     curNode = root;
X		     boardClear(&theBoard);
X		     (*io->clearBoard) (&theBoard);
X		     (*io->setCursor) (xcur, ycur);
X		     (*io->refreshIO) ();
X		     step(curNode, &theBoard);
X		     xcur = ycur = 0;
X		  }
X	       }
X	    }
X	    break;
X
X	 case C_BACKFILE:
X	 case C_NEXTFILE:
X	    if (c == C_BACKFILE) {
X	       if (currentfile > 0)
X		  currentfile--;
X	       else
X		  break;
X	    }
X	    if (c == C_NEXTFILE) {
X	       if (currentfile + 1 < filecount)
X		  currentfile++;
X	       else
X		  break;
X	    }
X	    openfile(files[currentfile]);
X
X	    if (input) {
X	       madechanges = 0;
X	       freeNode(root);
X	       initNodes();
X	       readInit();
X	       root = parse(0);
X	       fclose(input);
X	       if (!root)
X		  root = newNode();
X	       curNode = root;
X	       boardClear(&theBoard);
X	       (*io->clearBoard) (&theBoard);
X	       (*io->setCursor) (xcur, ycur);
X	       (*io->refreshIO) ();
X	       step(curNode, &theBoard);
X	       xcur = ycur = 0;
X	    }
X	    break;
X
X
X
X	 case C_REDRAW:
X	    {
X	       int savex, savey;
X	       savex = xcur;
X	       savey = ycur;
X	       (*io->clearBoard) (&theBoard);
X	       (*io->refreshIO) ();
X	       step(curNode, &theBoard);
X	       xcur = savex;
X	       ycur = savey;
X	       break;
X	    }
X	 case C_NOTHING:
X	    break;
X	 case C_PASS:{
X	       extern Token lastTurn;
X	       curPlayer = (curPlayer == t_Black) ? t_White : t_Black;
X	       lastTurn = t_EOF;
X	    }
X
X	    break;
X	 case C_MOVE:
X	    if (okChange() && legal(&theBoard, curPlayer, xcur, ycur)) {
X	       int flag;
X	       flag = makeMove(curNode, curPlayer, xcur, ycur);
X	       if (flag)
X		  step(curNode, &theBoard);
X	       curNode = treeDown(curNode);
X	       curPlayer = (curPlayer == t_Black) ? t_White : t_Black;
X	       stepDown(curNode, &theBoard);
X
X	    }
X	    break;
X	 case C_ADDVAR:
X	    if (okChange()) {
X	       makeVariation(curNode);
X	       step(curNode, &theBoard);
X	    }
X	    break;
X	 case C_DELNODE:
X	    if (okChange()) {
X	       deleteNode(&curNode);
X	       step(curNode, &theBoard);
X	    }
X	    break;
X	 case C_PASTE:
X	    if (okChange()) {
X	       int rflag;
X
X	       rflag = (curNode == root) ? 1 : 0;
X	       pasteTree(&curNode);
X	       if (rflag)
X		  root = curNode;
X	       step(curNode, &theBoard);
X	       break;
X	    }
X	 case C_TREECUT:
X	    if (okChange()) {
X	       nodep prevNode;
X	       int savex, savey;
X	       savex = xcur;
X	       savey = ycur;
X	       prevNode = curNode->parent;
X	       cutTree(curNode);
X	       curNode = prevNode;
X	       if (!curNode) {
X		  initNodes();
X		  root = curNode = newNode();
X	       }
X	       step(curNode, &theBoard);
X	       xcur = savex;
X	       ycur = savey;
X	       break;
X	    }
X	 case C_ADDBLACK:
X	    if (okChange()) {
X	       if (boardGet(&theBoard, xcur, ycur) == P_BLACK) {
X		  addStone(curNode, t_AddEmpty, xcur, ycur);
X		  setPiece(&theBoard, xcur, ycur, P_NOTHING);
X	       } else {
X		  addStone(curNode, t_AddBlack, xcur, ycur);
X		  setPiece(&theBoard, xcur, ycur, P_BLACK);
X	       }
X	       if (lastletters)
X		  for (i = 0; i < MAX_LETTERS && (lastletters[i].x != -1); i++)
X		     (*io->plotLetter) (lastletters[i].x, lastletters[i].y, i + 'a');
X	    }
X	    break;
X	 case C_ADDWHITE:
X	    if (okChange()) {
X	       if (boardGet(&theBoard, xcur, ycur) == P_WHITE) {
X		  addStone(curNode, t_AddEmpty, xcur, ycur);
X		  setPiece(&theBoard, xcur, ycur, P_NOTHING);
X	       } else {
X		  addStone(curNode, t_AddWhite, xcur, ycur);
X		  setPiece(&theBoard, xcur, ycur, P_WHITE);
X	       }
X	       if (lastletters)
X		  for (i = 0; i < MAX_LETTERS && (lastletters[i].x != -1); i++)
X		     (*io->plotLetter) (lastletters[i].x, lastletters[i].y, i + 'a');
X	    }
X	    break;
X	 case C_ADDLETTER:
X	    if (okChange() && (i = addMark(curNode, t_Letter, xcur, ycur))) {
X	       if (i == 2)
X		  (*io->plotPiece) (&theBoard, xcur, ycur);
X	       step(curNode, &theBoard);
X	    }
X	    break;
X	 case C_ADDMARK:
X	    if (okChange() && (i = addMark(curNode, t_Mark, xcur, ycur))) {
X	       if (i == 2)
X		  (*io->plotPiece) (&theBoard, xcur, ycur);
X	       stepDown(curNode, &theBoard);
X	    }
X	    break;
X	 case C_EDCOMMENT:
X	    if (okChange()) {
X	       edComment(curNode);
X	       stepDown(curNode, &theBoard);
X	    }
X	    break;
X	 case C_ADDNAME:
X	    if (okChange()) {
X	       makeName(curNode);
X	       step(curNode, &theBoard);
X	    }
X	    break;
X	 case C_DOWN:
X	    tNode = treeDown(curNode);
X	    if (tNode != curNode) {
X	       curNode = tNode;
X	       stepDown(curNode, &theBoard);
X	    }
X	    break;
X	 case C_UP:
X	    curNode = treeUp(curNode);
X	    step(curNode, &theBoard);
X	    break;
X	 case C_WALKDOWN:
X	    tNode = treeNext(curNode);
X	    if (tNode->parent == curNode) {
X	       stepDown(tNode, &theBoard);
X	    } else {
X	       step(tNode, &theBoard);
X	    }
X	    curNode = tNode;
X	    break;
X	 case C_WALKUP:
X	    curNode = treeLast(curNode);
X	    step(curNode, &theBoard);
X	    break;
X	 case C_SEARCHCOMMENT:
X	    {
X	       nodep tBegin;
X	       tBegin = curNode;
X	       tNode = curNode;
X	       do {
X		  tNode = treeNext(tNode);
X	       }
X	       while (tNode != tBegin && !getprop(tNode, t_Comment));
X	       if (tNode != curNode) {
X		  if (tNode->parent == curNode) {
X		     stepDown(tNode, &theBoard);
X		  } else {
X		     step(tNode, &theBoard);
X		  }
X		  curNode = tNode;
X	       }
X	    }
X	    break;
X	 case C_SEARCHBACKCOMMENT:
X	    tNode = curNode;
X	    curNode = curNode;
X	    do {
X	       curNode = treeLast(curNode);
X	    }
X	    while (curNode != tNode && !getprop(curNode, t_Comment));
X	    step(curNode, &theBoard);
X	    break;
X	 case C_UPFORK:
X	    while (curNode->parent) {
X	       curNode = curNode->parent;
X	       if (treeCountSiblings(curNode) > 1)
X		  break;
X	    }
X	    step(curNode, &theBoard);
X	    break;
X	 case C_DOWNFORK:
X	    {
X	       boolean useOneStep = true;
X	       while (curNode->child) {
X		  curNode = treeDown(curNode);
X		  if (treeCountSiblings(curNode) > 1)
X		     break;
X		  else
X		     useOneStep = false;
X	       }
X	       if (useOneStep)
X		  stepDown(curNode, &theBoard);
X	       else
X		  step(curNode, &theBoard);
X	    }
X	    break;
X	 case C_END:
X	    while (curNode->child) {
X	       curNode = treeDown(curNode);
X	    }
X	    step(curNode, &theBoard);
X	    break;
X	 case C_BEGINNING:
X	    curNode = root;
X	    step(curNode, &theBoard);
X	    break;
X	 case C_SCORE:
X	    doScore(&theBoard, curNode);
X	    break;
X	 case C_GOTO:
X	    {
X	       char buf[7];
X	       if (((*io->queryStr) ("Move to node # ?", buf, 5)) &&
X		   ((searchNodeNum = atoi(buf)) >= 0)) {
X		  (*io->notifyMessage) ("Searching...");
X		  curNode = search(root, true);
X		  step(curNode, &theBoard);
X		  (*io->notifyClear) ();
X	       }
X	    }
X	    break;
X	 case C_QUIT:
X	    if (okExit(root))
X	       quitflg++;
X	    break;
X	 case C_WRITE:
X	    {
X	       char filename[50];
X	       if ((*io->queryStr) ("Save name? ", filename, 48)) {
X		  madechanges = 0;
X		  writeTree(filename, root);
X	       }
X	    }
X	    break;
X	 case C_CURLEFT:
X	    xcur = (xcur - 1 + boardsize) % boardsize;
X	    (*io->setCursor) (xcur, ycur);
X	    (*io->refreshIO) ();
X	    break;
X	 case C_CURRIGHT:
X	    xcur = (xcur + 1) % boardsize;
X	    (*io->setCursor) (xcur, ycur);
X	    (*io->refreshIO) ();
X	    break;
X	 case C_CURUP:
X	    ycur = (ycur - 1 + boardsize) % boardsize;
X	    (*io->setCursor) (xcur, ycur);
X	    (*io->refreshIO) ();
X	    break;
X	 case C_CURDOWN:
X	    ycur = (ycur + 1) % boardsize;
X	    (*io->setCursor) (xcur, ycur);
X	    (*io->refreshIO) ();
X	    break;
X	 case C_UPLEFT:
X	    ycur = (ycur - 1 + boardsize) % boardsize;
X	    xcur = (xcur - 1 + boardsize) % boardsize;
X	    (*io->setCursor) (xcur, ycur);
X	    (*io->refreshIO) ();
X	    break;
X	 case C_UPRIGHT:
X	    xcur = (xcur + 1) % boardsize;
X	    ycur = (ycur - 1 + boardsize) % boardsize;
X	    (*io->setCursor) (xcur, ycur);
X	    (*io->refreshIO) ();
X	    break;
X	 case C_DOWNLEFT:
X	    xcur = (xcur - 1 + boardsize) % boardsize;
X	    ycur = (ycur + 1) % boardsize;
X	    (*io->setCursor) (xcur, ycur);
X	    (*io->refreshIO) ();
X	    break;
X	 case C_DOWNRIGHT:
X	    xcur = (xcur + 1) % boardsize;
X	    ycur = (ycur + 1) % boardsize;
X	    (*io->setCursor) (xcur, ycur);
X	    (*io->refreshIO) ();
X	    break;
X	 }
X   }
X}
END_OF_FILE
if test 12794 -ne `wc -c <'doit.c'`; then
    echo shar: \"'doit.c'\" unpacked with wrong size!
fi
# end of 'doit.c'
fi
if test -f 'mgt.6' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'mgt.6'\"
else
echo shar: Extracting \"'mgt.6'\" \(11372 characters\)
sed "s/^X//" >'mgt.6' <<'END_OF_FILE'
X.TH MGT 6  "5 April 1991"
X.SH NAME
Xmgt - game record display/editor for the oriental game of go
X.SH SYNOPSIS
X.B mgt
X[\-m filename] [files]
X.SH DESCRIPTION
XGo is an ancient oriental strategy game based on the capturing of territory.  
XThe players alternate putting stones on the board, 
Xtrying to surround as many empty intersections as possible.  
X.LP
X.B mgt
Xallows the user to examine Go game tree files created through the 
XMacintosh(tm) programs 
X.B Smart Go (tm)
Xor
X.B Go Explorer (tm).
X.B mgt
Xalso has basic Go game tree editing capabilities and may be used to
Xcreate or edit game tree files.  
XThe on\-line material provided by a
Xrather extensive and growing database allows many hours of instructional
Xenjoyment of various studies and tutorials concerning the game of Go. 
X.LP
X.B mailgo 
Xis a utility which manages E-mail Go games using  
X.B mgt 
Xas the Go board editor.  It is included in the 
X.B mgt 
Xpackage.  
X.LP
XThe 
X.B mgt 
Xprogram was originally developed to be a companion for the series, 
X"From My Go Teacher",
Xarchived at scam.berkeley.edu and milton.u.washington.edu for ftp.
XAlso available is the Internet GO Board communications program, 'go',
Xalso by Greg Hale, which connects up two terminals in real\-time
Xanywhere in the world.
X.SH COMMAND LINE OPTIONS
X.TP 8
X.B \-m filename
XInvoke a set of options used by the 
X.B mailgo
Xprogram for managing email games.  If a filename is specified for
Xloading (see below), the game record is loaded, and 
X.B mgt
Xautomatically moves to the end of the main variation of the game record. 
XThe game can be modified without confirmation.  
XIf the game record has been modified, 
Xit will be automatically saved, on exit, to the filename 
Xspecified after the \-m and 
X.B mgt
Xwill return success (zero).  If the game record has not been modified, 
Xor has not been allowed to be saved, then 
X.B mgt 
Xwill return failure (nonzero). 
X.LP
X.TP 8
X.B \-s
XChange save format used by the w command.  The default save format is
Xthe long format Smart-Go file.  Using this option results in 
Xshort format Smart-Go files.
X.LP
X.TP 8
X.B files
XThese are the files to be loaded.  The Unix and IBM version support 
Xwildcards.  If no file is specified, 
X.B mgt 
Xloads a blank board.  If you attempt to modify a file that was loaded,
X.B mgt 
Xwill prompt for confirmation the first time.  
X.LP
X.SH OPERATION
X.B mgt
Xcan be used to view and edit game records, 
Xor as an electronic game board for a two person 
Xgame.  There are many keyboard commands which execute 
Xthe various editing and display functions.
X.LP
X.TP 8
X> 
XStep down the game tree to the next move.  Stop at the end of a variation
Xand do not visit other variations.
X.LP
X.TP 8
X<
XMove back up the game tree.  (Previous move)
X.LP
X.TP 8
X .
XGo to the next sequentially numbered node.  This allows you to traverse the 
Xentire game tree, seeing all variation branches.  If you make any changes to 
Xthe game, however, the order in which the nodes are numbered may become very 
Xconfusing.
X.LP
X.TP 8
X,
XGo to the previous sequentially numbered node.
X.LP
X.TP 8
Xe
XGo to end of the current variation.
X.LP
X.TP 8
Xb
XGo to beginning of the game tree. 
X.LP
X.TP 8
X}
XGo forward like the "." command until a comment.
X.LP
X.TP 8
X{
XGo backwards like the "," command until a comment.
X.LP
X.TP 8
Xg
XGo to a specified node.  Type in the desired node number.
X.LP
X.TP 8
X] 
XMove forward until there is a variation branch in the game tree.
X.LP
X.TP 8
X[ 
XMove backwards until there is a variation branch in the game tree.
X.LP
X.TP 8
Xk and i 
XScroll the game tree variation window up and down. 
XA \- at the top of the variation window, and 
Xa + at the bottom indicate that more variations are available.
X.LP
X.TP 8
Xj and u 
XScroll comment window up and down.  
XA \- at the top of the comment, and 
Xa + at the bottom indicate that more comments are available.
X.LP
X.TP 8
X# 
XLoad new file.  Will prompt for confirmation if the current file has been
Xmodified.
X.LP
X.TP 8
Xr
XLoad previous file.  (Reverse through the file list)
X.LP
X.TP 8
Xf
XLoad next file.  (Forward through the file list)
X.LP
X.TP 8
Xw 
XWrite out Smart\-Go file.  Will prompt for a filename.
X.LP
X.TP 8
Xspace or 0 
XMake a move.  The current player turn is indicated by the > < 
Xaround the captured stones on the lower right. 
X.LP
X.TP 8
Xp 
XPass.  Change whose turn it is.  Does not generate a game tree token.
X.LP 
X.TP 8 
Xz 
XSet/unset black stones. 
X.LP 
X.TP 8 
Xx 
XSet/unset white stones. 
X.LP 
X.TP 8 
Xq or ESC.  
XQuit.  q will 
Xprompt for confirmation.  ESC will not prompt for confirmation.  
X.LP 
X.TP 8 
Xv 
XCreate a variation below the current node.  The variation will initially
Xcontain a null node.  You must move to that variation to make a move in
Xit.  If the "v" command is invoked at a node which is at the end of a
Xvariation, variation "A" is created with a null node. Subsequent
Xinvocations of the "v" command will create the "B", "C"... variations. 
X.LP 
X.TP 8 
X! 
XCut tree.  Moves the 
Xcurrent node and everything below it to a temporary holding buffer.  (Moves 
Xyour location back to the parent of the node you are one when you invoke it.) 
X.LP 
X.TP 8 
X^ 
XPaste tree.  Pastes the temporary holding buffer in after the 
Xcurrent node.  Usually the  opposite of cutting the tree. 
X.LP 
X.TP 8 
Xc 
XEdit the 
Xcurrent comment.  Use the emacs cursor keys ^P for up, ^N for down, ^F for 
Xright ^B for back.  There is no insert mode nor delete capability. Either 
Xbackspace or delete will backspace. Only a comment as large as the comment 
Xwindow may be edited.  Pressing c on a comment larger than the window will 
Xcause the extra to be lost.  Press Ctrl\-D or ESC to conclude comment 
Xediting and save the new comment.  Press Ctrl\-X to exit comment editing and
Xkeep the old comment, discarding any changes.
X.LP 
X.TP 8 
Xd 
XDelete node.  Deletes the current node, replacing it with its 
Xchild. If the current node has no child, then clear the properties of the 
Xcurrent node. 
X.LP 
X.TP 8 
Xn 
XName the current node.  You will be prompted for the 
Xname. 
X.LP 
X.TP 8 
Xs 
XScore the game.  After selecting this, move the cursor 
Xaround and remove the dead groups with 0 or space.  Then press return to 
Xscore. The score (Japanese) will be printed in the comment area.  You will
Xbe prompted to either keep this as the comment for the current node, or
Xrestore the old comment.
X.LP
X.TP 8
XCtrl\-L 
XRefresh the screen.
X.LP
X.TP 8
XCtrl\-F 
XSave the current screen to a file.
X.LP
X.TP 8
X? 
XDisplay a help screen.
X.LP
X.TP 8
X12346789 
XMove the cursor around.  Assumes standard numeric keypad orientation.
X.LP
X.SH ENVIRONMENT SETTINGS
XAll of the characters used for the commands and the display are configurable 
Xvia environment variables.  For the ascii interface, use:
X.LP
X.sp
X.if n \{.nf
Xsetenv MGT="_ASCII:q><.,eb}{][gkijuwzxv!lm#^
X            cdns&prf123467890X@O:+\-.+|\-++++"
X       (command should appear all on one line)
X.fi
X\}
X.if t \{.nf
Xsetenv MGT="_ASCII:q><.,eb}{][gkijuwzxv!lm#^cdns&prf123467890X@O=+\-.+|\-++++"
X.fi
X\}
X.LP
Xto get the default characters.  Change the @ to # to get # for black stones.
XPlace this line in your .cshrc, .login or .profile file (depending upon
Xwhich version of unix or type of shell you are using) 
Xso the alternate characters are always in effect.
X.LP
X.sp
X.if n \{.nf
Xsetenv MGT="_ASCCOM:q><.,eb}{][gkijuwzxv!
X                    lm#^cdns&prf123467890X
X            _ASCCHAR:@O:+\-.+|\-++++"
X       (command should appear all on one line with a 
X        single space separating _ASCCHAR from the
X        previous string.)
X.fi
X\}
X.if t \{.nf
Xsetenv MGT="_ASCCOM:q><.,eb}{][gkijuwzxv!lm#^cdns&prf123467890X
X            _ASCCHAR:@O=+\-.+|\-++++"
X.fi
X.in +.25i
X(command should appear all on one line with a 
Xsingle space separating _ASCCHAR from the
Xprevious string.)
X.in -.25i
X\}
X.LP
XThis command achieves the same effect as the first, but may be more 
Xconvenient if you only wish to change the commands or the display characters 
Xand not both since one of the two declarations ("_ASCCOM:" or "_ASCCHAR:") 
Xmay be omitted.  "_ASCCOM:" is used to change the commands recognized by
X.B mgt 
Xand "_ASCCHAR:" is used to change the displayed Go board characters. 
XTo set the default display type to inverse video, user _ASCINV in the 
XMGT environment variable.
XIf multiple contradictory specifications occur in the MGT
Xenvironment variable, the last that appear will be used by the program.
X.LP
XWith the IBM version, the same effects may be achieved under DOS 4.0 with
Xa SET command placed in the AUTOEXEC.BAT file.  Under previous DOS 
Xversions, quotes were interpreted literally and "|", ">" and "<" characters
Xhave special meanings and thus cannot be put into environment variables
Xwith the SET command.
XUnder VMS, the command is just MGT = "_ASCCHAR:..."
X.LP
X.SH COMMENT FORMATTING
XIn order to produce the most readable comment display possible, 
X.B mgt
Xreformats comments across line breaks, and ignores extra spaces at the ends
Xof lines.
XTo prevent your comments from  being reformatted, indent them at least one 
Xspace.
X.SH DISPLAYS
XAll displays have in common the purpose of displaying a go tree.
X.LP
XASCII display:
X.LP
X.sp
X.ft CW
X.nf
X    A B C D E F G H  S T
X   +---------------  ---+   -Suppose this is the second
X 19|. . . @ . . . .  . .|19| line of the comment.  Since
X 18|. O O @ @ @ O .  . .|18| there is some more of the
X 17|. @ @ O O O O .  . .|17| comment above us unseen, 
X 16|. @ O + . . . .  . .|16| the - appears to the left
X 15|. @ O . O . . .  . .|15| of 'Suppose'.
X 14|. . @ O . . . .  . .|14|
X 13|. . @ . . . . .  . .|13|
X 12|. . . . . . . .  . .|12|
X 11|. . . . . . . .  . .|11| And here, when there is
X 10|. . . + . . . .  . .|10| more of the comment
X  9|. . . . . . . .  . .| 9| below, the '+'
X  8|. . . . . . . .  . .| 8|+appears to our left.
X  7|. . . . . . . .  . .| 7|
X  6|. . . . . . . .  . .| 6|   Node #173: Name
X  5|. . . . . . . .  . .| 5|-B: variation 1 hit 'B' to see
X  4|. . . + . . . .  . .| 4| C: variation 2 hit 'C'
X  3|. . . . . . . .  . .| 3| D: variation 3 etc...            
X  2|. . . . . . . .  . .| 2| E: variation 4
X  1|. . . . . . . .  . .| 1|+F: variation 5
X   +---------------  ---+    Commands: q.,><eb}{][gkijuwzx
X    A B C D E F G H  S T               #^cdns&p   (? help)
X Black #1 at 'D19'                @: 0      > O: 0 <
X.fi
X.ft
X.LP
X.SH FILES
XThe 
X.B From My Go Teacher
Xtutorial lessons, and many professional game records all available at 
Xmilton.u.washington.edu.
X.LP
XInternet go, a program to play go over internet, available on milton.
X.LP 
XSmart-Go.def, the Smart\-Go format definition.
X.LP
XRules - a brief introduction to the game of go
X.sp
X.SH BUGS
X.LP
XComment editing has is limited to one screen, a return will do strange things 
Xin the middle of a line, and no insertion or deletion is available.
X.LP
XKo is not detected in game play.
X.LP
XOnly 12 Letters and 12 Marks can be displayed.  The marks may look like the 
Xcursor on some systems.
X.LP
XDoes not support the pass property Black[tt] and White[tt]
X.LP
XSend further bug reports to "adrian@milton.u.washington.edu",
X"...!ucbvax!scam!hale" or "hale@scam.Berkeley.EDU"
X.fi
X.sp
X.SH AUTHORS
XGreg Hale (hale@scam.berkeley.edu)
X.LP
XJeff Boscole
X.LP
XAdrian Mariano (adrian@milton.u.washington.edu)
X.sp
X.SH SEE ALSO
Xrn rec.games.go \- a newsgroup on the game
X.br
XGraded go problems for beginners, vol 1-3.,
XIshi Press. (Highly recommended.)
X.br
XIn the Beginning, 
XIshi Press.
X.br
XThe Treasure Chest Enigma, 
XIshi Press.
X
X
X
X
END_OF_FILE
if test 11372 -ne `wc -c <'mgt.6'`; then
    echo shar: \"'mgt.6'\" unpacked with wrong size!
fi
# end of 'mgt.6'
fi
if test -f 'parse.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'parse.c'\"
else
echo shar: Extracting \"'parse.c'\" \(5764 characters\)
sed "s/^X//" >'parse.c' <<'END_OF_FILE'
X/* "mgt" Copyright (c) 1991 Shodan  */
X
X#include <string.h>
X#include "mgt.h"
X
X
X/* "USer", "ANalysis", "CoPyright", "SOurce", "TiMe", "KoMi", "PlayBlack",
X * "PlayWhite", "PlaCe", "DaTe", "EVent", "GameName", "FileFormat", "VieW",
X * "GaMe", "BlackSpec","WhiteSpec", */
X
Xstruct {
X   char *str;
X   Token val;
X}  tokens[] = {
X   {
X      "W", t_White
X   },
X   {
X      "B", t_Black
X   },
X   {
X      "C", t_Comment
X   },
X   {
X      "AW", t_AddWhite
X   },
X   {
X      "AB", t_AddBlack
X   },
X   {
X      "L", t_Letter
X   },
X   {
X      "AE", t_AddEmpty
X   },
X   {
X      "N", t_Name
X   },
X   {
X      "M", t_Mark
X   },
X   {
X      "SZ", t_Size
X   },
X   {
X      "GN", t_Name
X   },
X};
X
X
Xchar buf[1024], *curin, started;
X
XFUNCTION void readInit()
X{
X   buf[0] = '\0';
X   curin = &buf[0];
X   started = 1;
X}
X
X
Xstatic void readLine()
X{
X   curin = &buf[0];
X   buf[0] = '\0';
X   fgets(&buf[0], 1023, input);
X}
X
X
Xstatic char readChar()
X{
X   if (*curin)
X      return *(curin++);
X   curin = &buf[0];
X   buf[0] = '\0';
X   fgets(&buf[0], 1023, input);
X   return 0;
X}
X
X
Xstatic int getCoordStr(co)
X    coord *co;
X{
X   if (curin[0] == '[' && curin[1] >= 'a' && curin[1] <= 's'
X       && curin[2] >= 'a' && curin[2] <= 's' && curin[3] == ']') {
X      co->x = curin[1] - 'a';
X      co->y = curin[2] - 'a';
X      curin += 4;
X      while (*curin == ' ' || *curin == '\t')
X	 curin++;
X      if (*curin == '\n')
X	 readLine();
X      return 1;
X   } else
X      return 0;
X}
X
X
Xstatic void getCoordList(clp)
X    coordListP clp;
X{
X   coord co;
X   while (getCoordStr(&co)) {
X      setCoord(co.x, co.y, clp);
X   }
X}
X
X
X
Xstatic Token tokenize()
X{
X   int i, len;
X   char buf[4];
X
X   len = 0;
X   do {
X      if (!*curin || *curin == '\n') {
X	 if (feof(input))
X	    return t_EOF;
X	 readLine();
X      }
X      if (*curin == ')') {
X	 curin++;
X	 return t_Close;
X      }
X      if (*curin == '(') {
X	 curin++;
X	 return t_Open;
X      }
X      if (*curin == ';') {
X	 curin++;
X	 return t_NewNode;
X      }
X      if (*curin >= 'A' && *curin <= 'Z')
X	 buf[len++] = *curin;
X      curin++;
X   } while (len < 3 && *curin != '[');
X   buf[len] = 0;
X   if (len == 1 || len == 2)
X      for (i = 0; i < sizeof(tokens) / sizeof(tokens[0]); i++)
X	 if (!strcmp(buf, tokens[i].str))
X	    return tokens[i].val;
X   while (*curin != ']') {
X      if (!*++curin) {
X	 readLine();
X	 if (feof(input))
X	    return t_EOF;
X      }
X   }
X   return t_WS;
X}
X
X
X
Xstatic void addMoveArrayProp(t, n)
X    Token t;
X    nodep n;
X{
X   coordListP cl;
X   property *p;
X
X#ifdef DEBUG
X   totalmemory += sizeof(property);
X   fprintf(debug, "%ld %ld\n", totalmemory, coreleft());
X#endif
X
X   p = (property *) calloc(1, sizeof(property));
X
X#ifdef DEBUG
X   totalmemory += sizeof(coordList);
X   fprintf(debug, "%ld %ld\n", totalmemory, coreleft());
X#endif
X
X   cl = (coordListP) calloc(1, sizeof(coordList));
X   if (!p || !cl)
X      barf("Memory allocation failure (addMoveArrayProp)");
X
X   p->t = t;
X   p->d = (data *) cl;
X   getCoordList(cl);
X   addprop(n, p);
X}
X
X
Xstatic void doletter(t, n)
X    Token t;
X    nodep n;
X{
X   coord *co;
X   coord dummy;
X   property *p;
X   int i;
X   p = (property *) calloc(1, sizeof(property));
X   co = (coord *) calloc(MAX_LETTERS, sizeof(coord));
X   if (!p || !co)
X      barf("Memory allocation failure (doletter)");
X   p->t = t;
X   p->d = (data *) co;
X   for (i = 0; i < MAX_LETTERS; i++)
X      co[i].x = -1;
X   for (i = 0; (i < MAX_LETTERS) && getCoordStr(co + i); i++);
X   addprop(n, p);
X   while (getCoordStr(&dummy));	/* Dump stuff over MAX_LETTERS */
X
X}
X
X
Xstatic void doSize()
X{
X   int size;
X   char *s, c, b[25];
X   s = &b[0];
X   readChar();
X   while ((c = readChar()) != ']')
X      if (c && c != '\\')
X	 *s++ = c;
X   *s = 0;
X   size = atoi(b);
X   if ((size > 0) && (size <= 19))
X      boardsize = size;
X}
X
X
Xstatic void doComment(n, t)
X    nodep n;
X    Token t;
X{
X   char c, *s, *buffer;
X   property *p;
X   int space;
X
X   buffer = (char *) malloc(MAXCOMMENT);
X   p = (property *) calloc(1, sizeof(property));
X   if (!p)
X      barf("Memory Allocation Failure (doComment)");
X   s = buffer;
X   space = MAXCOMMENT - 1;
X   readChar();
X   while (space && (c = readChar()) != ']') {
X      if (c == '\\')
X	 c = readChar();
X      if (c) {
X	 *s++ = c;
X	 space--;
X      }
X   }
X   *s = 0;
X   p->t = t;
X   p->d = (data *) dupStr(buffer);
X   addprop(n, p);
X   free(buffer);
X}
X
XFUNCTION void addChild(n, c)	/* add child c to node n */
X    nodep n, c;
X{
X   if (n) {
X      if (n->child) {
X	 nodep s;
X	 s = treeLastSibling(child(n));
X	 s->nextSibling = c;
X	 c->lastSibling = s;
X	 c->parent = n;
X      } else {
X	 n->child = c;
X	 c->parent = n;
X      }
X   }
X}
X
X
XFUNCTION nodep parse(lev)
X    int lev;
X{
X   nodep r, n, new;
X   Token t;
X
X   if (started) {
X      started = 0;
X
X      while (*curin != '(') {
X	 readLine();
X	 if (feof(input))
X	    break;
X      }
X   }
X   r = n = 0;
X   for (;;) {
X      t = tokenize();
X      switch (t) {
X      case t_Size:
X	 doSize();
X	 break;
X      case t_AddWhite:
X      case t_AddBlack:
X      case t_AddEmpty:
X      case t_White:
X      case t_Black:
X	 if (n)
X	    addMoveArrayProp(t, n);
X	 else
X	    fprintf(stderr, "Error - property w/o node in data\n");
X	 break;
X      case t_Mark:
X      case t_Letter:
X	 if (n)
X	    doletter(t, n);
X	 else
X	    fprintf(stderr, "Error - property w/o node in data\n");
X	 break;
X      case t_Name:
X      case t_Comment:
X	 if (n)
X	    doComment(n, t);
X	 else
X	    fprintf(stderr, "Error - property w/o node in data\n");
X	 break;
X      case t_NewNode:
X	 new = newNode();
X	 if (!r)
X	    r = new;
X	 else
X	    addChild(n, new);
X	 n = new;
X	 break;
X      case t_Open:
X	 if (lev == 1 && !r)
X	    n = r = newNode();
X	 if (new = parse(lev + 1)) {
X	    addChild(n, new);
X	    if (!r)
X	       r = new;
X	 }
X	 break;
X      case t_Close:
X      case t_EOF:
X	 return r;
X      default:
X	 break;
X      }
X   }
X}
END_OF_FILE
if test 5764 -ne `wc -c <'parse.c'`; then
    echo shar: \"'parse.c'\" unpacked with wrong size!
fi
# end of 'parse.c'
fi
echo shar: End of archive 2 \(of 4\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 3 4 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 4 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0