home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / go / prog / mgt23.sh < prev    next >
Encoding:
Linux/UNIX/POSIX Shell Script  |  1993-06-20  |  278.8 KB  |  11,690 lines

  1. #! /bin/sh
  2. # This is a shell archive, meaning:
  3. # 1. Remove everything above the #! /bin/sh line.
  4. # 2. Save the resulting text in a file.
  5. # 3. Execute the file with /bin/sh (not csh) to create:
  6. #    help.c
  7. #    asc_ibm.inc
  8. #    asc_unix.inc
  9. #    mou.c
  10. #    ascii.c
  11. #    build.c
  12. #    comment.c
  13. #    doit.c
  14. #    edit.c
  15. #    mgt.c
  16. #    parse.c
  17. #    play.c
  18. #    tree.c
  19. #    mgt.h
  20. #    proto.h
  21. #    mou.h
  22. #    Smart-Go.def
  23. #    README
  24. #    Makefile
  25. #    format
  26. #    mgt.6
  27. #    Spec.io
  28. #    Makefile.bc
  29. #    Build.com
  30. #    mailgo
  31. #    mailgo.6
  32. #    mgtdoc.asc
  33. #    Sample.01
  34. #    Sample.02
  35. #    Rules
  36. #    Prop.lst
  37. #    README.IBM
  38. #    wrapmgt.6
  39. #    wrapmgt.c
  40. #    mgt2short
  41. #    mgt2short.6
  42. #    mgtshort.bat
  43. #    mgtshort.cmd
  44. # This archive created: Mon Apr  5 10:32:55 1993
  45. export PATH; PATH=/bin:/usr/bin:$PATH
  46. if test -f 'help.c'
  47. then
  48.     echo shar: "will not over-write existing file 'help.c'"
  49. else
  50. cat << \SHAR_EOF > 'help.c'
  51. /* "mgt" Copyright (c) 1991 Shodan  */
  52.  
  53. /* Short help strings.  Don't make any of these longer than the longest one
  54.  * already present */
  55.  
  56. char *helpStr[] =
  57. {
  58.    "Quit mgt",
  59.    "Move forward",
  60.    "Move backward",
  61.    "Next node",
  62.    "Previous node",
  63.    "End of the current variation",
  64.    "Beginning of file",
  65.    "Next comment",
  66.    "Previous comment",
  67.    "Next variation branch",
  68.    "Last variation branch",
  69.    "Jump to a specific node number",
  70.    "Write Smart-Go file",
  71.    "Set black stone",
  72.    "Set white stone",
  73.    "Make variation",
  74.    "Cut tree into buffer",
  75.    "Add letter",
  76.    "Add mark",
  77.    "Load new file",
  78.    "Paste buffer in",
  79.    "Edit comment",
  80.    "Delete current node",
  81.    "Name the current node",
  82.    "Score the game",
  83.    "Pass move",
  84.    "Other player's turn (permanent)",
  85.    "Toggle stone",
  86.    "Reverse through files",
  87.    "Forward through files",
  88.    "Redraw screen",
  89.    "Toggle save format",
  90.    "Toggle tutor mode",
  91.    "Save screen image",
  92.    "Show game info",
  93.    "Make a move",
  94.    "Cursor down left",
  95.    "Cursor down",
  96.    "Cursor down right",
  97.    "Cursor left",
  98.    "Cursor right",
  99.    "Cursor up left",
  100.    "Cursor up",
  101.    "Cursor up right",
  102.    "___last command marker___"};
  103. SHAR_EOF
  104. fi
  105. if test -f 'asc_ibm.inc'
  106. then
  107.     echo shar: "will not over-write existing file 'asc_ibm.inc'"
  108. else
  109. cat << \SHAR_EOF > 'asc_ibm.inc'
  110. /* "mgt" Copyright (c) 1991 Shodan  */
  111.  
  112. char chars[] = "\3O?+-\372.\263\304\332\277\300\331";
  113. char graphchar[] = "\2O?\17.\305\307\335     ";
  114.  
  115. int graphicalCursor = 1;
  116. int graphics = 1;
  117. int usecolor = 1;
  118.  
  119. int boardcolor = 6;
  120. int blackstone = 0;
  121. int damecolor = 1;
  122. int whitestone = 7;
  123. int background = 0;
  124. int foreground = 7;
  125. int markcolor = 9;
  126. int lettercolor = 1;
  127. int menufg = 2;
  128. int menubg = 0;
  129.  
  130. int branchmode = 0;
  131. int stonemode = 1;
  132.  
  133. int bred = /* 0x3f; 63 44  40; */ 39;
  134. int bblue = /* 0x16; 22 15  14; */ 5;
  135. int bgreen = /* 0x2e; 46 32  30;  */ 33;
  136.  
  137. int fixfont = 0;
  138.  
  139. int menu = 0;
  140.  
  141. int cursorkey = 0;        /* 0 tree mode 1 movement 2 variable */
  142.  
  143. char *stoneModeName[] =
  144. {"mark", "stone"};
  145. char *branchModeName[] =
  146. {"walk", "branch"};
  147. char *menumode[] =
  148. {"move", "play", "edit", "files"};
  149.  
  150. #define MENUITEMS 4
  151.  
  152.  
  153. /* 6789012345678901234567890123456789012345 */
  154. char *menulines[] =
  155. {"    start  end  var  comment    ",
  156.  "       score  pass  player       ",
  157.  "info  cut  paste  delnode  addvar",
  158.  "     save  load  next  prev      "};
  159.  
  160.  
  161. struct {
  162.    char bottom, top;
  163. }  menubounds[4][5] = {
  164.    {{
  165.      -1, -1
  166.    }, {
  167.       10, 14
  168.    }, {
  169.       17, 19
  170.    }, {
  171.       22, 24
  172.    }, {
  173.       27, 33
  174.    }
  175.    },
  176.    {{
  177.      -1, -1
  178.    }, {
  179.       13, 17
  180.    }, {
  181.       20, 23
  182.    }, {
  183.       26, 31
  184.    }, {
  185.       -1, -1
  186.    }
  187.    },
  188.    {{
  189.      6, 9
  190.    }, {
  191.       12, 14
  192.    }, {
  193.       17, 21
  194.    }, {
  195.       24, 30
  196.    }, {
  197.       33, 38
  198.    }
  199.    },
  200.    {{
  201.      -1, -1
  202.    }, {
  203.       11, 14
  204.    }, {
  205.       17, 20
  206.    }, {
  207.       23, 26
  208.    }, {
  209.       29, 32
  210.    }
  211.    }
  212. };
  213.  
  214.  
  215. #include <conio.h>
  216. #include <dos.h>
  217. #include "mou.h"
  218.  
  219. #define doredraw()
  220. #define move(Y, X) gotoxy((X)+1, (Y)+1)
  221. #define mvaddstr(Y, X, STRING) gotoxy((X)+1, (Y)+1), cputs(STRING)
  222. #define mvprintw(Y, X, STRING) gotoxy((X)+1, (Y)+1), cputs(STRING)
  223. #define mvaddch(Y, X, CHAR) gotoxy((X)+1, (Y)+1), putch(CHAR)
  224. #define addch(CHAR) putch(CHAR)
  225. #define printw cprintf
  226. #define clrtoeol() clreol()
  227. #define clear() clrscr()
  228. #define refresh()
  229. #define wrefresh(win)
  230. #define wmove(win,y,x) move(y,x)
  231. #define waddch(win,c) addch(c)
  232. #define mvwaddch(win,y,x,c) mvaddch(y,x,c)
  233. #define waddstr(win,c) cputs(c)
  234. #define wclrtoeol(win) clreol()
  235. #define closewin() window(1,1,80,25)
  236. #define xpos(w) (wherex()-1)
  237. #define ypos(w) (wherey()-1)
  238. #define WINDOW char
  239. #define openwin() win=0,window(WINLEFT+1,WINTOP+1,WINRIGHT+1,WINBOT+2),clear()
  240. #define fixcursor() if (ypos(win)>WINHIGH) wmove(win,WINHIGH,WINWIDE);
  241. #define preserveScreen() char screen[160][25];gettext(1,1,80,25,&screen)
  242. #define restoreScreen() puttext(1,1,80,25,&screen)
  243. #define restoreRegion(x1,y1,dx,dy) puttext(x1+1,y1+1,x1+1+dx,y1+dy,savearea)
  244. #define saveRegion(x1,y1,dx,dy)    gettext(x1+1,y1+1,x1+1+dx,y1+dy,savearea)
  245. #define normalize(c) (c)
  246. #define set_inverse()
  247. #define unset_inverse()
  248. #define mainwin() closewin()
  249. #define unmainwin() window(WINLEFT+1,WINTOP+1,WINRIGHT+1,WINBOT+2)
  250.  
  251. void wclrtobot(win)
  252. int *win;
  253. {
  254.    int savex, savey, y;
  255.    savex = wherex();
  256.    savey = wherey();
  257.    clreol();
  258.    for (y = savey + 1; y <= WINBOT + 2; y++) {
  259.       gotoxy(1, y);
  260.       clreol();
  261.    }
  262.    gotoxy(savex, savey);
  263. }
  264.  
  265.  
  266. static unsigned char far *getfont()
  267. {
  268.    struct REGPACK regs;
  269.    regs.r_ax = 0x1130;
  270.    regs.r_bx = 0x0600;
  271.    intr(0x10, ®s);
  272.    return (unsigned char far *) MK_FP(regs.r_es, regs.r_bp);
  273. }
  274.  
  275.  
  276. static void setfont(unsigned char far * newfont)
  277. {
  278.    struct REGPACK regs;
  279.    regs.r_cx = 256;
  280.    regs.r_bx = 0x1000;
  281.    regs.r_dx = 0;
  282.    regs.r_ax = 0x1100;
  283.    regs.r_es = FP_SEG(newfont);
  284.    regs.r_bp = FP_OFF(newfont);
  285.    intr(0x10, ®s);
  286. }
  287.  
  288. static void endwin()
  289. {
  290.    closewin();
  291.    if (graphics && isegavga())
  292.       setfont(getfont());
  293.    normvideo();
  294.    MOUdeinit();
  295.    clrscr();
  296.    if (fixfont) {
  297.       _AX = 0x1112;
  298.       _BL = 0;
  299.       geninterrupt(0x10);
  300.    }
  301. }
  302.  
  303.  
  304. static void setcolor(bg, fg)
  305. int bg, fg;
  306.  
  307. {
  308.    if (usecolor)
  309.       textattr((bg << 4) + fg);
  310. }
  311.  
  312.  
  313. static void drawPrisoners()
  314. {
  315.    extern int ispl;
  316.    char a, b, c, d;
  317.    if (curPlayer == t_Black) {
  318.       a = ispl ? '\20' : '>';
  319.       b = ispl ? '\21' : '<';
  320.       c = d = ' ';
  321.    } else {
  322.       a = b = ' ';
  323.       c = ispl ? '\20' : '>';
  324.       d = ispl ? '\21' : '<';
  325.    }
  326.    move(23, 49);
  327.    if (usecolor) {
  328.       setcolor(boardcolor, blackstone);
  329.       printw(" %c %c: %d %c    ", a, chars[CHAR_BLACK], prisoners[0], b);
  330.       setcolor(boardcolor, whitestone);
  331.       printw("%c %c: %d %c ", c, chars[CHAR_BLACK], prisoners[1], d);
  332.       setcolor(background, foreground);
  333.    } else
  334.       printw(" %c %c: %d %c    %c %c: %d %c ", a, chars[(int)
  335.                           CHAR_BLACK], prisoners[0], b, c,
  336.          chars[(int) CHAR_WHITE], prisoners[1], d);
  337.    clrtoeol();
  338. }
  339.  
  340.  
  341.  
  342. static char getKey()
  343. {
  344.    MOUINFOREC m;
  345.    for (;
  346.     ;
  347.       ) {
  348.       if (MOUcheck()) {
  349.      MOUget(&m);
  350.      if (m.buttonstat & (LEFTBPRESS | RIGHTBPRESS))
  351.         return ' ';
  352.       } if (kbhit())
  353.      return getch();
  354.    }
  355. }
  356.  
  357.  
  358. int iskey()
  359. {
  360.    _AH = 1;
  361.    geninterrupt(0x16);
  362.    return (!(_FLAGS & 64));
  363. }
  364.  
  365.  
  366.  
  367. char altkey[] = "qwertyuiop????asdfghjkl?????zxcvbnm";
  368.  
  369.  
  370. char getKeyEdit()
  371. {
  372.    MOUINFOREC m;
  373.    int key;
  374.  
  375.    for (;
  376.     ;
  377.       ) {
  378.       if (MOUcheck())
  379.      MOUget(&m);
  380.       if (iskey()) {
  381.      _AX = 0;
  382.      geninterrupt(0x16);
  383.      if (_AL == ESC) {
  384.         _AX = 0;
  385.         geninterrupt(0x16);
  386.         key = _AL;
  387.         return 128 | key;
  388.      }
  389.      if (_AL)
  390.         return _AL;
  391.      key = _AH;
  392.      switch (key) {
  393.         case 77:
  394.            return edcmds[EDRIGHT];
  395.         case 75:
  396.            return edcmds[EDLEFT];
  397.         case 80:
  398.            return edcmds[EDDOWN];
  399.         case 72:
  400.            return edcmds[EDUP];
  401.         case 79:
  402.            return edcmds[EDEOL];
  403.         case 71:
  404.            return edcmds[EDBOL];
  405.         case 82:
  406.            return edcmds[EDTINS];
  407.         case 83:
  408.            return edcmds[EDDEL];
  409.         case 73:
  410.            return edcmds[EDPUP];
  411.         case 81:
  412.            return edcmds[EDPDOWN];
  413.         case 119:        /* ctrl home */
  414.            return 0;
  415.         case 117:        /* ctrl end */
  416.            return edcmds[EDDEOL];
  417.         case 132:        /* Ctrl Pg Up */
  418.            return edcmds[EDBOC];
  419.         case 118:        /* Ctrl Pg Dn */
  420.            return edcmds[EDEOC];
  421.         default:
  422.            if (key >= 16 && key <= 50) {
  423.           return altkey[key - 16] | 128;
  424.            }
  425.            return 0;
  426.      }
  427.       }
  428.    }
  429. }
  430.  
  431.  
  432.  
  433. char getKeyLine()
  434. {
  435.    static lastmouse = 0;
  436.    MOUINFOREC m;
  437.    for (;
  438.     ;
  439.       ) {
  440.       if (MOUcheck()) {
  441.      MOUget(&m);
  442.      if (m.buttonstat & LEFTBPRESS) {
  443.         if (lastmouse == 1) {
  444.            lastmouse = 0;
  445.            return '\r';
  446.         }
  447.         if (!lastmouse) {
  448.            lastmouse = 1;
  449.            return 'y';
  450.         }
  451.         lastmouse = 0;
  452.         return '\b';
  453.      }
  454.      if (m.buttonstat & RIGHTBPRESS) {
  455.         if (lastmouse == 2) {
  456.            lastmouse = 0;
  457.            return '\r';
  458.         }
  459.         if (!lastmouse) {
  460.            lastmouse = 2;
  461.            return 'n';
  462.         }
  463.         lastmouse = 0;
  464.         return '\b';
  465.      }
  466.       }
  467.       if (kbhit()) {
  468.      lastmouse = 0;
  469.      return getch();
  470.       }
  471.    }
  472. }
  473.  
  474.  
  475. static char scoring = 0;
  476.  
  477.  
  478. void printmodes()
  479. {
  480.    setcolor(menubg, menufg);
  481.    move(0, 4);
  482.    printw("  help   quit %7s%7s%7s", stoneModeName[stonemode], branchModeName[branchmode], menumode[menu]);
  483.    setcolor(background, foreground);
  484.    setCursor(xcur, ycur);
  485. }
  486.  
  487.  
  488. int getmenu(cx)
  489. int cx;
  490. {
  491.    int i;
  492.    for (i = 0;
  493.     i < 5;
  494.     i++)
  495.       if (cx <= menubounds[menu][i].top && cx >= menubounds[menu][i].bottom)
  496.      return (menu << 4) + i;
  497.    return -1;
  498. }
  499.  
  500.  
  501. int checkLeftButton(cx, cy)
  502. int cx, cy;
  503. {
  504.    if (cy == COMMAND_Y && cx >= COMMAND_X) {
  505.       cx -= COMMAND_X;
  506.       if (cx < 10)
  507.      return '?';
  508.       if (cx >= 15 && cx < 20)
  509.      return keys[C_TUTORSWAP];
  510.       if (cx >= 24 && cx < 29)
  511.      return keys[C_SAVESHORT];
  512.       cx += COMMAND_X;
  513.    }
  514.    if (cy >= COMMENT_Y && cy < COMMENT_Y + COMMENT_HIGH && cx >= COMMENT_X)
  515.       return keys[C_EDCOMMENT];
  516.    if ((cy == 22) && usecolor) {
  517.       switch (getmenu(cx)) {
  518.      case 0x01:
  519.         return keys[C_BEGINNING];
  520.      case 0x02:
  521.         return keys[C_END];
  522.      case 0x03:
  523.         return keys[C_DOWNFORK];
  524.      case 0x04:
  525.         return keys[C_SEARCHCOMMENT];
  526.  
  527.      case 0x11:
  528.         return keys[C_SCORE];
  529.  
  530.      case 0x12:
  531.         return keys[C_PASSMOVE];
  532.  
  533.      case 0x13:
  534.         return keys[C_TOPLAY];
  535.  
  536.  
  537.  
  538.      case 0x20:
  539.         return keys[C_INFO];
  540.      case 0x21:
  541.         return keys[C_TREECUT];
  542.      case 0x22:
  543.         return keys[C_PASTE];
  544.      case 0x23:
  545.         return keys[C_DELNODE];
  546.      case 0x24:
  547.         return keys[C_ADDVAR];
  548.  
  549.      case 0x31:
  550.         return keys[C_WRITE];
  551.      case 0x32:
  552.         return keys[C_LOAD];
  553.      case 0x33:
  554.         return keys[C_NEXTFILE];
  555.      case 0x34:
  556.         return keys[C_BACKFILE];
  557.       }
  558.    }
  559.    if (cy == STATUS_Y && cx >= STATUS_X) {
  560.       return keys[filecount ? C_NEXTFILE : C_LOAD];
  561.    }
  562.    if ((cy == 0) && usecolor) {
  563.       MOUhide();
  564.       switch ((cx - 4) / 7) {
  565.      case 0:
  566.         MOUshow();
  567.         return '?';
  568.      case 1:
  569.         MOUshow();
  570.         return keys[C_QUIT];
  571.      case 2:
  572.         stonemode = !stonemode;
  573.         printmodes();
  574.         break;
  575.      case 3:
  576.         branchmode = !branchmode;
  577.         printmodes();
  578.         break;
  579.      case 4:
  580.         menu++;
  581.         menu %= MENUITEMS;
  582.         printmodes();
  583.         setcolor(menubg, menufg);
  584.         mvaddstr(22, 6, menulines[menu]);
  585.         setcolor(background, foreground);
  586.         setCursor(xcur, ycur);
  587.         break;
  588.       }
  589.       MOUshow();
  590.    }
  591.    if (scoring && cy == 23 && cx <= 39) {
  592.       if (cx <= 12)
  593.      return '\r';
  594.       if (cx <= 24)
  595.      return 0;
  596.       else if (cx <= 32)
  597.      return 'u';
  598.       else if (cx <= 39)
  599.      return 'q';
  600.    }
  601.    if (!((cx - LEFT) & 1) && inRange(cy - TOP, (cx - LEFT) / 2)) {
  602.       xcur = (cx - LEFT) / 2;
  603.       ycur = (cy - TOP);
  604.       return stonemode || scoring ? 32 : keys[C_ADDLETTER];
  605.    }
  606.    if ((cy == 23) && ((cx >= 48 && cx <= 54 && curPlayer != t_Black) ||
  607.               (cx >= 59 && cx <= 67 && curPlayer == t_Black)))
  608.       return keys[C_TOGGLESTONE];
  609.    if (cx == COMMENT_X - 1 && cy == COMMENT_Y)
  610.       return keys[C_COMMENTSCROLLUP];
  611.    if (cx == TREE_X - 1 && cy == TREE_Y + 1)
  612.       return keys[C_TREESCROLLUP];
  613.    if (cx == TREE_X - 1 && cy == TREE_Y + TREEHIGH - 1)
  614.       return keys[C_TREESCROLLDOWN];
  615.    if (cx == COMMENT_X - 1 && cy == COMMENT_Y + COMMENT_HIGH - 1)
  616.       return keys[C_COMMENTSCROLLDOWN];
  617.    if (cx >= TREE_X && cy > TREE_Y && cy < TREE_Y + TREEHIGH)
  618.       return branchmode ? 'A' + treeLine + cy - TREE_Y - 1 : keys[C_WALKDOWN];
  619.    if (cy == TREE_Y) {
  620.       if (cx > TREE_X + 10)
  621.      return keys[C_ADDNAME];
  622.       if (cx > TREE_X + 1)
  623.      return keys[C_GOTO];
  624.    }
  625.    return 0;
  626. }
  627.  
  628.  
  629.  
  630.  
  631. int checkRightButton(cx, cy)
  632. int cx, cy;
  633. {
  634.  
  635.    if (scoring)
  636.       return '\r';
  637.    if ((cy == 22) && usecolor) {
  638.       if (getmenu(cx) == 3)
  639.      return keys[C_UPFORK];
  640.       if (getmenu(cx) == 4)
  641.      return keys[C_SEARCHBACKCOMMENT];
  642.    }
  643.    if ((!((cx - LEFT) & 1))
  644.        && inRange(cy - TOP, (cx - LEFT) / 2)) {
  645.       xcur = (cx - LEFT) / 2;
  646.       ycur = (cy - TOP);
  647.       return keys[stonemode ?
  648.           (curPlayer == t_Black ? C_ADDBLACK : C_ADDWHITE)
  649.           :
  650.           C_ADDMARK];
  651.    }
  652.    if (cy == STATUS_Y && cx >= STATUS_X && filecount) {
  653.       return keys[C_BACKFILE];
  654.    }
  655.    if (cx >= TREE_X && cy > TREE_Y && cy < TREE_Y + TREEHIGH)
  656.       return keys[branchmode ? C_UP : C_WALKUP];
  657.    return 0;
  658. }
  659.  
  660.  
  661.  
  662.  
  663. char getKeyIdle()
  664. {
  665.    int key;
  666.    MOUINFOREC m;
  667.  
  668.    MOUshow();
  669.    for (;;) {
  670.       if (MOUcheck()) {
  671.      MOUget(&m);
  672.      if ((m.buttonstat & LEFTBPRESS) && (key = checkLeftButton(m.cx, m.cy))) {
  673.         MOUhide();
  674.         return key;
  675.      }
  676.      if ((m.buttonstat & RIGHTBPRESS) && (key = checkRightButton(m.cx, m.cy))) {
  677.         MOUhide();
  678.         return key;
  679.      }
  680.       }
  681.       if (kbhit()) {
  682.      MOUhide();
  683.      return getch();
  684.       }
  685.    }
  686. }
  687.  
  688.  
  689.  
  690. char getKeyScore()
  691. {
  692.    char temp;
  693.    scoring = 1;
  694.    temp = getKeyIdle();
  695.    scoring = 0;
  696.    return temp;
  697. }
  698.  
  699.  
  700.  
  701.  
  702. static void initAscii()
  703. {
  704.    char stone[] =
  705.    {0x00, 0x00, 0x00, 0x7E, 0xff, 0xff, 0xff, 0xff,
  706.     0xff, 0xff, 0xff, 0xff, 0x7E, 0x00, 0x00, 0x00};
  707.    char terr[] =
  708.    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x7e,
  709.     0x7e, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  710.    char hoshi[] =
  711.    {0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
  712.     0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18};
  713.  
  714.    /* note 0x3c and 0xff for dot in hoshi are set below. */
  715.  
  716.    unsigned char *dest, far * font;
  717.    int i, j, k;
  718.    unsigned char myfont[256][16];
  719.    extern vgapresent;
  720.    struct text_info info;
  721.  
  722.    gettextinfo(&info);
  723.    fixfont = info.screenheight == 50 || info.screenheight == 43;
  724.  
  725.    textmode(C80);
  726.  
  727.    if (graphics && isegavga()) {
  728.       _AX = 0x1003;
  729.       _BX = 0;
  730.       geninterrupt(0x10);    /* enable high intensity background */
  731.  
  732.       if (vgapresent) {
  733.      _AX = 0x1010;
  734.      _BX = 0x0014;
  735.      _CH = bgreen;
  736.      _CL = bblue;
  737.      _DH = bred;
  738.  
  739.      geninterrupt(0x10);    /* change color 6 */
  740.       }
  741.       font = getfont();
  742.  
  743.       /* adaptively set hoshi point character */
  744.       for (k = 0; k < 16; k++)
  745.      if (*(font + 197 * 16 + k) == 255)
  746.         break;
  747.       if (k == 16)
  748.      k = 9;
  749.       for (i = k - 2; i <= k + 2; i++)
  750.      hoshi[i] = 0x3c;
  751.       hoshi[k] = 0xff;
  752.  
  753.       for (dest = (char *) myfont, k = 0; k < 16 * 256; k++, dest++, font++)
  754.      *dest = *font;
  755.       for (k = 0; k < 16; k++) {
  756.      myfont[2][k] = stone[k];
  757.      myfont[15][k] = terr[k];
  758.      myfont[199][k] = hoshi[k];
  759.       }
  760.       setfont((unsigned char far *) myfont);
  761.       strcpy(chars, graphchar);
  762.       usecolor = 1;
  763.    } else
  764.       graphics = 0;
  765.    if ((!graphics) && usecolor)
  766.       strcpy(chars + CHAR_VERT, graphchar + CHAR_VERT);
  767.  
  768.    MOUinit();
  769.    MOUhide();
  770.    fixkeys();
  771.    fixedkeys();
  772. }
  773.  
  774.  
  775.  
  776. static void plotMarkAscii(b, i, j)
  777. pBoard b;
  778. int i, j;
  779. {
  780.    void plotPieceAscii();
  781.    int sc;
  782.  
  783.    if (usecolor) {
  784.       sc = boardcolor;
  785.       boardcolor = markcolor;
  786.    } else
  787.       textattr(inverseFlag ? 0x07 : 0x70);
  788.    plotPieceAscii(b, i, j);
  789.    if (usecolor) {
  790.       boardcolor = sc;
  791.    } else
  792.       textattr(inverseFlag ? 0x70 : 0x07);
  793. }
  794.  
  795.  
  796.  
  797. static command specialKeysIdle(c)
  798. char c;
  799. {
  800.    if (!c) {
  801.       c = getKey();
  802.       switch (c) {
  803.      case 77:
  804.         return (cursorkey == 0 || (cursorkey == 2 && tutor)) ? C_DOWN : C_CURRIGHT;
  805.      case 75:
  806.         return (cursorkey == 0 || (cursorkey == 2 && tutor)) ? C_UP : C_CURLEFT;
  807.      case 79:
  808.         return (cursorkey == 0 || (cursorkey == 2 && tutor)) ? 0 : C_DOWNLEFT;
  809.      case 80:
  810.         return (cursorkey == 0 || (cursorkey == 2 && tutor)) ? C_DOWNFORK : C_CURDOWN;
  811.      case 71:
  812.         return (cursorkey == 0 || (cursorkey == 2 && tutor)) ? 0 : C_UPLEFT;
  813.      case 72:
  814.         return (cursorkey == 0 || (cursorkey == 2 && tutor)) ? C_UPFORK : C_CURUP;
  815.      case 81:
  816.         return (cursorkey == 0 || (cursorkey == 2 && tutor)) ? C_SEARCHCOMMENT : C_DOWNRIGHT;
  817.      case 73:
  818.         return (cursorkey == 0 || (cursorkey == 2 && tutor)) ? C_SEARCHBACKCOMMENT : C_UPRIGHT;
  819.      default:
  820.         return (command) 0;
  821.       }
  822.    } else
  823.       return (command) 0;
  824. }
  825.  
  826.  
  827.  
  828.  
  829. static void drawPiece(i, j, c)
  830. int i, j;
  831. char c;
  832. {
  833.    move(TOP + j, LEFT + 2 * i);
  834.    setcolor(boardcolor, blackstone);
  835.  
  836.    if (c == chars[(int) CHAR_NOTHING]) {
  837.       if (graphics) {
  838.      if (i == 0) {
  839.         if (j == boardsize - 1)
  840.            c = '\300';
  841.         else if (j == 0)
  842.            c = '\332';
  843.         else
  844.            c = '\303';
  845.      } else if (i == boardsize - 1) {
  846.         if (j == boardsize - 1)
  847.            c = '\331';
  848.         else if (j == 0)
  849.            c = '\277';
  850.         else
  851.            c = '\264';
  852.      } else if (j == 0)
  853.         c = '\302';
  854.      else if (j == boardsize - 1)
  855.         c = '\301';
  856.       }
  857.    }
  858.    if (usecolor) {
  859.       if (c == chars[(int) CHAR_WHITE]) {
  860.      c = chars[(int) CHAR_BLACK];
  861.      setcolor(boardcolor, whitestone);
  862.       }
  863.       if (c == chars[(int) CHAR_WHITETERR]) {
  864.      c = chars[(int) CHAR_BLACKTERR];
  865.      setcolor(boardcolor, whitestone);
  866.       }
  867.       if (c == chars[(int) CHAR_DAME]) {
  868.      setcolor(boardcolor, damecolor);
  869.       }
  870.       if (c >= 'a' && c <= 'z')
  871.      setcolor(boardcolor, lettercolor);
  872.    }
  873.    addch(c);
  874.    setcolor(background, foreground);
  875. }
  876.  
  877.  
  878. static void initBoardAscii()
  879. {
  880.    int i, j;
  881.  
  882.    if (!usecolor) {
  883.       if (inverseFlag)
  884.      textattr(0x70);
  885.       else
  886.      textattr(0x07);
  887.    }
  888.    if (inverseFlag && usecolor) {
  889.       inverseFlag = foreground;
  890.       foreground = background;
  891.       background = inverseFlag;
  892.       menubg = background;
  893.       inverseFlag = 0;
  894.    }
  895.    setcolor(background, foreground);
  896.    clrscr();
  897.    if (mouseinstalled & usecolor) {
  898.       printmodes();
  899.       setcolor(menubg, menufg);
  900.       mvaddstr(22, 6, menulines[menu]);
  901.       setcolor(background, foreground);
  902.    }
  903.    if (usecolor) {
  904.       setcolor(boardcolor, blackstone);
  905.       for (i = LEFT + 1; i < LEFT + boardsize * 2 - 2; i += 2)
  906.      for (j = TOP; j < TOP + boardsize; j++)
  907.         mvaddch(j, i, graphics ? '\304' : ' ');
  908.    }
  909.    for (i = boardsize; i--;) {
  910.  
  911.       /* left */
  912.       set_inverse();
  913.       move(TOP + i, LEFT - 1);
  914.       setcolor(boardcolor, background);
  915.       addch(chars[(int) CHAR_VERT]);
  916.  
  917.       setcolor(background, boardcolor);
  918.       /* top */
  919.       move(TOP - 1, LEFT + i * 2 - 1);
  920.       printw("%c%c", chars[(int) CHAR_HORIZ], chars[(int) CHAR_HORIZ]);
  921.  
  922.       /* bottom */
  923.       move(TOP + boardsize, LEFT + i * 2 - 1);
  924.       printw("%c%c", chars[(int) CHAR_HORIZ], chars[(int) CHAR_HORIZ]);
  925.  
  926.       /* right */
  927.       move(TOP + i, LEFT + boardsize * 2 - 1);
  928.       setcolor(background, boardcolor);
  929.       addch(chars[(int) CHAR_VERT]);
  930.       setcolor(background, foreground);
  931.  
  932.       unset_inverse();
  933.  
  934.       /* right */
  935.       printw("%-2d%c", boardsize - i, '\263');
  936.  
  937.       /* left */
  938.       move(TOP + i, LEFT - 3);
  939.       printw("%2d", boardsize - i);
  940.  
  941.  
  942.       /* top */
  943.       move(TOP - 2 + usecolor, LEFT + i * 2);
  944.       addch(xAxisChars[i]);
  945.  
  946.       /* bottom */
  947.       move(TOP + boardsize + 1 - usecolor, LEFT + i * 2);
  948.       addch(xAxisChars[i]);
  949.  
  950.       for (j = boardsize; j--;)
  951.      drawPiece(i, j, boardPiece(i, j));
  952.    }
  953.    set_inverse();
  954.    move(TOP - 1, LEFT - 1);
  955.    addch(chars[(int) CHAR_UPLEFT]);
  956.    move(TOP + boardsize, LEFT - 1);
  957.    addch(chars[(int) CHAR_DOWNLEFT]);
  958.    move(TOP - 1, LEFT + boardsize * 2 - 1);
  959.    addch(chars[(int) CHAR_UPRIGHT]);
  960.    move(TOP + boardsize, LEFT + boardsize * 2 - 1);
  961.    addch(chars[(int) CHAR_DOWNRIGHT]);
  962.    unset_inverse();
  963.    mvaddstr(COMMAND_Y, COMMAND_X, helpMsg);
  964.    printstatus(name_buf);
  965. }
  966.  
  967. static char *mouseHelp[] =
  968. {
  969.    "                                 Mouse Commands",
  970.    "Click on           (left)=left click         (right)=right click",
  971.    " board        \"stone\" mode: makes a move (left)  sets stone (right)",
  972.    "              \"mark\" mode: places letter (left)  places mark (right)",
  973.    "",
  974.    " \"Node #\"     Goes to node by number",
  975.    " node name    Sets node name",
  976.    " comment      Edits the comment",
  977.    " \"+\" or \"-\"   (next to comment or variations) scroll the comment/variations",
  978.    " filename     Next (left) or previous (right) file, or load file.",
  979.    " variation    Go to that variation (left) back up (right)",
  980.    " long/short   Toggles save file format",
  981.    " read/edit/tutor Toggles tutor mode",
  982.    "",
  983. "When scoring a game, right button scores, left buttons kills, and clicking ",
  984.    "on words at the bottom of the screen executes whatever function.",
  985.    "",
  986.    "Mouse clicks will remove error messages.",
  987.    "At a (y/n) prompt, double click left to respond yes, double click right for no",
  988.    "",
  989.    "Menus above and below the board provide other functions",
  990.    "",
  991.    "                         Hit a key (or click) to continue"};
  992.  
  993. static char *ibmHelp[] =
  994. {"               Cursor Keys",
  995.  "",
  996.  "To move the cursor on the board",
  997.  "you must use the number keys",
  998.  "(have num lock on)",
  999.  "",
  1000.  "The cursor keys have the following functions:",
  1001.  "",
  1002.  "right  down tree like ",
  1003.  "left   up tree like ",
  1004.  "up     previous variation branch",
  1005.  "down   next variation branch",
  1006.  "pgup   last comment",
  1007.  "pgdn   next comment",
  1008.  "",
  1009.  "         press a key"
  1010. };
  1011.  
  1012.  
  1013.  
  1014. static void specialHelp()
  1015. {
  1016.    int i;
  1017.    char ch;
  1018.    clrscr();
  1019.    for (i = 0; i < sizeof(ibmHelp) / sizeof(char *); i++) {
  1020.       move(i + 5, 14);
  1021.       cputs(ibmHelp[i]);
  1022.       if (i == 8)
  1023.      addch(keys[C_DOWN]);
  1024.       if (i == 9)
  1025.      addch(keys[C_UP]);
  1026.    }
  1027.    ch = getKey();
  1028.    if (ch != '\n' && ch != '\r' && mouseinstalled) {
  1029.       clrscr();
  1030.       for (i = 0; i < sizeof(mouseHelp) / sizeof(char *); i++) {
  1031.      move(i, 0);
  1032.      if (i == 4) {
  1033.         printw(" ");
  1034.         if (usecolor)
  1035.            setcolor(boardcolor, blackstone);
  1036.         printw(" %c: ?? ", chars[CHAR_BLACK]);
  1037.         if (usecolor)
  1038.            setcolor(background, foreground);
  1039.         printw("      selects black stones, ");
  1040.         if (usecolor) {
  1041.            setcolor(boardcolor, whitestone);
  1042.            printw(" %c: ?? ", chars[CHAR_BLACK]);
  1043.            setcolor(background, foreground);
  1044.         } else
  1045.            printw(" %c: ?? ", chars[CHAR_WHITE]);
  1046.         printw(" selects white stones.");
  1047.  
  1048.  
  1049.      }
  1050.      cputs(mouseHelp[i]);
  1051.       }
  1052.       getKey();
  1053.       clrscr();
  1054.       printmodes();
  1055.  
  1056.  
  1057.       mvaddstr(1, 20, " \263      \263      \300\304 indicates menu chosen.  Click here to");
  1058.       mvaddstr(2, 20, " \263      \263         switch to a different menu.");
  1059.       mvaddstr(3, 20, " \263      \300\304 type of movement through game tree (see previous");
  1060.       move(4, 20);
  1061.       printw(" \263         screen).  Branch for movement like %c and %c, ", keys[C_DOWN], keys[C_UP]);
  1062.       move(5, 20);
  1063.       printw(" \263         walk for movement like %c and %c. ", keys[C_WALKDOWN], keys[C_WALKUP]);
  1064.       mvaddstr(6, 20, " \300\304 Mouse button on the board sets stones or sets marks.");
  1065.       mvaddstr(7, 20, "    Click here to toggle.");
  1066.  
  1067.       setcolor(menubg, menufg);
  1068.       mvaddstr(9, 0, menulines[0]);
  1069.       setcolor(background, foreground);
  1070.       mvaddstr(10, 2, "Click on start or end to go to start of file or end of current variation.");
  1071.       mvaddstr(11, 2, "Left click on var or comment to go to next variation branch or comment.");
  1072.       mvaddstr(12, 2, "Right click to go to last variation branch or comment.");
  1073.       setcolor(menubg, menufg);
  1074.       mvaddstr(13, 0, menulines[1]);
  1075.       setcolor(background, foreground);
  1076.  
  1077.       mvaddstr(14, 2, "Click on score to score, pass to play a pass move, and player to toggle the");
  1078.       mvaddstr(15, 2, "current player with an item in the game tree.");
  1079.  
  1080.       setcolor(menubg, menufg);
  1081.       mvaddstr(16, 0, menulines[2]);
  1082.       setcolor(background, foreground);
  1083.  
  1084.       mvaddstr(17, 2, "Click on info to get info, cut or paste to cut and paste, delnode to delete a");
  1085.       mvaddstr(18, 2, "node or addvar to add a variation.");
  1086.  
  1087.       setcolor(menubg, menufg);
  1088.       mvaddstr(19, 0, menulines[3]);
  1089.       setcolor(background, foreground);
  1090.  
  1091.       mvaddstr(20, 2, "Click on save to save the game record, load to load a new file, next to go to");
  1092.       mvaddstr(21, 2, "the next file or prev to go to the previous file.");
  1093.  
  1094.       mvaddstr(23, 24, "Hit a key or click to continue.");
  1095.       getKey();
  1096.  
  1097.    }
  1098. }
  1099. SHAR_EOF
  1100. fi
  1101. if test -f 'asc_unix.inc'
  1102. then
  1103.     echo shar: "will not over-write existing file 'asc_unix.inc'"
  1104. else
  1105. cat << \SHAR_EOF > 'asc_unix.inc'
  1106. /* "mgt" Copyright (c) 1991 Shodan  */
  1107.  
  1108.  
  1109. #include <curses.h>
  1110.  
  1111. char chars[] = "@O=+-.+|-++++";
  1112. #define doredraw() clearok(stdscr, TRUE), refresh(),clearok(stdscr, FALSE)
  1113.  
  1114. #define openwin() win=subwin(stdscr,WINHIGH+1,WINWIDE+1,WINTOP,WINLEFT)
  1115. /* ,wclear(win) */
  1116. #define fixcursor()
  1117. #define specialKeysEdit(c) (c)
  1118. #define closewin() delwin(win)
  1119. #define getKey getch
  1120. #define getKeyIdle getch
  1121. #define getKeyLine getch
  1122. #define getKeyScore getch
  1123. #define specialHelp()
  1124. #define preserveScreen() WINDOW *wi;wi=newwin(0,0,0,0);overwrite(stdscr,wi);touchwin(stdscr)
  1125. #define restoreScreen() overwrite(wi,stdscr);refresh();delwin(wi)
  1126.  
  1127. /* #define saveRegion(x1,y1,dx,dy) { WINDOW *ww;
  1128.  * ww=subwin(stdscr,dy,dx,y1,x1);wi=newwin(dy,dx,y1,x1);overwrite(ww,wi);delwin(
  1129.  * ww);} #define restoreRegion(x1,y1,dx,dy)
  1130.  * overwrite(wi,stdscr);refresh();delwin(wi) */
  1131.  
  1132. #define saveRegion(a,b,c,d) wi=newwin(0,0,0,0);overwrite(stdscr,wi);touchwin(stdscr)
  1133. #define restoreRegion(a,b,c,d) restoreScreen()
  1134. #define dopris() printw(" %c %c: %d %c    %c %c: %d %c ", a, chars[(int)\
  1135.           CHAR_BLACK], prisoners[0], b, c, \
  1136.       chars[(int) CHAR_WHITE], prisoners[1], d)
  1137. #define mainwin()
  1138. #define unmainwin()
  1139.  
  1140. static char getKeyEdit()
  1141. {
  1142.    char c;
  1143.    c = getch();
  1144.    if (!edvi && (c == ESC)) {
  1145.       c = 128 | getch();
  1146.    }
  1147.    if (c == '\333') {        /* ('[' | 128) */
  1148.       c = getch();
  1149.       if (c == 'A')
  1150.      c = edcmds[EDUP];
  1151.       if (c == 'B')
  1152.      c = edcmds[EDDOWN];
  1153.       if (c == 'C')
  1154.      c = edcmds[EDRIGHT];
  1155.       if (c == 'D')
  1156.      c = edcmds[EDLEFT];
  1157.    }
  1158.    return c;
  1159. }
  1160.  
  1161. static void drawPrisoners()
  1162. {
  1163.    extern int ispl;
  1164.    char a, b, c, d;
  1165.    if (curPlayer == t_Black) {
  1166.       a = ispl ? '}' : '>';
  1167.       b = ispl ? '{' : '<';
  1168.       c = d = ' ';
  1169.    } else {
  1170.       a = b = ' ';
  1171.       c = ispl ? '}' : '>';
  1172.       d = ispl ? '{' : '<';
  1173.    }
  1174.    move(23, 50);
  1175.    printw("%c %c: %d %c    %c %c: %d %c ", a, chars[(int)
  1176.                           CHAR_BLACK], prisoners[0], b, c,
  1177.       chars[(int) CHAR_WHITE], prisoners[1], d);
  1178.    clrtoeol();
  1179. }
  1180.  
  1181.  
  1182.  
  1183. static void initAscii()
  1184. {
  1185.    fixkeys();
  1186.    fixedkeys();
  1187.    initscr();
  1188.    noecho();
  1189.    crmode();
  1190. }
  1191.  
  1192.  
  1193.  
  1194. static void plotMarkAscii(b, i, j)
  1195. pBoard b;
  1196. int i, j;
  1197. {
  1198.    void drawPiece();
  1199.    piece p;
  1200.    p = boardGet(b, i, j);
  1201.    inverseFlag = !inverseFlag;
  1202.  
  1203.    drawPiece(i, j, (p == P_NOTHING ? boardPiece(i, j) :
  1204.             (p == P_BLACK ? chars[(int) CHAR_BLACK] :
  1205.              chars[(int) CHAR_WHITE])));
  1206.    inverseFlag = !inverseFlag;
  1207. }
  1208.  
  1209. static int xpos(win)
  1210. WINDOW *win;
  1211. {
  1212.    int x, y;
  1213.    getyx(win, y, x);
  1214.    return x;
  1215. }
  1216.  
  1217.  
  1218. static int ypos(win)
  1219. WINDOW *win;
  1220. {
  1221.    int y, x;
  1222.    getyx(win, y, x);
  1223.    return y;
  1224. }
  1225.  
  1226.  
  1227. static command specialKeysIdle(c)
  1228. char c;
  1229. {
  1230.    return (command) 0;
  1231. }
  1232.  
  1233. static void set_inverse()
  1234. {
  1235.  
  1236.    if (inverseFlag)
  1237.       standout();
  1238. }
  1239.  
  1240. static void unset_inverse()
  1241. {
  1242.    standend();
  1243. }
  1244.  
  1245.  
  1246.  
  1247. static void drawPiece(i, j, c)
  1248. int i, j;
  1249. char c;
  1250. {
  1251.    move(TOP + j, LEFT + 2 * i);
  1252.    set_inverse();
  1253.    addch(c);
  1254.    unset_inverse();
  1255. }
  1256.  
  1257.  
  1258. static void initBoardAscii()
  1259. {
  1260.    int i, j;
  1261.  
  1262.    clear();
  1263.    if (inverseFlag) {
  1264.       set_inverse();
  1265.       for (i = LEFT + 1; i < LEFT + boardsize * 2 - 2; i += 2)
  1266.      for (j = TOP; j < TOP + boardsize; j++)
  1267.         mvaddch(j, i, ' ');
  1268.       unset_inverse();
  1269.    }
  1270.    for (i = boardsize; i--;) {
  1271.       /* left */
  1272.       move(TOP + i, LEFT - 3);
  1273.       printw("%2d", boardsize - i);
  1274.       set_inverse();
  1275.       addch(chars[(int) CHAR_VERT]);
  1276.  
  1277.       /* right */
  1278.       move(TOP + i, LEFT + boardsize * 2 - 1);
  1279.       addch(chars[(int) CHAR_VERT]);
  1280.       unset_inverse();
  1281.       printw("%2d", boardsize - i);
  1282.       /* printw("%2d%c", boardsize - i, chars[(int) CHAR_VERT]); */
  1283.  
  1284.       /* top */
  1285.       move(TOP - 2, LEFT + i * 2);
  1286.       addch(xAxisChars[i]);
  1287.       move(TOP - 1, LEFT + i * 2 - 1);
  1288.       set_inverse();
  1289.       printw("%c%c", chars[(int) CHAR_HORIZ], chars[(int) CHAR_HORIZ]);
  1290.  
  1291.       /* bottom */
  1292.       move(TOP + boardsize, LEFT + i * 2 - 1);
  1293.       printw("%c%c", chars[(int) CHAR_HORIZ], chars[(int) CHAR_HORIZ]);
  1294.       unset_inverse();
  1295.       move(TOP + boardsize + 1, LEFT + i * 2);
  1296.       addch(xAxisChars[i]);
  1297.       for (j = boardsize; j--;)
  1298.      drawPiece(i, j, boardPiece(i, j));
  1299.    }
  1300.    set_inverse();
  1301.    move(TOP - 1, LEFT - 1);
  1302.    addch(chars[(int) CHAR_UPLEFT]);
  1303.    move(TOP - 1, LEFT + boardsize * 2 - 1);
  1304.    addch(chars[(int) CHAR_UPRIGHT]);
  1305.    move(TOP + boardsize, LEFT - 1);
  1306.    addch(chars[(int) CHAR_DOWNLEFT]);
  1307.    move(TOP + boardsize, LEFT + boardsize * 2 - 1);
  1308.    addch(chars[(int) CHAR_DOWNRIGHT]);
  1309.    unset_inverse();
  1310.    mvaddstr(COMMAND_Y, COMMAND_X, helpMsg);
  1311.    printstatus(name_buf);
  1312. }
  1313. SHAR_EOF
  1314. fi
  1315. if test -f 'mou.c'
  1316. then
  1317.     echo shar: "will not over-write existing file 'mou.c'"
  1318. else
  1319. cat << \SHAR_EOF > 'mou.c'
  1320. /*****************************************************************************
  1321.  * PROJECT:  Mouse routines with 'real' graphic cursor in text mode.
  1322.  *****************************************************************************
  1323.  * MODULE:  MOU.C
  1324.  *****************************************************************************
  1325.  * DESCRIPTION:
  1326.  *   Main file for the mouse routines.
  1327.  *
  1328.  *****************************************************************************
  1329.  * MODIFICATION NOTES:
  1330.  *    Date     Version Author Comment
  1331.  * 15-Mar-1991     1.04     dk   Added function to set mouse position.  From a
  1332.  *                  suggestion by Gary Tepel.
  1333.  * 17-Jan-1991     1.02     ta   Diffs sent to me from Tony Acero for middle
  1334.  *                  mouse button support.
  1335.  * 10-Jan-1991     1.01     dk   Made points variable global throughout module.
  1336.  * 07-Jan-1991     1.00     dk   Fixed bugs and set up for release to Usenet.
  1337.  * 26-Oct-1990     0.00     dk   Initial file.
  1338.  *****************************************************************************
  1339.  *
  1340.  * DISCLAIMER:
  1341.  *
  1342.  * Programmers may incorporate any or all code into their programs,
  1343.  * giving proper credit within the source. Publication of the
  1344.  * source routines is permitted so long as proper credit is given
  1345.  * to Dave Kirsch.
  1346.  *
  1347.  * Copyright (C) 1990, 1991 by Dave Kirsch.  You may use this program, or
  1348.  * code or tables extracted from it, as desired without restriction.
  1349.  * I can not and will not be held responsible for any damage caused from
  1350.  * the use of this software.
  1351.  *
  1352.  * Author: a563@mindlink.UUCP  -or-  Zoid@cc.sfu.ca
  1353.  *
  1354.  *****************************************************************************
  1355.  * This source works with Turbo C 2.0 and MSC 6.0 and above.
  1356.  *****************************************************************************/
  1357.  
  1358. #ifdef __TURBOC__
  1359. #pragma inline
  1360. #endif
  1361.  
  1362. #include <stdio.h>
  1363. #include <dos.h>
  1364. #include <stdlib.h>
  1365. #include <string.h>
  1366.  
  1367. #include "mou.h"
  1368.  
  1369. #define HEIGHT 16
  1370.  
  1371. int vgapresent=0;
  1372. word mousehidden = 0;           /* Is the mouse on? Additive flag */
  1373. mouseboolean mouseinstalled = FALSE; /* Is the mouse installed? */
  1374.  
  1375. volatile word mousex=0, mousey=0; /* Character position of mouse */
  1376.  
  1377. #ifndef __TURBOC__
  1378. STATIC word _based(_segname("_CODE")) DGroupSeg;
  1379. #endif
  1380.  
  1381. STATIC volatile word mbufin = 0, mbufout = 0; /* Mouse buffer pointers */
  1382.  
  1383. STATIC word mousefreeze = 0;           /* Is mouse frozen in place? */
  1384.  
  1385. STATIC MOUINFOREC mbuf[MOUSEBUFFERSIZE]; /* Mouse buffer */
  1386.  
  1387. /* Save information for non EGA/VGA */
  1388. STATIC word oldword;
  1389. STATIC word newword;
  1390. STATIC mouseboolean saved = FALSE;
  1391. STATIC word oldmx, oldmy;
  1392.  
  1393. /* Save information for EGA/VGA displays */
  1394.   mouseboolean egavga = FALSE; /* Do we have an EGA/VGA adapter? */
  1395. STATIC byte savechars[3][3]; /* The saved characters we overwrote */
  1396. STATIC dword mousecursormask[HEIGHT] =  {
  1397.   0x00000000L,  /*0000000000000000*/
  1398.   0x40000000L,  /*0100000000000000*/
  1399.   0x60000000L,  /*0110000000000000*/
  1400.   0x70000000L,  /*0111000000000000*/
  1401.   0x78000000L,  /*0111100000000000*/
  1402.   0x7c000000L,  /*0111110000000000*/
  1403.   0x7e000000L,  /*0111111000000000*/
  1404.   0x7f000000L,  /*0111111100000000*/
  1405.   0x7f800000L,  /*0111111110000000*/
  1406.   0x7f000000L,  /*0111111100000000*/
  1407.   0x7c000000L,  /*0111110000000000*/
  1408.   0x46000000L,  /*0100011000000000*/
  1409.   0x06000000L,  /*0000011000000000*/
  1410.   0x03000000L,  /*0000001100000000*/
  1411.   0x03000000L,  /*0000001100000000*/
  1412.   0x00000000L   /*0000000000000000*/
  1413. };
  1414.  
  1415. STATIC dword mousescreenmask[HEIGHT] =  {
  1416.   0x3fffffffL,  /*0011111111111111*/
  1417.   0x1fffffffL,  /*0001111111111111*/
  1418.   0x0fffffffL,  /*0000111111111111*/
  1419.   0x07ffffffL,  /*0000011111111111*/
  1420.   0x03ffffffL,  /*0000001111111111*/
  1421.   0x01ffffffL,  /*0000000111111111*/
  1422.   0x00ffffffL,  /*0000000011111111*/
  1423.   0x007fffffL,  /*0000000001111111*/
  1424.   0x003fffffL,  /*0000000000111111*/
  1425.   0x007fffffL,  /*0000000001111111*/
  1426.   0x01ffffffL,  /*0000000111111111*/
  1427.   0x10ffffffL,  /*0001000011111111*/
  1428.   0xb0ffffffL,  /*1011000011111111*/
  1429.   0xf87fffffL,  /*1111100001111111*/
  1430.   0xf87fffffL,  /*1111100001111111*/
  1431.   0xfcffffffL   /*1111110011111111*/
  1432. };
  1433.  
  1434. STATIC byte chardefs[32 * 9]; /* 9 character definitons. */
  1435. STATIC word mousepx, mousepy; /* Mouse pixel coordinates */
  1436.  
  1437. STATIC mouseboolean conditionalhidemouse = FALSE;
  1438. STATIC word conx1, cony1, conx2, cony2;
  1439.  
  1440. STATIC word vseg; /* Segment of video ram. */
  1441. STATIC word mcols, mrows;
  1442. STATIC byte savevmode;
  1443. STATIC word points;
  1444.  
  1445. STATIC word maxx, maxy;
  1446.  
  1447. STATIC mouseboolean desqview = FALSE;
  1448.  
  1449. #define POKEATTRIB(x, y, a) pokeb(vseg, (y) * (mcols * 2) + ((x) << 1) + 1, a)
  1450. #define PEEKATTRIB(x, y)    peekb(vseg, (y) * (mcols * 2) + ((x) << 1) + 1)
  1451.  
  1452. #define POINTS *((byte far *) 0x00000485)
  1453. #define COLS *((byte far *) 0x0040004AL)
  1454. #define ROWS *((byte far *) 0x00400084L)
  1455.  
  1456. #define DEFCHAR 0xd0
  1457.  
  1458. /*********************************************************************/
  1459. /* Mon 07-Jan-1991 - dk                                              */
  1460. /*                                                                   */
  1461. /*  Plot the cursor on the screen, save background, draw grid, etc.  */
  1462. /*                                                                   */
  1463. /*********************************************************************/
  1464. PRIVATE void LOCAL FAST plotegavgacursor(word func)
  1465. {
  1466. word off;
  1467. word width, height, i, j;
  1468. word disp;
  1469. word x = 0, y = 0;
  1470. static word lsavex = 0, lsavey = 0;
  1471.  
  1472.   switch (func) {
  1473.     case 0 : /* erase grid, put back save info */
  1474.       x = lsavex;
  1475.       y = lsavey;
  1476.       break;
  1477.     case 1 : /* draw grid */
  1478.       x = mousex;
  1479.       y = mousey;
  1480.       break;
  1481.     case 2 : /* save grid */
  1482.       lsavex = x = mousex;
  1483.       lsavey = y = mousey;
  1484.       break;
  1485.   }
  1486.  
  1487.   width = mcols - x;
  1488.   if (width > 3)
  1489.     width = 3;
  1490.   height = mrows - y;
  1491.   if (height > 3)
  1492.     height = 3;
  1493.  
  1494.   off = y * (mcols * 2) + x * 2;
  1495.   disp = (mcols * 2) - width * 2;
  1496.  
  1497.   switch (func) {
  1498.     case 0 : /* erase grid, put back save info */
  1499.       for (i = 0; i < height; i++, off += disp)
  1500.         for (j = 0; j < width; j++, off += 2)
  1501.           pokeb(vseg, off, savechars[i][j]);
  1502.       break;
  1503.     case 1 : /* draw grid. */
  1504.       for (i = 0; i < height; i++, off += disp)
  1505.         for (j = 0; j < width; j++, off += 2)
  1506.           pokeb(vseg, off, DEFCHAR + i * 3 + j);
  1507.       break;
  1508.     case 2 : /* save grid. */
  1509.       for (i = 0; i < height; i++, off += disp)
  1510.         for (j = 0; j < width; j++, off += 2)
  1511.           savechars[i][j] = peekb(vseg, off);
  1512.       break;
  1513.   }
  1514. }
  1515.  
  1516. PRIVATE void LOCAL FAST drawegavgacursor(void)
  1517. {
  1518. word off;
  1519. word i, j;
  1520. word s1, s2, s3;
  1521. dword *defs;
  1522. dword *masks;
  1523. word shift;
  1524. dword addmask;
  1525.  
  1526.   plotegavgacursor(2); /* Save current grid that is there. */
  1527.  
  1528.   /* Time for some assembler.  Program the EGA/VGA Sequencer and Graphics
  1529.      Controller for direct access to the character definition tables.
  1530.      Then read in the definitions for the characters we are changing, AND
  1531.      the screen mask, then OR the cursor mask to them.  Then copy those
  1532.      defintions into the location of the mouse cursor defintions
  1533.      and set the Sequencer and Graphics Controller back to normal <whew!>.
  1534.   */
  1535.  
  1536.   /* Program the Sequencer */
  1537.  
  1538.   asm pushf; /* Disable interrupts */
  1539.   asm cli;
  1540.   asm mov dx, 3c4h; /* Sequencer port address */
  1541.   asm mov ax, 0704h; /* Sequential addressing */
  1542.   asm out dx, ax;
  1543.  
  1544.   /* Program the Graphics Controller */
  1545.   asm mov dx, 3ceh; /* Graphics Controller port address */
  1546.   asm mov ax, 0204h; /* Select map 2 for CPU reads */
  1547.   asm out dx, ax;
  1548.   asm mov ax, 0005h; /* Disable odd-even addressing */
  1549.   asm out dx, ax;
  1550.   asm mov ax, 0406h; /* Map starts at A000:0000 (64K mode) */
  1551.   asm out dx, ax;
  1552.   asm popf;
  1553.  
  1554.   /* Ok, now we have direct access to the character defintion tables, copy
  1555.      over the defintions for the characters we are changing */
  1556.  
  1557.   off = 0;
  1558.   for (i = 0; i < 9; i += 3) { /* Grid is three characters high. */
  1559.     s1 = ((byte *)savechars)[i    ] * 32;
  1560.     s2 = ((byte *)savechars)[i + 1] * 32;
  1561.     s3 = ((byte *)savechars)[i + 2] * 32;
  1562.     for (j = 0; j < points; j++) {
  1563.       off++; /* 4th byte, that we don't need. */
  1564.       chardefs[off++] = peekb(0xa000, s3++);
  1565.       chardefs[off++] = peekb(0xa000, s2++);
  1566.       chardefs[off++] = peekb(0xa000, s1++);
  1567.     }
  1568.   }
  1569.  
  1570.   /* Ok, we've got the defintions for the characters that we are drawing the
  1571.      cursor on.  AND the screen mask and OR the cursor mask to them, thereby
  1572.      'drawing' the cursor.  Since the cursor is 16 pixels wide and 16 pixels
  1573.      high, we have to save a 3 by 3 character grid where the mouse cursor is
  1574.      going.  We use dwords (32 bits) to do the bit AND and OR.  This could
  1575.      be made alot faster on a 386 by using 32 bit registers. */
  1576.  
  1577.   shift = mousepx % 8;
  1578.   addmask = 0xff000000L << (8 - shift);
  1579.  
  1580.   masks = mousescreenmask;
  1581.   defs = ((dword *)chardefs) + mousepy % points;
  1582.   for (i = 0; i < HEIGHT; i++)
  1583.     *defs++ &= (*masks++ >> shift) | addmask;
  1584.  
  1585.   masks = mousecursormask;
  1586.   defs = ((dword *)chardefs) + mousepy % points;
  1587.   for (i = 0; i < HEIGHT; i++)
  1588.     *defs++ |= *masks++ >> shift;
  1589.  
  1590.   /* Ok, Everything is setup, now copy the modifed character definitions
  1591.      to their new location. */
  1592.  
  1593.   asm mov dx, 3c4h; /* Sequencer port address */
  1594.   asm mov ax, 0402h; /* CPU writes only to map 2 */
  1595.   asm out dx, ax;
  1596.  
  1597.   off = 0;
  1598.   for (i = 0; i < 9; i += 3) { /* Grid is three characters high. */
  1599.     s1 = (DEFCHAR + i    ) * 32;
  1600.     s2 = (DEFCHAR + i + 1) * 32;
  1601.     s3 = (DEFCHAR + i + 2) * 32;
  1602.     for (j = 0; j < points; j++) {
  1603.       off++; /* 4th byte, that we don't need. */
  1604.       pokeb(0xa000, s3++, chardefs[off++]);
  1605.       pokeb(0xa000, s2++, chardefs[off++]);
  1606.       pokeb(0xa000, s1++, chardefs[off++]);
  1607.     }
  1608.   }
  1609.  
  1610.   /* Ok, put the Sequencer and Graphics Controller back to normal */
  1611.  
  1612.   /* Program the Sequencer */
  1613.   asm pushf; /* Disable interrupts */
  1614.   asm cli;
  1615.   asm mov dx, 3c4h; /* Sequencer port address */
  1616.   asm mov ax, 0302h; /* CPU writes to maps 0 and 1 */
  1617.   asm out dx, ax;
  1618.   asm mov ax, 0304h; /* Odd-even addressing */
  1619.   asm out dx, ax;
  1620.  
  1621.   /* Program the Graphics Controller */
  1622.   asm mov dx, 3ceh; /* Graphics Controller port address */
  1623.   asm mov ax, 0004h; /* Select map 0 for CPU reads */
  1624.   asm out dx, ax;
  1625.   asm mov ax, 1005h; /* Enable odd-even addressing */
  1626.   asm out dx, ax;
  1627.   asm sub ax, ax;
  1628.   asm mov es, ax; /* Segment 0 */
  1629.   asm mov ax, 0e06h; /* Map starts at B800:0000 */
  1630.   asm mov bl, 7;
  1631.   asm cmp es:[49h], bl; /* Get current video mode */
  1632.   asm jne notmono;
  1633.   asm mov ax, 0806h; /* Map starts at B000:0000 */
  1634. notmono:
  1635.   asm out dx, ax;
  1636.   asm popf;
  1637.  
  1638.   /* Ok, now put the bytes on the screen */
  1639.  
  1640.   plotegavgacursor(1); /* Plot the new grid on the screen. */
  1641. }
  1642.  
  1643. /*******************************************************/
  1644. /* 27-Oct-1990 - dk                                    */
  1645. /*                                                     */
  1646. /*  This function checks for the presense of EGA/VGA.  */
  1647. /*                                                     */
  1648. /*******************************************************/
  1649.  mouseboolean isegavga(void)
  1650. {
  1651.   asm mov ax, 1a00h; /* ROM BIOS video function 1ah -- Read Display Code */
  1652.   asm int 10h;
  1653.   asm cmp ah, 1ah; /* Is this call supported? */
  1654.   asm je checkega; /* Not supported */
  1655.   asm cmp bl, 7; /* VGA w/monochrome display? */
  1656.   asm je isvga; /* Yup. */
  1657.   asm cmp bl, 8; /* VGA w/color display? */
  1658.   asm jne checkega; /* Nope */
  1659. isvga:
  1660.   vgapresent=1;
  1661. isega:
  1662.   return TRUE; /* EGA/VGA is installed */
  1663. checkega:
  1664.   asm mov ah, 12h; /* EGA BIOS function */
  1665.   asm mov bl, 10h;
  1666.   asm int 10h;
  1667.   asm cmp bl, 10h; /* Is EGA BIOS present? */
  1668.   asm jne isega; /* There is an EGA in the system. */
  1669.   return FALSE; /* Not EGA or VGA in system. */
  1670. }
  1671.  
  1672. /************************************************/
  1673. /* 26-Oct-1990 - dk                             */
  1674. /*                                              */
  1675. /*  Mouse handler -- called from mouse driver.  */
  1676. /*                                              */
  1677. /************************************************/
  1678. PRIVATE void far mousehandler(void)
  1679. /* This function is called whenever a button is pressed.  Do not call this
  1680.    function directly!!
  1681. */
  1682. {
  1683. register word conditionmask;
  1684.  
  1685.   /* Get our data segment */
  1686.   asm push ds
  1687. #ifdef __TURBOC__
  1688.   asm push ax
  1689.   asm mov ax, DGROUP
  1690.   asm mov ds, ax
  1691.   asm pop ax
  1692. #else
  1693.   asm mov ds, cs:DGroupSeg
  1694. #endif
  1695.  
  1696.   asm mov conditionmask,ax
  1697.  
  1698.   if (!mousefreeze) {
  1699.     /* save mouse info passed to us from driver */
  1700.     asm mov mousex, cx
  1701.     asm mov mousey, dx
  1702.     asm mov mousepx, cx
  1703.     asm mov mousepy, dx
  1704.  
  1705.     mousex /= 8; /* Characters are 8 pixels wide */
  1706.     mousey /= points; /* Scale mousey down */
  1707.  
  1708.     /* See if the mouse has moved. */
  1709.     if (conditionmask & MOUSEMOVE) {
  1710.       if (saved) {
  1711.         if (egavga)
  1712.           plotegavgacursor(0);
  1713.         else
  1714.           POKEATTRIB(oldmx, oldmy, oldword);
  1715.         saved = FALSE;
  1716.       }
  1717.  
  1718.       if (!mousehidden && conditionalhidemouse) /* Check to see if we need to hide */
  1719.         if (mousex >= conx1 && mousex <= conx2 &&
  1720.             mousey >= cony1 && mousey <= cony2) {
  1721.           mousehidden++;
  1722.           conditionalhidemouse = FALSE;
  1723.         }
  1724.  
  1725.       if (!mousehidden) {
  1726.         if (egavga)
  1727.           drawegavgacursor();
  1728.         else {
  1729.           oldword = PEEKATTRIB(mousex, mousey);
  1730.       asm mov ax, oldword;    /* Prepare to rotate attrib byte */
  1731.           asm and al, 0f7h; /* Clear high bit */
  1732.           asm mov cl, 4   /* We want to rotate 4 bits */
  1733.           asm rol al, cl  /* Rotate it */
  1734.       asm mov newword, ax;
  1735.  
  1736.           POKEATTRIB(mousex, mousey, newword); /* Write out new mouse cursor */
  1737.         }
  1738.  
  1739.         oldmx = mousex;
  1740.         oldmy = mousey;
  1741.         saved = TRUE;
  1742.  
  1743.       }
  1744.     }
  1745.   }
  1746.  
  1747.   /* Now, see if a mouse button was whacked */
  1748.   if (conditionmask & ~MOUSEMOVE)
  1749.     if (((mbufin + 1) % MOUSEBUFFERSIZE) == mbufout) { /* Buffer full? */
  1750. #ifdef __TURBOC__
  1751.       sound(1760); /* Make some noise. */
  1752.       delay(10);
  1753.       nosound();
  1754. #endif
  1755.     } else {
  1756.       mbuf[mbufin].buttonstat = conditionmask & ~MOUSEMOVE;
  1757.       mbuf[mbufin].cx = mousex;
  1758.       mbuf[mbufin].cy = mousey;
  1759.       mbuf[mbufin].shiftstate = peekb(0, 0x417); /* Get shift byte */
  1760.       mbufin = (mbufin + 1) % MOUSEBUFFERSIZE;
  1761.     }
  1762.  
  1763.   asm pop ds;
  1764. }
  1765.  
  1766. /************************************/
  1767. /* 26-Oct-1990 - dk                 */
  1768. /*                                  */
  1769. /*  Initialize the mouse routines.  */
  1770. /*                                  */
  1771. /************************************/
  1772. void FAST MOUinit(void)
  1773. {
  1774. extern int graphicalCursor;
  1775. byte v;
  1776.  
  1777. #ifndef __TURBOC__
  1778.   asm mov cs:DGroupSeg,ds   /* save for interrupt handler to use */
  1779. #endif
  1780.  
  1781.   asm sub ax,ax;    /* Mouse driver function 0 -- reset and detect */
  1782.   asm int 33h
  1783.   asm mov mouseinstalled, AX;
  1784.  
  1785.   if (mouseinstalled) { /* If a mouse is installed then activate driver */
  1786.  
  1787.     mousefreeze++; /* Make sure handler doesn't do things, yet */
  1788.  
  1789.     asm mov ax,0F00h;
  1790.     asm int 10h;
  1791.     asm mov v,al;
  1792.  
  1793.     if (v == 7) {
  1794.       vseg = 0xb000u;
  1795.     } else {
  1796.       vseg = 0xb800u;
  1797.       v = 3;
  1798.     }
  1799.  
  1800.     if (ROWS == 0) { /* No value, assume 80x25. */
  1801.       mrows = 25;
  1802.       mcols = 80;
  1803.       points = 8;
  1804.     } else {
  1805.       mrows = ROWS + 1;
  1806.       mcols = COLS;
  1807.       points = POINTS;
  1808.     }
  1809.  
  1810.     /* Check to see if we are running in DESQview.  If so, don't try to
  1811.        use the 'true' EGA/VGA cursor (DV doesn't like it at ALL). */
  1812.  
  1813.     asm mov ax, 2b01h;
  1814.     asm mov cx, 4445h;
  1815.     asm mov dx, 5351h;
  1816.     asm int 21h;
  1817.  
  1818.     asm cmp al, 0ffh;
  1819.     asm je notdv;
  1820.  
  1821.     desqview = TRUE;
  1822.  
  1823. notdv:
  1824.  
  1825.     /* Do we have an EGA or VGA?  If so, and we are not in monochrome mode
  1826.        and we are not in DESQview then setup to draw a 'true' mouse cursor
  1827.        on an EGA/VGA */
  1828.     egavga = isegavga() && vseg != 0xb000u && !desqview && graphicalCursor;
  1829.  
  1830.     if (egavga) {
  1831.       /* We are going to use our 'true' mouse cursor and we need pixel
  1832.          resolution, not character resolution from the mouse driver
  1833.          (In text mode, the mouse driver only returns coordinates in multiples
  1834.          of 8, which we don't want.  We want multiples of 1, i.e. pixel
  1835.          resolution).  To get the mouse driver to return coordinates in pixel
  1836.          resolution, we 'trick' it into thinking it's in graphics mode by
  1837.          setting the low memory byte indicating mode to mode 6 (CGA 640x200x2).
  1838.          Then we reset the mouse driver.  The mouse driver will get the video
  1839.          mode then act as if it was in graphics mode, not text mode. */
  1840.       savevmode = peekb(0x40, 0x49);
  1841.       pokeb(0x40, 0x49, 6); /* Does this work ?!?!?!?!? */
  1842.  
  1843.       /* Reset driver for change in video mode to take effect. */
  1844.       asm sub ax,ax
  1845.       asm int 33h
  1846.  
  1847.       /* Now that we've tricked the mouse driver into a grapics mode thereby
  1848.          causing it to give us pixel resolutions, put the old mode back. */
  1849.       pokeb(0x40, 0x49, savevmode);
  1850.     }
  1851.  
  1852.     /* Set up max x and y ranges. */
  1853.  
  1854.     maxx = mcols * 8 - 1; /* Pixels horizontally */
  1855.     maxy = mrows * points - 1; /* Pixels vertically */
  1856.  
  1857.     asm mov dx,maxx     /* Pixels horizontally */
  1858.     asm mov ax,7        /* mouse driver function 7 -- set max x range */
  1859.     asm sub cx,cx       /* Minimum range */
  1860.     asm int 33h
  1861.  
  1862.     asm mov dx,maxy     /* Pixels veritcally */
  1863.     asm mov ax,8        /* mouse driver function 8 -- set max y range */
  1864.     asm sub cx,cx       /* Minimum range */
  1865.     asm int 33h
  1866.  
  1867.     /* Now install user routine */
  1868.  
  1869.     asm mov ax,cs
  1870.     asm mov es,ax
  1871.     asm mov dx, offset mousehandler
  1872.     /* Setup up bits for calling routine */
  1873. #ifdef __TURBOC__
  1874.     _CX = LEFTBPRESS | LEFTBRELEASE | RIGHTBPRESS | RIGHTBRELEASE | MIDBPRESS |
  1875.       MIDBRELEASE | MOUSEMOVE;
  1876. #else
  1877.     asm mov cx, LEFTBPRESS | LEFTBRELEASE | RIGHTBPRESS | RIGHTBRELEASE | MIDBPRESS | MIDBRELEASE | MOUSEMOVE;
  1878. #endif
  1879.     asm mov ax,12       /* Function 12 -- set user routine */
  1880.     asm int 33h
  1881.  
  1882.     mousex = mousey = mousepx = mousepy = 0;
  1883.     asm mov cx,mousepx     /* xcoord */
  1884.     asm mov dx,mousepy     /* ycoord */
  1885.     asm mov ax,4    /* mouse driver function 4 -- set mouse position */
  1886.     asm int 33h
  1887.  
  1888.     MOUshow(); /* Call it twice just to make sure */
  1889.  
  1890.     mousefreeze--; /* Handler can get into business, now */
  1891.   }
  1892. }
  1893.  
  1894. /****************************/
  1895. /* 26-Oct-1990 - dk         */
  1896. /*                          */
  1897. /*  Hide the mouse cursor.  */
  1898. /*                          */
  1899. /****************************/
  1900. void FAST MOUhide(void)
  1901. /* This function turns off the mouse cursor, the mouse still responds
  1902.    to button presses */
  1903. {
  1904.   if (!mouseinstalled)
  1905.     return;
  1906.  
  1907.   mousefreeze++; /* don't have the handler doing weird things */
  1908.  
  1909.   mousehidden++; /* indicate it's hidden now */
  1910.  
  1911.   if (saved) {
  1912.     if (egavga)
  1913.       plotegavgacursor(0);
  1914.     else
  1915.       POKEATTRIB(oldmx, oldmy, oldword);
  1916.     saved = FALSE;
  1917.   }
  1918.  
  1919.   mousefreeze--; /* reactivate handler */
  1920. }
  1921.  
  1922. /****************************/
  1923. /* 26-Oct-1990 - dk         */
  1924. /*                          */
  1925. /*  Show the mouse cursor.  */
  1926. /*                          */
  1927. /****************************/
  1928. void FAST MOUshow(void)
  1929. {
  1930.   if (!mouseinstalled)
  1931.     return;
  1932.  
  1933.   mousefreeze++; /* don't have the handler doing weird things */
  1934.  
  1935.   /* Just in case we were in a conditionalhide */
  1936.   if (conditionalhidemouse) {
  1937.     /* We were about to conditional hide, but we didn't, don't reactive
  1938.        mouse cursor. */
  1939.     conditionalhidemouse = FALSE;
  1940.     mousefreeze--; /* Reactivate handler */
  1941.     return;
  1942.   }
  1943.  
  1944.   if (mousehidden)
  1945.     mousehidden--;
  1946.   else {
  1947.     mousefreeze--; /* Reactivate handler */
  1948.     return;  /* It isn't hidden! */
  1949.   }
  1950.  
  1951.   if (mousehidden) {
  1952.     mousefreeze--; /* reactivate handler */
  1953.     return; /* still hidden! */
  1954.   }
  1955.  
  1956.   /* Draw mouse cursor */
  1957.  
  1958.   if (egavga)
  1959.     drawegavgacursor();
  1960.   else {
  1961.     oldword = PEEKATTRIB(mousex, mousey);
  1962.     asm mov ax, oldword;  /* Prepare to rotate attrib byte */
  1963.     asm and al, 0f7h; /* Clear high bit */
  1964.     asm mov cl, 4   /* We want to rotate 4 bits */
  1965.     asm rol al, cl  /* Rotate it */
  1966.     asm mov newword, ax;
  1967.  
  1968.     POKEATTRIB(mousex, mousey, newword); /* Write out new mouse cursor */
  1969.   }
  1970.  
  1971.   oldmx = mousex;
  1972.   oldmy = mousey;
  1973.   saved = TRUE;
  1974.  
  1975.   mousefreeze--; /* Reactivate handler */
  1976. }
  1977.  
  1978. /*************************************************************/
  1979. /* 27-Oct-1990 - dk                                          */
  1980. /*                                                           */
  1981. /*  Returns true if there is something in the mouse buffer.  */
  1982. /*                                                           */
  1983. /*************************************************************/
  1984. mouseboolean FAST MOUcheck(void)
  1985. {
  1986.   return mbufin != mbufout;
  1987. }
  1988.  
  1989. /**************************************************************/
  1990. /* 26-Oct-1990 - dk                                           */
  1991. /*                                                            */
  1992. /*  Take a copy of the mouse event at the head of the queue.  */
  1993. /*                                                            */
  1994. /**************************************************************/
  1995. void FAST MOUpreview(MOUINFOREC *mouinforec)
  1996. {
  1997.   if (!mouseinstalled)
  1998.     return;
  1999.  
  2000.   if (mbufin != mbufout) /* if something is in buffer */
  2001.     *mouinforec = mbuf[mbufout];
  2002.   else {
  2003.     /* Nothing to pull, just report mouse position */
  2004.     mouinforec -> cx = mousex;
  2005.     mouinforec -> cy = mousey;
  2006.     mouinforec -> buttonstat = 0;
  2007.     mouinforec -> shiftstate = peekb(0, 0x417);
  2008.   }
  2009. }
  2010.  
  2011. /****************************************************************/
  2012. /* 26-Oct-1990 - dk                                             */
  2013. /*                                                              */
  2014. /*  Get (and remove) the mouse event at the head of the queue.  */
  2015. /*                                                              */
  2016. /****************************************************************/
  2017. void FAST MOUget(MOUINFOREC *mouinforec)
  2018. {
  2019.   if (!mouseinstalled)
  2020.     return;
  2021.  
  2022.   if (mbufin != mbufout) { /* if something is in buffer */
  2023.     if (mouinforec != NULL)
  2024.       *mouinforec = mbuf[mbufout];
  2025.     mbufout = (mbufout + 1) % MOUSEBUFFERSIZE;
  2026.   } else {
  2027.     /* Nothing to pull, just report mouse position */
  2028.     mouinforec -> cx = mousex;
  2029.     mouinforec -> cy = mousey;
  2030.     mouinforec -> buttonstat = 0;
  2031.     mouinforec -> shiftstate = peekb(0, 0x417);
  2032.   }
  2033. }
  2034.  
  2035. /**************************************/
  2036. /* 26-Oct-1990 - dk                   */
  2037. /*                                    */
  2038. /*  Deinitialize the mouse routines.  */
  2039. /*                                    */
  2040. /**************************************/
  2041. void FAST MOUdeinit(void)
  2042. {
  2043.   if (!mouseinstalled)
  2044.     return;
  2045.  
  2046.   MOUhide();
  2047.  
  2048.   asm sub ax,ax
  2049.   asm int 33h
  2050. }
  2051.  
  2052. /**************************************************/
  2053. /* 26-Oct-1990 - dk                               */
  2054. /*                                                */
  2055. /*  Returns the bits for the button status info.  */
  2056. /*                                                */
  2057. /**************************************************/
  2058. word FAST MOUbuttonstatus(void)
  2059. {
  2060. word buts;
  2061.  
  2062.   if (!mouseinstalled)
  2063.     return 0;
  2064.  
  2065.   asm mov ax,3
  2066.   asm int 33h
  2067.   asm mov buts,bx
  2068.   return buts;
  2069. }
  2070.  
  2071. /************************************************************************/
  2072. /* 26-Oct-1990 - dk                                                     */
  2073. /*                                                                      */
  2074. /*  Hide the mouse *if* it enters a certain screen area, automatically. */
  2075. /*                                                                      */
  2076. /************************************************************************/
  2077. void FAST MOUconditionalhide(int x1, int y1, int x2, int y2)
  2078. {
  2079.   if (!mouseinstalled)
  2080.     return;
  2081.  
  2082.   mousefreeze++; /* hold the handler */
  2083.  
  2084.   if (mousehidden) {
  2085.     mousefreeze--; /* reactivate handler */
  2086.     return; /* already hidden! */
  2087.   }
  2088.  
  2089.   conditionalhidemouse = TRUE;
  2090.  
  2091.   x1 -= 2;
  2092.   if (x1 < 0)
  2093.     x1 = 0;
  2094.   y1 -= 2;
  2095.   if (y1 < 0)
  2096.     y1 = 0;
  2097.   x2 += 2;
  2098.   y2 += 2;
  2099.  
  2100.   conx1 = x1;
  2101.   cony1 = y1;
  2102.   conx2 = x2;
  2103.   cony2 = y2;
  2104.  
  2105.   if (mousex >= conx1 && mousex <= conx2 &&
  2106.       mousey >= cony1 && mousey <= cony2) {
  2107.     conditionalhidemouse = FALSE; /* We've already hidden it */
  2108.     MOUhide(); /* turn it off now if it's there. */
  2109.   }
  2110.  
  2111.   mousefreeze--;
  2112. }
  2113.  
  2114. /*********************************************************/
  2115. /* Fri 15-Mar-1991 - dk                  */
  2116. /*                             */
  2117. /*  Set the mouse cursor to a specific screen position.  */
  2118. /*                             */
  2119. /*********************************************************/
  2120. void FAST MOUsetpos(word x, word y)
  2121. {
  2122.   if (!mouseinstalled)
  2123.     return;
  2124.  
  2125.   mousefreeze++;
  2126.  
  2127.   MOUhide();
  2128.  
  2129.   mousex = x;
  2130.   mousey = y;
  2131.   mousepx = mousex * 8;
  2132.   mousepy = mousey * points;
  2133.   asm mov cx, mousepx    /* xcoord */
  2134.   asm mov dx, mousepy    /* ycoord */
  2135.   asm mov ax, 4     /* mouse driver function 4 -- set mouse position */
  2136.   asm int 33h
  2137.  
  2138.   MOUshow();
  2139.  
  2140.   mousefreeze--;
  2141. }
  2142. SHAR_EOF
  2143. fi
  2144. if test -f 'ascii.c'
  2145. then
  2146.     echo shar: "will not over-write existing file 'ascii.c'"
  2147. else
  2148. cat << \SHAR_EOF > 'ascii.c'
  2149. /* ascii.c test version 9/2/92 wclrtoeol */
  2150. /* "mgt" Copyright (c) 1991 Shodan  */
  2151.  
  2152. #include <ctype.h>
  2153. #include "mgt.h"
  2154.  
  2155. #define TOP 2
  2156. #define LEFT 4
  2157. #define RIGHT 79
  2158. #define STATUS_X 45
  2159. #define STATUS_Y 0
  2160. #define STATUS_WIDE (RIGHT-STATUS_X)
  2161. #define COMMENT_X 46
  2162. #define COMMENT_Y 2
  2163. #define COMMENT_WIDE (RIGHT-COMMENT_X)
  2164. #define COMMENT_HIGH (14-COMMENT_Y)
  2165. #define TREE_X COMMENT_X
  2166. #define TREE_Y 15
  2167. #define TREEWIDE (RIGHT-TREE_X)
  2168. #define TREEHIGH 6
  2169. #define COMMAND_X TREE_X
  2170. #define COMMAND_Y (TREE_Y+TREEHIGH)
  2171. #define WINLEFT   COMMENT_X
  2172. #define WINRIGHT  (RIGHT-1)
  2173. #define WINTOP    2
  2174. #define WINBOT    13
  2175. #define WINHIGH   (WINBOT-WINTOP)
  2176. #define WINWIDE   (WINRIGHT-WINLEFT)
  2177. #define SCRHIGH   120
  2178. #define PGOFFSET  3
  2179. #define CTRLC ('C'-64)
  2180. #define CTRLL ('L'-64)
  2181. #define ESC   27
  2182. #define EDHELP "%s - write %s   %s - keep old %s"
  2183.  
  2184. #define EDUP     0
  2185. #define EDDOWN     1
  2186. #define EDPUP     2
  2187. #define EDPDOWN    3
  2188. #define EDLEFT    4
  2189. #define EDRIGHT    5
  2190. #define EDBOL    6
  2191. #define EDEOL    7
  2192. #define EDBOC    8
  2193. #define EDEOC    9
  2194. #define EDDEL    10
  2195. #define EDDEOL    11
  2196. #define EDTINS    12
  2197. #define EDSAVE    13
  2198. #define EDABORT    14
  2199. #define MAXEDCMDS 14
  2200.  
  2201. #define C_COMMENTSCROLLDOWN C_LASTCOMMAND
  2202. #define C_COMMENTSCROLLUP   ((command) ((int)C_LASTCOMMAND+1))
  2203. #define C_TREESCROLLDOWN    ((command) ((int)C_LASTCOMMAND+2))
  2204. #define C_TREESCROLLUP      ((command) ((int)C_LASTCOMMAND+3))
  2205. #define C_VIDEO             ((command) ((int)C_LASTCOMMAND+4))
  2206. #define C_LASTOFS 5
  2207.  
  2208. enum {
  2209.    CHAR_BLACK, CHAR_WHITE,
  2210.    CHAR_DAME,
  2211.    CHAR_BLACKTERR, CHAR_WHITETERR,
  2212.    CHAR_NOTHING,
  2213.    CHAR_HANDICAP,
  2214.    CHAR_VERT, CHAR_HORIZ,
  2215.    CHAR_UPLEFT, CHAR_UPRIGHT,
  2216.    CHAR_DOWNLEFT, CHAR_DOWNRIGHT,
  2217.    ASC_NUMCHARS
  2218. };
  2219.  
  2220.  
  2221. static boolean commentExists;
  2222. static int commentLine;
  2223. static int treeLine;
  2224. static int inverseFlag = 0;
  2225. static char boardPiece();
  2226. static int getLine();
  2227. static void drawPiece();
  2228. static void printstatus();
  2229. static void setCursor();
  2230.  
  2231. char keys[] = "q><.,eb}{][gwzxv!lm#^cdnspotrfLWTFI012346789kiju&";
  2232. char edcmds[] = "PNpnBFAE<>DKIzW";
  2233. char emacscmds[] = "PNpnBFAE<>DKIzW";
  2234. char vicmds[] = "kj\002\006hl0$HLxDRwq";
  2235.  
  2236. int edvi = 0;
  2237.  
  2238. char xAxisChars[] = "ABCDEFGHJKLMNOPQRSTUVWXYZ";
  2239. char helpMsg[] = "? for help";
  2240.  
  2241. static void fixedkeys()
  2242. {
  2243.    char *ptr;
  2244.    if (!edvi)
  2245.       for (ptr = edcmds; *ptr; ptr++)
  2246.      if (*ptr >= 'A' && *ptr <= 'Z')
  2247.         *ptr -= 64;
  2248.      else
  2249.         *ptr |= 128;
  2250. }
  2251.  
  2252.  
  2253. char *dispedkey(key, keystr)
  2254. char key;
  2255. char *keystr;
  2256. {
  2257.    if (key & 128) {
  2258.       keystr[0] = ']';
  2259.       keystr[1] = key & 127;
  2260.       keystr[2] = 0;
  2261.    } else if (key < ' ') {
  2262.       keystr[0] = '^';
  2263.       keystr[1] = key + 64;
  2264.       keystr[2] = 0;
  2265.    } else {
  2266.       keystr[0] = key;
  2267.       keystr[1] = 0;
  2268.    }
  2269.    return keystr;
  2270. }
  2271.  
  2272.  
  2273. static void fixkeys()
  2274. {
  2275.    char *keyptr;
  2276.    for (keyptr = keys; *keyptr; keyptr++)
  2277.       if (*keyptr >= 'A' && *keyptr <= 'Z')
  2278.      *keyptr -= 64;
  2279. }
  2280.  
  2281.  
  2282. #ifdef MGT_IBM
  2283. #include "asc_ibm.inc"
  2284. #endif
  2285.  
  2286. #if (MGT_UNIX || vms)
  2287. #include "asc_unix.inc"
  2288. #endif
  2289.  
  2290.  
  2291. static void notifyClearAscii()
  2292. {
  2293.    move(23, 1);
  2294.    clrtoeol();
  2295. }
  2296.  
  2297. static void notifyMessageAscii(s)
  2298. char *s;
  2299. {
  2300.    mvaddstr(23, 1, s);
  2301.    refresh();
  2302. }
  2303.  
  2304. static void notifyErrorAscii(s)
  2305. char *s;
  2306. {
  2307.    mvaddstr(23, 1, s);
  2308.    printw("  Hit a key.");
  2309.    refresh();
  2310.    getKey();
  2311.    notifyClearAscii();
  2312. }
  2313.  
  2314. static void clearScreenAscii()
  2315. {
  2316.    clear();
  2317. }
  2318.  
  2319.  
  2320. static void printstatus(mesg)
  2321. char *mesg;
  2322. {
  2323.    int i;
  2324.    move(STATUS_Y, STATUS_X);
  2325.    for (i = 0; i < STATUS_WIDE && mesg[i]; i++)
  2326.       addch(mesg[i]);
  2327. }
  2328.  
  2329.  
  2330. static int getLine(query, dst, maxLen)    /* char *, char *, int */
  2331. char *query, *dst;
  2332. int maxLen;
  2333. {
  2334.    int qLen, dLen;
  2335.    char c;
  2336.    mvaddstr(23, 1, query);
  2337.    clrtoeol();
  2338.    dLen = 0;
  2339.    qLen = strlen(query);
  2340.    do {
  2341.       move(23, qLen + 1 + dLen);
  2342.       refresh();
  2343.       c = getKeyLine();
  2344.       if (isprint(c) && dLen < maxLen) {
  2345.      move(23, qLen + dLen + 1);
  2346.      refresh();
  2347.      addch(c);
  2348.      dst[dLen++] = c;
  2349.       } else if (dLen && (c == '\b' || c == '\177')) {
  2350.      dLen--;
  2351.      move(23, qLen + dLen + 1);
  2352.      addch(' ');
  2353.       }
  2354.    }
  2355.    while (c != '\n' && c != '\r');
  2356.    dst[dLen] = 0;
  2357.    move(23, 1);
  2358.    clrtoeol();
  2359.    return dLen;
  2360. }
  2361.  
  2362.  
  2363. static int askYNAscii(query, def)
  2364. char *query;
  2365. int def;
  2366. {
  2367.    static char *yn[] =
  2368.    {" (y/N)? ", " (Y/n)? "};
  2369.    char line[80];
  2370.    char buf[3];
  2371.  
  2372.    strcpy(line, query);
  2373.    strcat(line, yn[def]);
  2374.    if (getLine(line, buf, 2)) {
  2375.       if (*buf == 'Y' || *buf == 'y')
  2376.      return 1;
  2377.       if (*buf == 'N' || *buf == 'n')
  2378.      return 0;
  2379.    }
  2380.    return def;;
  2381. }
  2382.  
  2383.  
  2384. static void setCursor(x, y)
  2385. int x, y;
  2386. {
  2387.    move(TOP + y, LEFT + 2 * x);
  2388. }
  2389.  
  2390.  
  2391. static void printNStr(s, n)
  2392. char *s;
  2393. int n;
  2394. {
  2395.    int i;
  2396.    for (i = 0; i < n && s[i]; i++)
  2397.       addch(s[i]);
  2398. }
  2399.  
  2400.  
  2401. static void drawTreeAscii0(n)
  2402. nodep n;
  2403. {
  2404.    property *p;
  2405.  
  2406.    move(TREE_Y, TREE_X + 1);
  2407.    printw(" Node #%d: ", n->nodeNum);
  2408.    if (p = getprop(n, t_Name)) {
  2409.       int num, width;
  2410.  
  2411.       width = TREEWIDE - 10;
  2412.       num = n->nodeNum;
  2413.       do {
  2414.      num /= 10;
  2415.      width--;
  2416.       } while (num);
  2417.       printNStr(p->data.comment, width);
  2418.    }
  2419.    clrtoeol();
  2420.    {
  2421.       int temp;
  2422.       if (treeLine < 0)
  2423.      treeLine = 0;
  2424.       else {
  2425.      temp = treeCountSiblings(n) - TREEHIGH + 1;
  2426.      temp = MAX(temp, 0);
  2427.      treeLine = treeLine > temp ? temp : treeLine;
  2428.       }
  2429.    }
  2430.    {
  2431.       nodep ch;
  2432.       int index;
  2433.       index = 0;
  2434.       ch = nthChild(n, treeLine);
  2435.       while (ch && index < TREEHIGH - 1) {
  2436.      move(index + TREE_Y + 1, TREE_X);
  2437.      printw("%c:", 'A' + index + treeLine);
  2438.      clrtoeol();
  2439.      if (p = getprop(ch, t_Name))
  2440.         printNStr(p->data.comment, 80 - (TREE_X + 3));
  2441.      ch = ch->nextSibling;
  2442.      index++;
  2443.       }
  2444.       while (index < TREEHIGH - 1) {
  2445.      move(index++ + TREE_Y + 1, TREE_X);
  2446.      clrtoeol();
  2447.       }
  2448.       move(TREE_Y + TREEHIGH - 1, TREE_X - 1);
  2449.       addch(ch ? '+' : ' ');
  2450.       move(TREE_Y + 1, TREE_X - 1);
  2451.       addch(treeLine ? '-' : ' ');
  2452.    }
  2453.    refresh();
  2454. }
  2455.  
  2456.  
  2457. /* draw the tree children when node currently is at n */
  2458. static void drawTreeAscii(n)
  2459. nodep n;
  2460. {
  2461.    treeLine = 0;
  2462.    drawTreeAscii0(n);
  2463. }
  2464.  
  2465.  
  2466. static void closeAscii()
  2467. {
  2468.    endwin();
  2469. }
  2470.  
  2471.  
  2472. static void refreshAscii()
  2473. {
  2474.    refresh();
  2475. }
  2476.  
  2477. static char boardPiece(x, y)
  2478. int x, y;
  2479. {
  2480.    return
  2481.  
  2482.       (((boardsize == 19 && x == 9) || (boardsize >= 10 && (x == 3 || x == boardsize - 4))
  2483.     || (boardsize > 6 && boardsize < 10 && (x == 2 || x == boardsize - 3)))
  2484.        &&
  2485.        ((boardsize == 19 && y == 9) || (boardsize >= 10 && (y == 3 || y == boardsize - 4))
  2486.     || (boardsize > 6 && boardsize < 10 && (y == 2 || y == boardsize - 3)))
  2487.       )
  2488.       ? chars[(int) CHAR_HANDICAP] : chars[(int) CHAR_NOTHING];
  2489. }
  2490.  
  2491.  
  2492.  
  2493.  
  2494. static void plotPieceAscii(b, i, j)
  2495. pBoard b;
  2496. int i, j;
  2497. {
  2498.    piece p;
  2499.    char c;
  2500.    p = boardGet(b, i, j);
  2501.    switch (p) {
  2502.       case P_NOTHING:
  2503.      c = boardPiece(i, j);
  2504.      break;
  2505.       case P_BLACK:
  2506.      c = chars[(int) CHAR_BLACK];
  2507.      break;
  2508.       case P_WHITE:
  2509.      c = chars[(int) CHAR_WHITE];
  2510.      break;
  2511.       case P_DAME:
  2512.      c = chars[(int) CHAR_DAME];
  2513.      break;
  2514.       case P_BLACKTERR:
  2515.      c = chars[(int) CHAR_BLACKTERR];
  2516.      break;
  2517.       case P_WHITETERR:
  2518.      c = chars[(int) CHAR_WHITETERR];
  2519.      break;
  2520.    }
  2521.    drawPiece(i, j, c);
  2522. }
  2523.  
  2524.  
  2525. static char *savetype[] =
  2526. {"long ", "short"};
  2527.  
  2528. static void highlightAscii(x, y, movenum, turn)
  2529. int x, y, movenum, turn;
  2530. {
  2531.    extern int madechanges;
  2532.    if (movenum > 0 && x >= 0) {
  2533.       move(23, 1);
  2534.       printw("%s #%d ",
  2535.          turn ? "White" : "Black",
  2536.          movenum);
  2537.       if (x == PASSVAL && y == PASSVAL)
  2538.      printw("Pass      ");
  2539.       else
  2540.      printw("at %c%d  ", xAxisChars[x], boardsize - y);
  2541.    } else {
  2542.       move(23, 1);
  2543.       clrtoeol();
  2544.    }
  2545.    drawPrisoners();
  2546.    move(COMMAND_Y, COMMAND_X + 15);
  2547.    if (tutor)
  2548.       printw("tutor");
  2549.    else if (madechanges)
  2550.       printw("edit ");
  2551.    else
  2552.       printw("read ");
  2553.    printw("    %s", savetype[saveShort ? 1 : 0]);
  2554.    refresh();
  2555. }
  2556.  
  2557. static void showCommentAscii(i)    /* display from line i onward */
  2558. int i;
  2559. {
  2560.    short line;
  2561.  
  2562.    /* line = MIN(commentLines() - i, COMMENT_HIGH); / */
  2563.    line = COMMENT_HIGH;
  2564.  
  2565.    move(COMMENT_Y, COMMENT_X - 1);
  2566.    addch(i ? '-' : ' ');
  2567.    move(COMMENT_Y + COMMENT_HIGH - 1, COMMENT_X - 1);
  2568.    addch(commentLines() - i > COMMENT_HIGH ? '+' : ' ');
  2569.  
  2570.    while (line--) {
  2571.       mvaddstr(line + COMMENT_Y, COMMENT_X, commentGet(line + i));
  2572.       clrtoeol();
  2573.    }
  2574.    refresh();
  2575. }
  2576.  
  2577. static void clearCommentAscii()
  2578. {
  2579.    int line;
  2580.  
  2581.    commentExists = false;
  2582.    for (line = COMMENT_Y; line < COMMENT_Y + COMMENT_HIGH; line++)
  2583.       move(line, COMMENT_X), clrtoeol();
  2584.    move(COMMENT_Y, COMMENT_X - 1);
  2585.    addch(' ');
  2586.    move(COMMENT_Y + COMMENT_HIGH - 1, COMMENT_X - 1);
  2587.    addch(' ');
  2588.    refresh();
  2589. }
  2590.  
  2591. static void displayCommentAscii(s)
  2592. char *s;
  2593. {
  2594.    commentExists = true;
  2595.    commentLine = 0;
  2596.    formatComment(s, COMMENT_WIDE);
  2597.    showCommentAscii(0);
  2598.    refresh();
  2599. }
  2600.  
  2601.  
  2602. static command charToCommand(c)
  2603. char c;
  2604. {
  2605.    int i;
  2606.    if ((c == ESC) || (c == CTRLC))
  2607.       return C_QUIT;
  2608.    for (i = (int) C_LASTCOMMAND + C_LASTOFS; i--;) {
  2609.       if (c == keys[i])
  2610.      break;
  2611.    }
  2612.    return (command) i;        /* -1 = not found */
  2613. }
  2614.  
  2615.  
  2616. static int getPointAscii()
  2617. {
  2618.    char c;
  2619.  
  2620.    setCursor(xcur, ycur);
  2621.    refresh();
  2622.    while (1) {
  2623.       c = getKeyScore();
  2624.       if (c == 'u')
  2625.      return (int) C_UNDO;
  2626.       if ((c == ESC) || (c == keys[(int) C_QUIT]))
  2627.      return (int) C_QUIT;
  2628.       if (c == 014)
  2629.      return (int) C_REDRAW;
  2630.       if ((c == '\r') || (c == '\n'))
  2631.      return (int) C_SCORE;
  2632.       if ((c == ' ') || (c == keys[(int) C_MOVE]))
  2633.      return (int) C_MOVE;
  2634.       switch (charToCommand(c)) {
  2635.      case C_CURLEFT:
  2636.         xcur = (xcur - 1 + boardsize) % boardsize;
  2637.         setCursor(xcur, ycur);
  2638.         refresh();
  2639.         break;
  2640.      case C_CURRIGHT:
  2641.         xcur = (xcur + 1) % boardsize;
  2642.         setCursor(xcur, ycur);
  2643.         refresh();
  2644.         break;
  2645.      case C_CURUP:
  2646.         ycur = (ycur - 1 + boardsize) % boardsize;
  2647.         setCursor(xcur, ycur);
  2648.         refresh();
  2649.         break;
  2650.      case C_CURDOWN:
  2651.         ycur = (ycur + 1) % boardsize;
  2652.         setCursor(xcur, ycur);
  2653.         refresh();
  2654.         break;
  2655.      case C_UPLEFT:
  2656.         ycur = (ycur - 1 + boardsize) % boardsize;
  2657.         xcur = (xcur - 1 + boardsize) % boardsize;
  2658.         setCursor(xcur, ycur);
  2659.         refresh();
  2660.         break;
  2661.      case C_UPRIGHT:
  2662.         xcur = (xcur + 1) % boardsize;
  2663.         ycur = (ycur - 1 + boardsize) % boardsize;
  2664.         setCursor(xcur, ycur);
  2665.         refresh();
  2666.         break;
  2667.      case C_DOWNLEFT:
  2668.         xcur = (xcur - 1 + boardsize) % boardsize;
  2669.         ycur = (ycur + 1) % boardsize;
  2670.         setCursor(xcur, ycur);
  2671.         refresh();
  2672.         break;
  2673.      case C_DOWNRIGHT:
  2674.         xcur = (xcur + 1) % boardsize;
  2675.         ycur = (ycur + 1) % boardsize;
  2676.         setCursor(xcur, ycur);
  2677.         refresh();
  2678.         break;
  2679.       }
  2680.    }
  2681. }
  2682.  
  2683.  
  2684.  
  2685.  
  2686. static char *edhelp[] =
  2687. {
  2688.    "                Comment Editor Help",
  2689.    "",
  2690.    " Cursor control ('^' control, ']' <esc>/<meta>):",
  2691.    "    %s: Previous line         %s: Next line",
  2692.    "    %s: Previous page         %s: Next page",
  2693.    "    %s: Back one character    %s: Forward one character",
  2694.    "    %s: Beginning of line     %s: End of line",
  2695.    "    %s: Beginning of comment  %s: End of comment",
  2696.    "    %s: Delete one character  %s: Delete to end of line",
  2697.    " Press %s to toggle insert mode",
  2698.    " Press %s to exit and write your comment",
  2699.    " Press %s to exit and keep the old comment",
  2700.    "",
  2701.    "  (Warning:  comments longer than 120 lines",
  2702.    "             will be truncated if edited)",
  2703.    "",
  2704.    "                    Other Notes",
  2705.    "",
  2706.    "  When saving a file, * stands for the current file",
  2707.    "       (printed in the upper right corner)",
  2708.    "",
  2709.    "               Hit any key to return"
  2710. };
  2711.  
  2712.  
  2713.  
  2714.  
  2715. #define HALFWAY (((int)C_DOWNLEFT)/2)
  2716.  
  2717.  
  2718. char *fixkey(key, keystr)
  2719. char key;
  2720. char *keystr;
  2721. {
  2722.    if (key == keys[(int) C_QUIT])
  2723.       printw("ESC or ");
  2724.    if (key == keys[(int) C_MOVE])
  2725.       printw("Space or ");
  2726.    if (key < ' ') {
  2727.       keystr[0] = '^';
  2728.       keystr[1] = key + 64;
  2729.       keystr[2] = 0;
  2730.    } else {
  2731.       keystr[0] = key;
  2732.       keystr[1] = 0;
  2733.    }
  2734.    return keystr;
  2735. }
  2736.  
  2737.  
  2738. static void helpAscii()
  2739. {
  2740.    int i;
  2741.    extern char *helpStr[];
  2742.    char keystr[3];
  2743.    char kstr[3];
  2744.    char ch;
  2745.  
  2746.    /* don't put anything here */
  2747.    preserveScreen();
  2748.    clear();
  2749.    move(0, 33);
  2750.    printw("MGT Version %s", VERSION);
  2751.    move(1, 12);
  2752.    printw("Written by Greg Hale        Enhancements by Adrian Mariano");
  2753.    move(2, 11);
  2754.    printw("(hale@scam.Berkely.edu)        (adrian@u.washington.edu)");
  2755.    for (i = 0; i < HALFWAY; i++) {
  2756.       move(i + 3, 8);
  2757.       printw("%s: %s", fixkey(keys[i], keystr), helpStr[i]);
  2758.       move(i + 3, 46);
  2759.       printw("%s: %s", fixkey(keys[i + HALFWAY], keystr), helpStr[i + HALFWAY]);
  2760.    }
  2761.    move(21, 8);
  2762.    printw("%s", fixkey(keys[C_TREESCROLLUP], keystr));
  2763.    printw(", %s: Scroll tree window", fixkey(keys[C_TREESCROLLDOWN], keystr));
  2764.    move(21, 46);
  2765.    printw("%s", fixkey(keys[C_COMMENTSCROLLUP], keystr));
  2766.    printw(", %s: Scroll comment window", fixkey(keys[C_COMMENTSCROLLDOWN], keystr));
  2767.    move(22, 8);
  2768.    printw("Uppercase letters visit variations");
  2769.    move(22, 46);
  2770.    for (i = (int) C_DOWNLEFT; i <= (int) C_UPRIGHT; i++)
  2771.       addch(keys[i]);
  2772.    printw(": Cursor movement");
  2773.    move(23, 21);
  2774.    printw("Hit return to return, any key to continue");
  2775.    refresh();
  2776.    ch = getKey();
  2777.    if (ch != '\r' && ch != '\n') {
  2778.       clear();
  2779.       for (i = 0; i < 3; i++) {
  2780.      move(i, 10);
  2781.      printw(edhelp[i]);
  2782.       }
  2783.       for (i = 0; i < 12; i += 2) {
  2784.      move((i / 2 + 3), 10);
  2785.      printw(edhelp[(i / 2 + 3)], dispedkey(edcmds[i], kstr), dispedkey(edcmds[i + 1], keystr));
  2786.       }
  2787.       move(9, 10);
  2788.       printw(edhelp[9], dispedkey(edcmds[EDTINS], kstr));
  2789.       move(10, 10);
  2790.       printw(edhelp[10], dispedkey(edcmds[EDSAVE], kstr));
  2791.       move(11, 10);
  2792.       printw(edhelp[11], dispedkey(edcmds[EDABORT], kstr));
  2793.       for (i = 12; i < sizeof(edhelp) / sizeof(char *); i++)
  2794.      mvaddstr(i, 10, edhelp[i]);
  2795.       refresh();
  2796.       ch = getKey();
  2797.       if (ch != '\r' && ch != '\n')
  2798.      specialHelp();
  2799.    }
  2800.    restoreScreen();
  2801. }
  2802.  
  2803.  
  2804.  
  2805. static int idleAscii(curnode)
  2806. nodep curnode;
  2807. {
  2808.    char c;
  2809.    command r;
  2810.    command com;
  2811.  
  2812.    highlightLast();
  2813.    setCursor(xcur, ycur);
  2814.    refresh();
  2815.  
  2816.    c = getKeyIdle();
  2817.    if (r = specialKeysIdle(c))
  2818.       return (int) r;
  2819.    r = C_NOTHING;
  2820.    if (c >= 'A' && c <= 'Z') {
  2821.       r = (command) ((char) C_CHOSECHILD + (c - 'A'));
  2822.    } else
  2823.       switch (c) {
  2824.      case ' ':
  2825.         return (int) C_MOVE;
  2826.      case '?':
  2827.         helpAscii();
  2828.         return (int) C_NOTHING;
  2829.      default:
  2830.         com = charToCommand(c);
  2831.         switch (com) {
  2832.            case C_QUIT:
  2833.           {
  2834.              char buf[5];
  2835.              if (c != ESC) {
  2836.             getLine("Quit (y/N)?", buf, 1);
  2837.             if (buf[0] == 'y')
  2838.                r = C_QUIT;
  2839.              } else
  2840.             r = C_QUIT;
  2841.           }
  2842.           break;
  2843.            case C_VIDEO:
  2844.           inverseFlag = !inverseFlag;
  2845.           return (int) C_REDRAW;
  2846.            case C_COMMENTSCROLLDOWN:
  2847.           if (commentExists) {
  2848.              if (commentLine < commentLines() - COMMENT_HIGH)
  2849.             commentLine += COMMENT_HIGH - PGOFFSET;
  2850.              showCommentAscii(commentLine);
  2851.           }
  2852.           break;
  2853.            case C_COMMENTSCROLLUP:
  2854.           if (commentExists && commentLine) {
  2855.              commentLine -= COMMENT_HIGH - PGOFFSET;
  2856.              showCommentAscii(commentLine);
  2857.           }
  2858.           break;
  2859.            case C_TREESCROLLDOWN:
  2860.           treeLine++;
  2861.           drawTreeAscii0(curnode);
  2862.           break;
  2863.            case C_TREESCROLLUP:
  2864.           treeLine--;
  2865.           drawTreeAscii0(curnode);
  2866.           break;
  2867.            default:
  2868.           r = (command) com;
  2869.         }
  2870.       }
  2871.    return (int) r;
  2872. }
  2873.  
  2874.  
  2875. #define MATCH(string,action) if (!strncmp((*env), (string), strlen(string))){ \
  2876.                                (*env) += strlen(string);\
  2877.                                action;\
  2878.                              } else
  2879.  
  2880. static void readEnvAscii(env)
  2881. char **env;
  2882. {
  2883.    MATCH("ASCCOM:", strncpy(keys, *env, (int) C_LASTCOMMAND + C_LASTOFS))
  2884.       MATCH("ASCCHAR:", strncpy(chars, *env, (int) ASC_NUMCHARS))
  2885.       MATCH("ASCED:", strncpy(edcmds, *env, MAXEDCMDS + 1))
  2886.       MATCH("ASCINV", inverseFlag = 1)
  2887.       MATCH("ASCEDVI", (edvi = 1, strncpy(edcmds, vicmds, MAXEDCMDS + 1)))
  2888.       MATCH("ASCEDEMACS", (edvi = 0, strncpy(edcmds, emacscmds, MAXEDCMDS + 1)))
  2889. #ifdef MGT_IBM
  2890.       MATCH("ASCARROW:", cursorkey =
  2891.         (0 == strnicmp(*env, "cursor", 6)) +
  2892.         2 * (0 == strnicmp(*env, "mode", 4)))
  2893.       MATCH("ASCNOGRAPH", graphics = 0)
  2894.       MATCH("ASCMOUSENORM", graphicalCursor = 0)
  2895.       MATCH("ASCNOCOLOR", (usecolor = 0, graphics = 0))
  2896.       MATCH("ASCBCOL:", blackstone = atoi(*env))
  2897.       MATCH("ASCWCOL:", whitestone = atoi(*env))
  2898.       MATCH("ASCDAME:", damecolor = atoi(*env))
  2899.       MATCH("ASCBOARD:", boardcolor = atoi(*env))
  2900.       MATCH("ASCBG:", background = atoi(*env))
  2901.       MATCH("ASCFG:", foreground = atoi(*env))
  2902.       MATCH("ASCMARK:", markcolor = atoi(*env))
  2903.       MATCH("ASCLET:", lettercolor = atoi(*env))
  2904.       MATCH("ASCMENUBG:", menubg = atoi(*env))
  2905.       MATCH("ASCMENUFG:", menufg = atoi(*env))
  2906.       MATCH("RED:", bred = atoi(*env))
  2907.       MATCH("GREEN:", bgreen = atoi(*env))
  2908.       MATCH("BLUE:", bblue = atoi(*env))
  2909. #endif
  2910.       ;
  2911. }
  2912.  
  2913.  
  2914.  
  2915. char screen[SCRHIGH + 1][WINWIDE + 1];
  2916. int yoffset, cmplus, cmminus;
  2917.  
  2918. #define inwin(Y) ((Y <= (WINHIGH + yoffset)) && (Y >= yoffset))
  2919.  
  2920. static void showcommentindicator()
  2921. {
  2922.    int rfr;
  2923.    rfr = 0;
  2924.    mainwin();
  2925.    if (!((yoffset > 0) == cmminus)) {
  2926.       cmminus = !cmminus;
  2927.       move(COMMENT_Y, COMMENT_X - 1);
  2928.       addch(cmminus ? '-' : ' ');
  2929.       rfr = 1;
  2930.    }
  2931.    if (!((screen[yoffset + WINHIGH + 1][0] > 0) == cmplus)) {
  2932.       cmplus = !cmplus;
  2933.       move(COMMENT_Y + COMMENT_HIGH - 1, COMMENT_X - 1);
  2934.       addch(cmplus ? '+' : ' ');
  2935.       rfr = 1;
  2936.    }
  2937.    if (rfr)
  2938.       refresh();
  2939.    unmainwin();
  2940. }
  2941.  
  2942.  
  2943. static void adjustwin(win, yloc)
  2944. WINDOW *win;
  2945. int yloc;
  2946. {
  2947.    int x, y;
  2948.    if ((yloc < yoffset) || (yloc > (yoffset + WINHIGH))) {
  2949.       if (yloc < yoffset)
  2950.      yoffset = yloc - WINHIGH + PGOFFSET;
  2951.       if (yloc > (yoffset + WINHIGH))
  2952.      yoffset = yloc - PGOFFSET;
  2953.       if (yoffset < 0)
  2954.      yoffset = 0;
  2955.       if (yoffset > (SCRHIGH - WINHIGH))
  2956.      yoffset = (SCRHIGH - WINHIGH);
  2957.       for (; yoffset > 0 && !screen[yoffset + WINHIGH][0]; yoffset--);
  2958.       for (y = yoffset; y <= (yoffset + WINHIGH) && screen[y][0]; y++) {
  2959.      for (x = 0; x <= WINWIDE && screen[y][x]; x++) {
  2960.         wmove(win, y - yoffset, x);
  2961.         waddch(win, screen[y][x] < ' ' ? ' ' : screen[y][x]);
  2962.      }
  2963.      if (x <= WINWIDE) {
  2964.         wmove(win, y - yoffset, x);
  2965.         wclrtoeol(win);
  2966.      }
  2967.       }
  2968.       if (y <= (yoffset + WINHIGH)) {
  2969.      wmove(win, y - yoffset, 0);
  2970.      wclrtobot(win);
  2971.       }
  2972.    }
  2973.    showcommentindicator();
  2974. }
  2975.  
  2976.  
  2977. static void fixnewline(win, xloc, yloc)
  2978. WINDOW *win;
  2979. int xloc, yloc;
  2980. {
  2981.    if (xloc < WINWIDE && screen[yloc][xloc] == '\n' &&
  2982.        screen[yloc][xloc + 1]) {
  2983.       int myx, myy;
  2984.       for (myy = SCRHIGH - 1; myy > yloc && !screen[myy][0]; myy--);
  2985.       for (; myy > yloc; myy--)
  2986.      for (myx = 0; myx <= WINWIDE && (screen[myy + 1][myx] || screen[myy][myx]); myx++) {
  2987.         screen[myy + 1][myx] = screen[myy][myx];
  2988.         if (inwin((myy + 1))) {
  2989.            wmove(win, myy - yoffset + 1, myx);
  2990.            waddch(win, screen[myy][myx] >= ' ' ?
  2991.               screen[myy][myx] : ' ');
  2992.         }
  2993.      }
  2994.       for (myx = xloc + 1; myx <= WINWIDE && screen[myy][myx]; myx++) {
  2995.      screen[myy + 1][myx - xloc - 1] = screen[myy][myx];
  2996.      if (inwin(myy)) {
  2997.         wmove(win, myy - yoffset, myx);
  2998.         waddch(win, ' ');
  2999.      }
  3000.      if (inwin((myy + 1))) {
  3001.         wmove(win, myy - yoffset + 1, myx - xloc - 1);
  3002.         waddch(win, screen[myy][myx] >= ' ' ?
  3003.            screen[myy][myx] : ' ');
  3004.      }
  3005.      screen[myy][myx] = 0;
  3006.       }
  3007.       for (myx = myx - xloc - 1; myx <= WINWIDE && screen[myy + 1][myx]; myx++) {
  3008.      screen[myy + 1][myx] = 0;
  3009.      if (inwin((myy + 1))) {
  3010.         wmove(win, myy - yoffset + 1, myx);
  3011.         waddch(win, ' ');
  3012.      }
  3013.       }
  3014.       wrefresh(win);
  3015.    }
  3016. }
  3017.  
  3018.  
  3019. static void deletechar(win, x, y, x1, y1)
  3020. WINDOW *win;
  3021. int x, y, x1, y1;
  3022. {
  3023.    char c;
  3024.    c = ' ';
  3025.    while (c && !(c == '\n') && x1 <= WINWIDE && y1 <= SCRHIGH) {
  3026.       c = screen[y1][x1];
  3027.       screen[y][x] = c;
  3028.       if (inwin(y)) {
  3029.      wmove(win, y - yoffset, x);
  3030.      waddch(win, c < ' ' ? ' ' : c);
  3031.       }
  3032.       screen[y1][x1] = 0;
  3033.       if (x < WINWIDE)
  3034.      x++;
  3035.       else {
  3036.      x = 0;
  3037.      y++;
  3038.       }
  3039.       if (x1 < WINWIDE)
  3040.      x1++;
  3041.       else {
  3042.      x1 = 0;
  3043.      y1++;
  3044.       }
  3045.    }
  3046.    for (; x <= WINWIDE; x++) {
  3047.       screen[y][x] = 0;
  3048.       if (inwin(y)) {
  3049.      wmove(win, y - yoffset, x);
  3050.      waddch(win, ' ');
  3051.       }
  3052.    }
  3053.    if (!(y == y1)) {
  3054.       y++;
  3055.       y1++;
  3056.       for (; y1 <= SCRHIGH && screen[y1][0]; y++, y1++)
  3057.      for (x = 0; x <= WINWIDE; x++) {
  3058.         screen[y][x] = screen[y1][x];
  3059.         if (inwin(y)) {
  3060.            wmove(win, y - yoffset, x);
  3061.            waddch(win, screen[y][x] < ' ' ? ' ' : screen[y][x]);
  3062.         }
  3063.      }
  3064.       for (x = 0; x <= WINWIDE; x++) {
  3065.      screen[y1 - 1][x] = 0;
  3066.      if (inwin(y1 - 1)) {
  3067.         wmove(win, y1 - 1 - yoffset, x);
  3068.         waddch(win, ' ');
  3069.      }
  3070.       }
  3071.    }
  3072. }
  3073.  
  3074.  
  3075. static void insertchar(win, c, x, y, mflag)
  3076. WINDOW *win;
  3077. char c;
  3078. int x, y;
  3079. char mflag;
  3080. {
  3081.  
  3082.    int xend = -1, yend;
  3083.    char k, nlflag;
  3084.    nlflag = 0;
  3085.    while (c && x <= WINWIDE && y <= SCRHIGH) {
  3086.       k = screen[y][x];
  3087.       screen[y][x] = c;
  3088.       if (inwin(y) && !nlflag) {
  3089.      wmove(win, y - yoffset, x);
  3090.      waddch(win, c >= ' ' ? c : ' ');
  3091.       }
  3092.       if (c == '\n')
  3093.      nlflag = 1;
  3094.       if (x < WINWIDE)
  3095.      x++;
  3096.       else {
  3097.      x = 0;
  3098.      y++;
  3099.       }
  3100.       c = k;
  3101.       if (xend == -1) {
  3102.      xend = x;
  3103.      yend = y;
  3104.       }
  3105.    }
  3106.    for (y = 0; y <= SCRHIGH; y++)
  3107.       for (x = 0; x <= WINWIDE; x++)
  3108.      if (screen[y][x] == '\n')
  3109.         fixnewline(win, x, y);
  3110.    if (mflag) {
  3111.       adjustwin(win, (yend + 1));
  3112.       wmove(win, yend - yoffset + 1, 0);
  3113.    } else {
  3114.       adjustwin(win, yend);
  3115.       wmove(win, yend - yoffset, xend);
  3116.    }
  3117. }
  3118.  
  3119.  
  3120.  
  3121. static void edit(inp, out, mesg)
  3122. char *inp, **out, *mesg;
  3123. {
  3124.    int x, y, x1, y1, insert, cmdmode;
  3125.    char c;
  3126.    char str[(SCRHIGH + 1) * (WINWIDE + 1) + 1];
  3127.    char *s;
  3128.    WINDOW *win;
  3129.    char edithelp[80];
  3130.    char kstr[10];
  3131.    char keystr[10];
  3132.    dispedkey(edcmds[EDSAVE], keystr);
  3133.    if (keystr[0] == ']')
  3134.       sprintf(keystr, "ESC-%c", edcmds[EDSAVE] & 127);
  3135.    dispedkey(edcmds[EDABORT], kstr);
  3136.    if (keystr[0] == ']')
  3137.       sprintf(kstr, "ESC-%c", edcmds[EDABORT] & 127);
  3138.    sprintf(edithelp, EDHELP, keystr, mesg, kstr, mesg);
  3139.    notifyMessageAscii(edithelp);
  3140.    openwin();
  3141.    cmplus = 0;
  3142.    cmminus = 0;
  3143.    insert = 1;
  3144.    cmdmode = 0;
  3145.    yoffset = 1;
  3146.    for (y = 0; y < SCRHIGH + 1; y++)
  3147.       for (x = 0; x < WINWIDE + 1; x++) {
  3148.      screen[y][x] = 0;
  3149.       }
  3150.    if (inp) {
  3151.       for (s = inp, x = y = 0; *s && (x <= WINWIDE) && (y <= SCRHIGH); s++) {
  3152.      c = screen[y][x] = *s;
  3153.      if (*s == '\n') {
  3154.         x = 0;
  3155.         y++;
  3156.      } else if (x < WINWIDE)
  3157.         x++;
  3158.      else {
  3159.         x = 0;
  3160.         y++;
  3161.      }
  3162.       }
  3163.       if (!(c == '\n') && !(x == WINWIDE && y == SCRHIGH))
  3164.      screen[y][x] = '\n';    /* removed when comment is saved */
  3165.    }
  3166.    adjustwin(win, 0);
  3167.    wmove(win, 0, 0);
  3168.    wrefresh(win);
  3169.    if (!screen[0][0])
  3170.       screen[0][0] = '\n';
  3171.    do {
  3172.       fixcursor();
  3173.       c = getKeyEdit();
  3174.       x = xpos(win);
  3175.       y = ypos(win) + yoffset;
  3176.       if (((edvi && !cmdmode) || !edvi) && (c >= ' ') && (c < 127)) {
  3177.      if (insert)
  3178.         insertchar(win, c, x, y, 0);
  3179.      else {
  3180.         if (screen[y][x] == '\n')
  3181.            insertchar(win, c, x, y, 0);
  3182.         else {
  3183.            screen[y][x] = c;
  3184.            waddch(win, c);
  3185.         }
  3186.      }
  3187.      wrefresh(win);
  3188.       }
  3189.       if (c == CTRLL) {
  3190.      doredraw();
  3191.      wmove(win, y - yoffset, x);
  3192.      wrefresh(win);
  3193.       }
  3194.       if (!edvi && (c == edcmds[EDTINS]))    /* toggle insert mode */
  3195.      insert = !insert;
  3196.       if (edvi && cmdmode && (c == edcmds[EDTINS]))    /* toggle cmdmode */
  3197.      cmdmode = !cmdmode;
  3198.       if (edvi && !cmdmode && (c == ESC)) {    /* toggle cmdmode */
  3199.      cmdmode = !cmdmode;
  3200.      c = ' ';        /* get rid of the ESC */
  3201.       }
  3202.       if (((edvi && cmdmode) || !edvi) && (c == edcmds[EDDEOL])) {    /* delete to end of line */
  3203.      x1 = x;
  3204.      y1 = y;
  3205.      wmove(win, y - yoffset, x);
  3206.      wclrtoeol(win);
  3207.      for (; x <= WINWIDE; x++)
  3208.         screen[y][x] = 0;
  3209.      screen[y1][x1] = '\n';
  3210.      adjustwin(win, y1);
  3211.      wmove(win, y1 - yoffset, x1);
  3212.      wrefresh(win);
  3213.       }
  3214.       if (((edvi && !cmdmode) || !edvi) && ((c == '\n') || (c == '\r'))) {    /* newline, return */
  3215.      if (y < SCRHIGH)
  3216.         insertchar(win, '\n', x, y, 1);
  3217.      else {
  3218.         int xsave;
  3219.         xsave = x;
  3220.         screen[y][x] = '\n';
  3221.         waddch(win, ' ');
  3222.         for (x++; x <= WINWIDE; x++) {
  3223.            screen[y][x] = 0;
  3224.            waddch(win, ' ');
  3225.         }
  3226.         adjustwin(win, y);
  3227.         wmove(win, y - yoffset, xsave);
  3228.      }
  3229.      wrefresh(win);
  3230.       }
  3231.       if (((edvi && cmdmode) || !edvi) && (c == edcmds[EDDEL])) {    /* Delete a character */
  3232.      y1 = y;
  3233.      x1 = x;
  3234.      if (x1 < WINWIDE) {
  3235.         x1++;
  3236.         if (!screen[y1][x1]) {
  3237.            x1 = 0;
  3238.            y1++;
  3239.         }
  3240.      } else {
  3241.         x1 = 0;
  3242.         y1++;
  3243.      }
  3244.      deletechar(win, x, y, x1, y1);
  3245.      adjustwin(win, y);
  3246.      wmove(win, y - yoffset, x);
  3247.      wrefresh(win);
  3248.       }
  3249.       if (((edvi && cmdmode) || !edvi) && (c == '\b' || c == '\177') && (y || x)) {    /* backspace */
  3250.      y1 = y;
  3251.      x1 = x;
  3252.      if (x)
  3253.         x--;
  3254.      else {
  3255.         y--;
  3256.         for (x = WINWIDE; !screen[y][x]; x--);
  3257.      }
  3258.      deletechar(win, x, y, x1, y1);
  3259.      adjustwin(win, y);
  3260.      wmove(win, y - yoffset, x);
  3261.      wrefresh(win);
  3262.       }
  3263.       if (((edvi && cmdmode) || !edvi) && (c == edcmds[EDUP]) && (y)) {    /* cursor up */
  3264.      y--;
  3265.      for (; x > 0 && !screen[y][x]; x--);
  3266.      adjustwin(win, y);
  3267.      wmove(win, y - yoffset, x);
  3268.      wrefresh(win);
  3269.       }
  3270.       if (((edvi && cmdmode) || !edvi) && (c == edcmds[EDPUP])) {    /* page up */
  3271.      y = yoffset - 1;
  3272.      if (y < 0)
  3273.         y = 0;
  3274.      for (; x > 0 && !screen[y][x]; x--);
  3275.      adjustwin(win, y);
  3276.      wmove(win, y - yoffset, x);
  3277.      wrefresh(win);
  3278.       }
  3279.       if (((edvi && cmdmode) || !edvi) && (c == edcmds[EDBOC])) {    /* beginning of comment */
  3280.      y = x = 0;
  3281.      adjustwin(win, y);
  3282.      wmove(win, 0, 0);
  3283.      wrefresh(win);
  3284.       }
  3285.       if (((edvi && cmdmode) || !edvi) && (c == edcmds[EDDOWN]) && (y < SCRHIGH)) {    /* cursor down */
  3286.      y++;
  3287.      for (; x > 0 && !screen[y][x]; x--);
  3288.      if (!screen[y][x])
  3289.         screen[y][x] = '\n';
  3290.      adjustwin(win, y);
  3291.      wmove(win, y - yoffset, x);
  3292.      wrefresh(win);
  3293.       }
  3294.       if (((edvi && cmdmode) || !edvi) && (c == edcmds[EDPDOWN])) {    /* page down */
  3295.      y = yoffset + WINHIGH + 1;
  3296.      if (y > SCRHIGH)
  3297.         y = SCRHIGH;
  3298.      for (; y > 0 && !screen[y][0]; y--);
  3299.      for (; x > 0 && !screen[y][x]; x--);
  3300.      adjustwin(win, y);
  3301.      wmove(win, y - yoffset, x);
  3302.      wrefresh(win);
  3303.       }
  3304.       if (((edvi && cmdmode) || !edvi) && (c == edcmds[EDEOC])) {    /* end of comment */
  3305.      for (y = SCRHIGH; y > 0 && !screen[y][0]; y--);
  3306.      for (x = WINWIDE; x > 0 && !screen[y][x]; x--);
  3307.      adjustwin(win, y);
  3308.      wmove(win, y - yoffset, x);
  3309.      wrefresh(win);
  3310.       }
  3311.       if (((edvi && cmdmode) || !edvi) && (c == edcmds[EDLEFT]) && (y || x)) {    /* cursor left */
  3312.      if (x)
  3313.         x--;
  3314.      else {
  3315.         y--;
  3316.         x = WINWIDE;
  3317.         for (; x > 0 && !screen[y][x]; x--);
  3318.      }
  3319.      adjustwin(win, y);
  3320.      wmove(win, y - yoffset, x);
  3321.      wrefresh(win);
  3322.       }
  3323.       if (((edvi && cmdmode) || !edvi) && (c == edcmds[EDRIGHT])
  3324.       && !((x == WINWIDE) && (y == SCRHIGH))) {    /* cursor right */
  3325.      if (x < WINWIDE) {
  3326.         x++;
  3327.         if (!screen[y][x]) {
  3328.            y++;
  3329.            x = 0;
  3330.         }
  3331.      } else {
  3332.         y++;
  3333.         x = 0;
  3334.      }
  3335.      for (; x > 0 && !screen[y][x]; x--);
  3336.      if (!screen[y][x])
  3337.         screen[y][x] = '\n';
  3338.      adjustwin(win, y);
  3339.      wmove(win, y - yoffset, x);
  3340.      wrefresh(win);
  3341.       }
  3342.       if (((edvi && cmdmode) || !edvi) && (c == edcmds[EDEOL])) {    /* cursor to end of line */
  3343.      for (x = WINWIDE; x > 0 && !screen[y][x]; x--);
  3344.      if (x < WINWIDE && screen[y][x] && screen[y][x] != '\n')
  3345.         x++;
  3346.      wmove(win, y - yoffset, x);
  3347.      wrefresh(win);
  3348.       }
  3349.       if (((edvi && cmdmode) || !edvi) && (c == edcmds[EDBOL])) {    /* cursor to beginning
  3350.                                      * of line */
  3351.      wmove(win, y - yoffset, 0);
  3352.      wrefresh(win);
  3353.       }
  3354.    }
  3355.    while ((((edvi && cmdmode) || !edvi) &&
  3356.        (c != edcmds[EDSAVE]) && (c != edcmds[EDABORT]) && (c != ESC)) ||
  3357.       (edvi && !cmdmode));
  3358.    closewin();
  3359.    notifyClearAscii();
  3360.    if (c == edcmds[EDABORT])
  3361.       *out = inp;
  3362.    else {
  3363.       for (y = SCRHIGH; y >= 0; y--)
  3364.      for (x = WINWIDE; x >= 0; x--)
  3365.         if ((screen[y][x] == 0) || (screen[y][x] == '\n'))
  3366.            screen[y][x] = 0;
  3367.         else
  3368.            y = x = 0;
  3369.       strcpy(str, "");
  3370.       s = str;
  3371.       for (y = 0; y <= SCRHIGH; y++)
  3372.      for (x = 0; x <= WINWIDE && screen[y][x]; x++, s++)
  3373.         *s = screen[y][x];
  3374.       *s = 0;
  3375.       if (inp)
  3376.      free(inp);
  3377.       *out = dupStr(str);
  3378.    }
  3379.  
  3380. }
  3381.  
  3382.  
  3383.  
  3384. static char *names[] =
  3385. {
  3386.    " Size        ",
  3387.    " Handicap    ",
  3388.    " Komi        ",
  3389.    " playerBlack ",
  3390.    " bLackrank   ",
  3391.    " playerWhite ",
  3392.    " whIterank   ",
  3393.    " Gamename    ",
  3394.    " Event       ",
  3395.    " rouNd       ",
  3396.    " Date        ",
  3397.    " Place       ",
  3398.    " Time        ",
  3399.    " Result      ",
  3400.    " gameComment ",
  3401.    " sOurce      ",
  3402.    " User        "
  3403. };
  3404.  
  3405.  
  3406.  
  3407.  
  3408. getInfoToChange()
  3409. {
  3410.    static char convert[] = "SHBLWIGENDPTRCOUK";
  3411.    static flag = 0;
  3412.    static char savearea[28][17];
  3413.    static WINDOW *wi;
  3414.    static char didhelp = 0;
  3415.  
  3416.    char ch;
  3417.    int con;
  3418.    if (flag == 1) {
  3419.       flag = 0;
  3420.       return t_BlackRank;
  3421.    }
  3422.    if (flag == 2) {
  3423.       flag = 0;
  3424.       return t_WhiteRank;
  3425.    }
  3426.    notifyClearAscii();
  3427.    notifyMessageAscii("Press capital letter to edit info field (? for list) or return to exit");
  3428.    while (1) {
  3429.       ch = getKey();
  3430.       if (ch == 'W')
  3431.      flag = 2;
  3432.       if (ch == 'B')
  3433.      flag = 1;
  3434.       if (ch == '?') {
  3435.      saveRegion(16, 3, 13, 17);
  3436.      for (ch = 0; ch < 17; ch++)
  3437.         mvaddstr(ch + 3, 16, names[ch]);
  3438.      refresh();
  3439.      didhelp = 1;
  3440.       }
  3441.       if (ch == keys[C_COMMENTSCROLLDOWN]) {
  3442.      if (commentLine < commentLines() - COMMENT_HIGH)
  3443.         commentLine += COMMENT_HIGH - 1;
  3444.      showCommentAscii(commentLine);
  3445.       } else if (ch == keys[C_COMMENTSCROLLUP])
  3446.      if (commentLine) {
  3447.         commentLine -= COMMENT_HIGH - 1;
  3448.         showCommentAscii(commentLine);
  3449.      }
  3450.       for (con = strlen(convert); con--;)
  3451.      if (ch == convert[con]) {
  3452.         notifyClearAscii();
  3453.         return (int) t_Size + con;
  3454.      }
  3455.       if (ch == '\n' || ch == '\r' || ch == ESC) {
  3456.      notifyClearAscii();
  3457.      if (didhelp) {
  3458.         restoreRegion(16, 3, 13, 17);
  3459.         didhelp = 0;
  3460.      }
  3461.      return (int) t_EOF;
  3462.       }
  3463.    }
  3464. }
  3465.  
  3466.  
  3467. static char *editName[] =
  3468. {"Size: ", "Handicap: ", "black's name", "Black's rank: ", "white's name", "White's rank: ", "game name", "event", "round", "date", "place", "time", "result", "game comment", "source", "user", "Komi: "};
  3469.  
  3470.  
  3471. static void editInfo(in, out, prop)
  3472. char *in, **out;
  3473. Token prop;
  3474. {
  3475.    if (prop == t_Size || prop == t_Handicap || prop == t_BlackRank
  3476.        || prop == t_WhiteRank || prop == t_Komi) {
  3477.       if (in)
  3478.      free(in);
  3479.       *out = (char *) malloc(21);
  3480.       getLine(editName[prop - FIRSTINFO + 2], *out, 20);
  3481.    } else
  3482.       edit(in, out, editName[prop - FIRSTINFO + 2]);
  3483. }
  3484.  
  3485.  
  3486. static void commentEdit(in, out)
  3487. char *in, **out;
  3488. {
  3489.    edit(in, out, "comment");
  3490. }
  3491.  
  3492.  
  3493.  
  3494. interface asciiInterface =
  3495. {
  3496.    (char *) 0,
  3497.    (char *) 0,
  3498.    (char *) 0,
  3499.    (pfi) initAscii,
  3500.    (pfi) closeAscii,
  3501.    (pfi) refreshAscii,
  3502.    (pfi) plotPieceAscii,
  3503.    (pfi) displayCommentAscii,
  3504.    (pfi) clearCommentAscii,
  3505.    (pfi) initBoardAscii,
  3506.    (pfi) clearScreenAscii,
  3507.    idleAscii,
  3508.    (pfi) drawTreeAscii,
  3509.    (pfi) highlightAscii,
  3510.    (pfi) readEnvAscii,
  3511.    (pfi) notifyMessageAscii,
  3512.    (pfi) notifyClearAscii,
  3513.    getLine,
  3514.    (pfi) setCursor,
  3515.    (pfi) plotMarkAscii,
  3516.    (pfi) drawPiece,
  3517.    getPointAscii,
  3518.    (pfi) commentEdit,
  3519.    askYNAscii,
  3520.    (pfi) notifyErrorAscii,
  3521.    (pfi) displayCommentAscii,
  3522.    getInfoToChange,
  3523.    (pfi) editInfo
  3524. };
  3525. SHAR_EOF
  3526. fi
  3527. if test -f 'build.c'
  3528. then
  3529.     echo shar: "will not over-write existing file 'build.c'"
  3530. else
  3531. cat << \SHAR_EOF > 'build.c'
  3532. /* "mgt" Copyright (c) 1991 Shodan  */
  3533.  
  3534. #include "mgt.h"
  3535.  
  3536. int lastMoveX, lastMoveY, moveNum, lastTurn;
  3537. coordList *lastletters = 0, *lastmarks;
  3538. coordList *marks = 0;
  3539. coordList *letters = 0;
  3540.  
  3541.  
  3542. FUNCTION void clearLast()
  3543. {
  3544.    lastMoveX = lastMoveY = -1;
  3545.    moveNum = 0;
  3546. }
  3547.  
  3548. FUNCTION void highlightLast()
  3549. {
  3550.    extern Token curPlayer;
  3551.    if (lastMoveX >= 0 && moveNum > 0 && lastTurn != (int) t_EOF)
  3552.       curPlayer = lastTurn ? t_Black : t_White;
  3553.    (*io->highlightLast) (lastMoveX, lastMoveY, moveNum, lastTurn);
  3554.  
  3555. }
  3556.  
  3557.  
  3558. FUNCTION void doPlace(p, b, t)
  3559. property *p;
  3560. pBoard b;
  3561. piece t;
  3562. {
  3563.    coordList *list;
  3564.  
  3565.    list = p->data.stones;
  3566.    while (list) {
  3567.       placeStone(b, list->x, list->y, t);
  3568.       list = list->next;
  3569.    }
  3570.    if (p->t == t_Black || p->t == t_White)
  3571.       moveNum++;
  3572.  
  3573. }
  3574.  
  3575.  
  3576.  
  3577.  
  3578. FUNCTION void doProps(p, b)
  3579. property *p;
  3580. pBoard b;
  3581. {
  3582.    letters = NULL;
  3583.    marks = NULL;
  3584.    while (p) {
  3585.       switch (p->t) {
  3586.      case t_White:
  3587.         BUG("t_White ");
  3588.         doPlace(p, b, P_WHITE);
  3589.         break;
  3590.      case t_Black:
  3591.         BUG("t_Black ");
  3592.         doPlace(p, b, P_BLACK);
  3593.         break;
  3594.      case t_AddWhite:
  3595.         BUG("t_AddWhite ");
  3596.         doPlace(p, b, P_WHITE);
  3597.         break;
  3598.      case t_AddBlack:
  3599.         BUG("t_AddBlack ");
  3600.         doPlace(p, b, P_BLACK);
  3601.         break;
  3602.      case t_AddEmpty:
  3603.         BUG("t_AddEmpty ");
  3604.         doPlace(p, b, P_NOTHING);
  3605.         break;
  3606.      case t_Comment:
  3607.         break;
  3608.      case t_Pass:
  3609.         moveNum++;
  3610.         break;
  3611.      case t_Mark:
  3612.         marks = p->data.stones;
  3613.         break;
  3614.      case t_Letter:
  3615.         letters = p->data.stones;
  3616.         BUG("t_Letter ");
  3617.         break;
  3618.      default:
  3619.         BUG("default ");
  3620.       }
  3621.       p = p->next;
  3622.    }
  3623. }
  3624.  
  3625. static void setLastMovePos(p)
  3626. property *p;
  3627. {
  3628.    lastTurn = p->t == t_White ? 1 : 0;
  3629.    if (p->data.stones) {
  3630.       lastMoveX = p->data.stones->x;
  3631.       lastMoveY = p->data.stones->y;
  3632.    } else
  3633.       lastMoveX = lastMoveY = -1;
  3634.  
  3635. }
  3636.  
  3637.  
  3638. FUNCTION void doPropComment(n)
  3639. nodep n;
  3640. {
  3641.    property *p;
  3642.  
  3643.    if (p = getprop(n, t_Comment))
  3644.       (*io->displayComment) (p->data.comment);
  3645.  
  3646.    if (p = getprop(n, t_Black))
  3647.       setLastMovePos(p);
  3648.    else if (p = getprop(n, t_White))
  3649.       setLastMovePos(p);
  3650.  
  3651.    if (p = getprop(n, t_Pass)) {
  3652.       lastTurn = p->data.player == t_White ? 1 : 0;
  3653.       lastMoveX = lastMoveY = PASSVAL;
  3654.    }
  3655. }
  3656.  
  3657. FUNCTION void buildTree0(n, b)
  3658. nodep n;
  3659. pBoard b;
  3660. {
  3661.    BUG("parent >");
  3662.    if (n) {
  3663.       buildTree0(n->parent, b);
  3664.       BUG("\nprops:");
  3665.       doProps(n->p, b);
  3666.    }
  3667. }
  3668.  
  3669.  
  3670.  
  3671. FUNCTION void buildTree(n, b)
  3672. nodep n;
  3673. pBoard b;
  3674. {
  3675.    prisoners[0] = 0;
  3676.    prisoners[1] = 0;
  3677.    boardClear(b);
  3678.    (*io->clearComment) ();
  3679.    BUG("buildTree:\n");
  3680.    clearLast();
  3681.    buildTree0(n, b);
  3682.    doPropComment(n);
  3683. }
  3684.  
  3685.  
  3686. FUNCTION void setPiece(b, i, j, p)
  3687. pBoard b;
  3688. int i, j;
  3689. piece p;
  3690. {
  3691.    boardSet(b, i, j, p);
  3692.    (*io->plotPiece) (b, i, j);
  3693. }
  3694.  
  3695. FUNCTION void updateBoard(dst, new)
  3696. pBoard dst, new;        /* update dst to look like new */
  3697. {
  3698.    int i, j;
  3699.    coordList *cl;
  3700.  
  3701.    for (cl = lastmarks; cl; cl = cl->next)
  3702.       (*io->plotPiece) (new, cl->x, cl->y);
  3703.  
  3704.    for (cl = lastletters; cl; cl = cl->next)
  3705.       (*io->plotPiece) (new, cl->x, cl->y);
  3706.    lastmarks = marks;
  3707.    lastletters = letters;
  3708.    for (i = boardsize; i--;)
  3709.       for (j = boardsize; j--;) {
  3710.      if (boardGet(new, i, j) != boardGet(dst, i, j)) {
  3711.         setPiece(dst, i, j, boardGet(new, i, j));
  3712.      }
  3713.       }
  3714.    if (marks) {
  3715.       for (cl = marks; cl; cl = cl->next)
  3716.      (*io->plotMark) (new, cl->x, cl->y);
  3717.       marks = NULL;
  3718.    }
  3719.    if (letters) {
  3720.       for (i = 0, cl = letters; cl; cl = cl->next, i++)
  3721.      (*io->plotLetter) (cl->x, cl->y, (i % 26) + 'a');
  3722.       letters = NULL;
  3723.    }
  3724. }
  3725. SHAR_EOF
  3726. fi
  3727. if test -f 'comment.c'
  3728. then
  3729.     echo shar: "will not over-write existing file 'comment.c'"
  3730. else
  3731. cat << \SHAR_EOF > 'comment.c'
  3732. /* "mgt" Copyright (c) 1991 Shodan  */
  3733.  
  3734. #include "mgt.h"
  3735. #include <string.h>
  3736. #include <ctype.h>
  3737.  
  3738.  
  3739. #define NEWBLOCK 20
  3740.  
  3741. typedef char clinetype[MAXCOMMENTWIDTH];
  3742.  
  3743. static int nlines = 0;
  3744. int clines = 0;
  3745. clinetype *cbuf = 0;
  3746. char *empty = "";
  3747.  
  3748. FUNCTION char *commentGet(line)    /* int */
  3749. int line;
  3750. {
  3751.    if (cbuf && line < clines)
  3752.       return cbuf[line];
  3753.    else
  3754.       return empty;
  3755. }
  3756.  
  3757.  
  3758. FUNCTION int commentLines()
  3759. {
  3760.    return clines;
  3761. }
  3762.  
  3763.  
  3764. FUNCTION void formatComment(comment, width)
  3765. char *comment;
  3766. int width;
  3767. {
  3768.    char *partstart, *dest, c;
  3769.    int len, partlen, wordlen;
  3770.  
  3771.    clines = 0;
  3772.    width = MIN(width, MAXCOMMENTWIDTH - 1);
  3773.    wordlen = partlen = len = 0;
  3774.    dest = *cbuf;
  3775.    if (*comment == '\n')
  3776.       comment++;
  3777.    partstart = comment;
  3778.    do {
  3779.       if (clines >= nlines) {
  3780.      nlines += NEWBLOCK;
  3781.      cbuf = (clinetype *) (cbuf ? realloc(cbuf, nlines * sizeof(clinetype)) :
  3782.                    malloc(nlines * sizeof(clinetype)));
  3783.      if (!cbuf)
  3784.         barf("Memory allocation failure (formatComment)");
  3785.      dest = cbuf[clines];
  3786.       }
  3787.       c = *(comment++);
  3788.       len++;
  3789.       partlen++;
  3790.       wordlen++;
  3791.       if (c == ' ')
  3792.      wordlen = 0;
  3793.       else if (c == '\n' && *(comment - 2) == ' ' &&
  3794.            *comment != '\n') {
  3795.      partlen--;
  3796.      len--;
  3797.      strncpy(dest, partstart, partlen);
  3798.      dest += partlen;
  3799.      partstart = comment;
  3800.      wordlen = partlen = 0;
  3801.       } else if (c == '\n' || !c) {
  3802.      strncpy(dest, partstart, partlen - 1);
  3803.      *(dest + partlen - 1) = 0;
  3804.      len = partlen = wordlen = 0;
  3805.      dest = cbuf[++clines];
  3806.      partstart = comment;
  3807.       }
  3808.       if (len == width) {
  3809.  
  3810.      if (len == wordlen)
  3811.         wordlen = 0;
  3812.  
  3813.      else
  3814.         len = partlen - wordlen;
  3815.  
  3816.      strncpy(dest, partstart, len);
  3817.      partstart += len;
  3818.      *(dest + len) = 0;
  3819.      len = partlen = wordlen;
  3820.  
  3821.      dest = cbuf[++clines];
  3822.       }
  3823.    } while (c);
  3824. }
  3825. SHAR_EOF
  3826. fi
  3827. if test -f 'doit.c'
  3828. then
  3829.     echo shar: "will not over-write existing file 'doit.c'"
  3830. else
  3831. cat << \SHAR_EOF > 'doit.c'
  3832. /* "mgt" Copyright (c) 1991 Shodan  */
  3833.  
  3834. #include "mgt.h"
  3835.  
  3836. int xcur, ycur;
  3837. Token curPlayer;
  3838. int change;
  3839. int madechanges;
  3840. int searchNodeNum;
  3841. int ispl = 0;
  3842.  
  3843. FUNCTION int okChange()
  3844. {
  3845.    if (tutor) {
  3846.       (*io->notifyError) ("Can't edit in tutor mode.");
  3847.       return 0;
  3848.    }
  3849.    if ((!change) && ((*io->askYN) ("Modify tree", 0)))
  3850.       change = 1;
  3851.    if (change)
  3852.       madechanges = 1;
  3853.    return change;
  3854. }
  3855.  
  3856.  
  3857.  
  3858. FUNCTION int okExit(root)
  3859. nodep root;
  3860. {
  3861.    if (mailFlag) {
  3862.       if (madechanges) {
  3863.      if (!(*io->askYN) ("Save", 1)) {
  3864.         retVal = 1;
  3865.         return 1;
  3866.      }
  3867.      if (writeTree(saveName, root))
  3868.         return 0;
  3869.      return 1;
  3870.       }
  3871.       retVal = 1;
  3872.       return 1;
  3873.    }
  3874.    if (madechanges) {
  3875.       if ((*io->askYN) ("Unsaved changes.  Exit without saving", 0))
  3876.      return 1;
  3877.       return 0;
  3878.    }
  3879.    return 1;
  3880. }
  3881.  
  3882.  
  3883.  
  3884. FUNCTION nodep search(n)    /* return 0 on failure */
  3885. nodep n;
  3886. {
  3887.    nodep s;
  3888.    if (!n || n->nodeNum == searchNodeNum)
  3889.       return n;
  3890.    s = search(child(n));
  3891.    if (s && s->nodeNum == searchNodeNum)
  3892.       return s;
  3893.    s = search(nextSibling(n));
  3894.    if (s && s->nodeNum == searchNodeNum)
  3895.       return s;
  3896.    return (nodep) 0;
  3897. }
  3898.  
  3899. FUNCTION void step(n, b)
  3900. nodep n;
  3901. pBoard b;
  3902. {
  3903.    board temp;
  3904.    buildTree(n, &temp);
  3905.    updateBoard(b, &temp);
  3906.    (*io->drawTree) (n);
  3907.    (*io->refreshIO) ();
  3908.    highlightLast();
  3909. }
  3910.  
  3911. FUNCTION void stepDown(n, b)
  3912. nodep n;
  3913. pBoard b;
  3914. {
  3915.    board temp;
  3916.    (*io->clearComment) ();
  3917.    copyBoard(b, &temp);
  3918.    doProps(n->p, &temp);
  3919.    doPropComment(n);
  3920.    updateBoard(b, &temp);
  3921.    (*io->drawTree) (n);
  3922.    (*io->refreshIO) ();
  3923.    highlightLast();
  3924. }
  3925.  
  3926.  
  3927. static char *color[] =
  3928. {
  3929.    "Black", "White"
  3930. };
  3931.  
  3932.  
  3933. int adjust(val, halfk, ksign)
  3934. int val, halfk, ksign;
  3935. {
  3936.    if (!halfk)
  3937.       return val;
  3938.    if (val * ksign >= 0)
  3939.       return val;
  3940.    return val + ksign;
  3941. }
  3942.  
  3943.  
  3944. FUNCTION void doScore(b, curNode)
  3945. pBoard b;
  3946. nodep curNode;
  3947. {
  3948.    int savepris[2], lastpris[2];
  3949.    char out[200];
  3950.    command c;
  3951.    property *p;
  3952.    board new, old, last;
  3953.    int score[2], scored;
  3954.    char komicopy[10];
  3955.    int intkomi, halfkomi, kptr, komisign, winner, diff;
  3956.  
  3957.    winner = -1;
  3958.    scored = 0;
  3959.    lastpris[1] = savepris[1] = prisoners[1];
  3960.    lastpris[0] = savepris[0] = prisoners[0];
  3961.    copyBoard(b, &old);
  3962.    copyBoard(b, &last);
  3963.    copyBoard(b, &new);
  3964.    (*io->notifyClear) ();
  3965.    (*io->notifyMessage) ("return score, space kill, u undo, q quit");
  3966.    do {
  3967.       c = (command) (*io->getPoint) ();
  3968.       if (c == C_MOVE && (new.b[xcur][ycur] == P_WHITE ||
  3969.               new.b[xcur][ycur] == P_BLACK)
  3970.      ) {
  3971.      if (scored) {
  3972.         scored = 0;
  3973.         copyBoard(&last, &new);
  3974.         prisoners[1] = lastpris[1];
  3975.         prisoners[0] = lastpris[0];
  3976.      }
  3977.      copyBoard(&new, &last);
  3978.      lastpris[1] = prisoners[1];
  3979.      lastpris[0] = prisoners[0];
  3980.      removeStones(&new, xcur, ycur);
  3981.      updateBoard(b, &new);
  3982.       }
  3983.       if (c == C_UNDO) {
  3984.      copyBoard(&last, &new);
  3985.      prisoners[1] = lastpris[1];
  3986.      prisoners[0] = lastpris[0];
  3987.      updateBoard(b, &new);
  3988.       }
  3989.       if (c == C_SCORE && !scored) {
  3990.      copyBoard(&new, &last);
  3991.      lastpris[1] = prisoners[1];
  3992.      lastpris[0] = prisoners[0];
  3993.      scoreBoard(&new, score);
  3994.      updateBoard(b, &new);
  3995.      if (info[t_Komi - FIRSTINFO]) {
  3996.         halfkomi = 0;
  3997.         for (kptr = 0; info[t_Komi - FIRSTINFO][kptr]; kptr++) {
  3998.            if (info[t_Komi - FIRSTINFO][kptr] == '.') {
  3999.           kptr++;
  4000.           if (info[t_Komi - FIRSTINFO][kptr] >= '1' && info[t_Komi - FIRSTINFO][kptr] <= '9')
  4001.              halfkomi = 1;
  4002.           break;
  4003.            }
  4004.            komicopy[kptr] = info[t_Komi - FIRSTINFO][kptr];
  4005.         }
  4006.         komicopy[kptr] = 0;
  4007.         intkomi = atoi(komicopy);
  4008.         komisign = 0;
  4009.         if (komicopy[0] == '-' || intkomi < 0)
  4010.            komisign = -1;
  4011.         else if (intkomi > 0 || halfkomi)
  4012.            komisign = 1;
  4013.         sprintf(komicopy, "+ %s ", info[t_Komi - FIRSTINFO]);
  4014.      } else {
  4015.         komisign = intkomi = halfkomi = 0;
  4016.         strcpy(komicopy, "");
  4017.      }
  4018.  
  4019.      diff = score[1] + prisoners[0] - score[0] - prisoners[1] + intkomi;
  4020.  
  4021.      if (!diff) {
  4022.         if (halfkomi) {
  4023.            if (komisign > 0)
  4024.           winner = 1;
  4025.            else if (komisign < 0)
  4026.           winner = 0;
  4027.         } else
  4028.            winner = 2;
  4029.      } else
  4030.         winner = diff > 0 ? 1 : 0;
  4031.  
  4032.  
  4033.      diff = adjust(diff, halfkomi, komisign);
  4034.      sprintf(out,
  4035.          "Black: %d + %d = %d\n\nWhite: %d + %d %s= %s%d%s\n\n",
  4036.          score[0], prisoners[1], score[0] + prisoners[1],
  4037.          score[1], prisoners[0], komicopy, (!diff) && halfkomi && (komisign == -1) ? "-" : "",
  4038.          adjust(score[1] + prisoners[0] + intkomi, halfkomi, komisign),
  4039.          halfkomi ? ".5" : "");
  4040.      if (winner == 2)
  4041.         sprintf(out + strlen(out), "Tie game.");
  4042.      else
  4043.         sprintf(out + strlen(out), "%s wins by %d%s",
  4044.             color[winner], abs(diff), halfkomi ? ".5" : "");
  4045.  
  4046.  
  4047.      (*io->clearComment) ();
  4048.      (*io->displayComment) (out);
  4049.      scored = 1;
  4050.       }
  4051.    }
  4052.    while (c != C_QUIT);
  4053.  
  4054.    if (scored && (*io->askYN) ("Keep comment", 1) && okChange())
  4055.       replaceComment(curNode, out);
  4056.    else {
  4057.       (*io->clearComment) ();
  4058.       if (p = getprop(curNode, t_Comment))
  4059.      (*io->displayComment) (p->data.comment);
  4060.    }
  4061.  
  4062.    prisoners[0] = savepris[0];
  4063.    prisoners[1] = savepris[1];
  4064.  
  4065.    (*io->notifyClear) ();
  4066.    updateBoard(b, &old);
  4067. }
  4068.  
  4069.  
  4070.  
  4071. static void initBoard(b)
  4072. pBoard b;
  4073. {
  4074.    extern coordList *lastmarks, *lastletters;
  4075.  
  4076.    boardClear(b);
  4077.    (*io->initializeBoard) ();
  4078.    lastletters = lastmarks = 0;
  4079. }
  4080.  
  4081.  
  4082.  
  4083. FUNCTION nodep loadFile(filename, root, b)
  4084. char *filename;
  4085. nodep root;
  4086. board *b;
  4087. {
  4088.    openfile(filename);
  4089.    if (input) {
  4090.       madechanges = change = 0;
  4091.       freeNode(root);
  4092.       initNodes();
  4093.       readInit();
  4094.       root = parse(0);
  4095.       fclose(input);
  4096.       if (!root)
  4097.      root = newNode();
  4098.       initBoard(b);
  4099.       (*io->setCursor) (xcur, ycur);
  4100.       (*io->refreshIO) ();
  4101.       xcur = ycur = 0;
  4102.    } else
  4103.       (*io->notifyError) ("Unable to load file.");
  4104.    return root;
  4105. }
  4106.  
  4107.  
  4108. FUNCTION nodep makeTutor(nod, tok, x, y)
  4109. nodep nod;
  4110. Token tok;
  4111. int x, y;
  4112. {
  4113.    property *prop;
  4114.    if (!nod->child)
  4115.       return 0;
  4116.    nod = nod->child;
  4117.    while (!((prop = getprop(nod, tok)) && getCoord(x, y, prop->data.stones))) {
  4118.       if (!nod->nextSibling)
  4119.      return 0;
  4120.       nod = nod->nextSibling;
  4121.    }
  4122.    return nod;
  4123. }
  4124.  
  4125.  
  4126.  
  4127.  
  4128.  
  4129. static char *infotitle[] =
  4130. {
  4131.    "Game name: ",
  4132.    "Event: ",
  4133.    "rouNd: ",
  4134.    "Date: ",
  4135.    "Place: ",
  4136.    "Time limit: ",
  4137.    "Result: ",
  4138.    "Comment: ",
  4139.    "sOurce: ",
  4140.    "User: ",
  4141.    "Komi: "
  4142. };
  4143.  
  4144.  
  4145.  
  4146.  
  4147. static void showinfo()
  4148. {
  4149.    char infoarray[4000];
  4150.    char *infostr;
  4151.    int p;
  4152.  
  4153.    infostr = infoarray;
  4154.  
  4155.    sprintf(infostr, "Size: %d", boardsize);
  4156.    while (*infostr)
  4157.       infostr++;
  4158.    if (info[(int) t_Komi - FIRSTINFO]) {
  4159.       sprintf(infostr, "  Komi: %s", info[(int) t_Komi - FIRSTINFO]);
  4160.       while (*infostr)
  4161.      infostr++;
  4162.    }
  4163.    if (handicap) {
  4164.       sprintf(infostr, "  Handicap: %d", handicap);
  4165.       while (*infostr)
  4166.      infostr++;
  4167.    }
  4168.    *infostr = '\n';
  4169.    infostr++;
  4170.  
  4171.    if (info[0] || info[1]) {
  4172.       sprintf(infostr, "Black: %s%s%s\n", info[0] ? info[0] : "",
  4173.           info[0] && info[1] ? ", " : "",
  4174.           info[1] ? info[1] : "");
  4175.       while (*infostr)
  4176.      infostr++;
  4177.    }
  4178.    if (info[2] || info[3]) {
  4179.       sprintf(infostr, "White: %s%s%s\n", info[2] ? info[2] : "",
  4180.           info[2] && info[3] ? ", " : "",
  4181.           info[3] ? info[3] : "");
  4182.       while (*infostr)
  4183.      infostr++;
  4184.    }
  4185.    for (p = 0; p <= LASTINFO - FIRSTINFO - 4; p++) {
  4186.       if (info[p + 4]) {
  4187.      sprintf(infostr, "%s%s\n", infotitle[p], info[p + 4]);
  4188.      while (*infostr)
  4189.         infostr++;
  4190.       }
  4191.    }
  4192.    *infostr = 0;
  4193.    (*io->displayInfo) (infoarray);
  4194.  
  4195. }
  4196.  
  4197.  
  4198. #define BUFFERSIZE 50
  4199.  
  4200.  
  4201. static int doinfo()
  4202. {
  4203.    Token change;
  4204.    int sizechanged, value;
  4205.    char buffer[BUFFERSIZE + 1];
  4206.    char *current;
  4207.  
  4208.    sizechanged = 0;
  4209.    do {
  4210.       showinfo();
  4211.       change = (Token) (*io->getInfoToChange) ();
  4212.       if (change == t_EOF)
  4213.      break;
  4214.       if (!okChange())
  4215.      continue;
  4216.       if (change == t_Size) {
  4217.      sprintf(buffer, "%d", boardsize);
  4218.      current = dupStr(buffer);
  4219.      (*io->editInfo) (current, ¤t, t_Size);
  4220.      if (current) {
  4221.         value = atoi(current);
  4222.         if (value > 1 && value < 20) {
  4223.            if (value != boardsize)
  4224.           sizechanged = 1;
  4225.            boardsize = value;
  4226.         } free(current);
  4227.      }
  4228.       } else if (change == t_Handicap) {
  4229.      sprintf(buffer, "%d", handicap);
  4230.      current = dupStr(buffer);
  4231.      (*io->editInfo) (current, ¤t, t_Handicap);
  4232.      if (current) {
  4233.         handicap = atoi(current);
  4234.         free(current);
  4235.      }
  4236.       } else {
  4237.  
  4238.      (*io->editInfo) (info[(int) change - FIRSTINFO], &info[(int) change - FIRSTINFO],
  4239.               change);
  4240.      if (!strlen(info[(int) change - FIRSTINFO])) {
  4241.         free(info[(int) change - FIRSTINFO]);
  4242.         info[(int) change - FIRSTINFO] = 0;
  4243.      }
  4244.       }
  4245.  
  4246.  
  4247.    } while (1);
  4248.    return sizechanged;
  4249.  
  4250. }
  4251.  
  4252.  
  4253.  
  4254.  
  4255. static void savescreen(bord)
  4256. board *bord;
  4257. {
  4258.    char fname[75];
  4259.    int i, j;
  4260.    FILE *out;
  4261.    extern coordList *lastletters;
  4262.    coordList *let;
  4263.    char local[19][19];
  4264.  
  4265.    if ((*io->queryStr) ("Save screen: ", fname, 74)) {
  4266.       if (out = fopen(fname, "a+t")) {
  4267.      fprintf(out, "%s to play.\n\n", curPlayer == t_Black ? "Black" : "White");
  4268.      fputs("  ", out);
  4269.      for (i = 0; i < boardsize; i++) {
  4270.         fputc(' ', out);
  4271.         fputc(i + 'A' + ((i + 'A' >= 'I') ? 1 : 0), out);
  4272.      }
  4273.      fputc('\n', out);
  4274.  
  4275.  
  4276.      for (j = 0; j < boardsize; j++)
  4277.         for (i = 0; i < boardsize; i++) {
  4278.            local[i][j] = ' ';
  4279.            switch (bord->b[i][j]) {
  4280.  
  4281.           case P_WHITE:
  4282.              local[i][j] = 'O';
  4283.              break;
  4284.           case P_BLACK:
  4285.              local[i][j] = '#';
  4286.              break;
  4287.  
  4288.           case P_NOTHING:
  4289.           default:
  4290.              local[i][j] = '.';
  4291.              break;
  4292.            }
  4293.         }
  4294.      let = lastletters;
  4295.      i = 0;
  4296.      while (let) {
  4297.         local[let->x][let->y] = i + 'a';
  4298.         i++;
  4299.         i %= 26;
  4300.         let = let->next;
  4301.  
  4302.  
  4303.      }
  4304.  
  4305.      for (j = 0; j < boardsize; j++) {
  4306.         fprintf(out, "%2d ", boardsize - j);
  4307.         for (i = 0; i < boardsize; i++) {
  4308.            fputc(local[i][j], out);
  4309.            fputc(' ', out);
  4310.         }
  4311.  
  4312.         fprintf(out, "%2d", boardsize - j);
  4313.         if (
  4314.           (j == boardsize / 2) && (prisoners[0] || prisoners[1]))
  4315.            fprintf(out, "  Captured #: %d   Captured O: %d", prisoners[0], prisoners[1]);
  4316.         fputc('\n', out);
  4317.      }
  4318.      fputs("  ", out);
  4319.      for (i = 0; i < boardsize; i++) {
  4320.         fputc(' ', out);
  4321.         fputc(i + 'A' + ((i + 'A' >= 'I') ? 1 : 0), out);
  4322.      }
  4323.  
  4324.      fputs("\n\n", out);
  4325.      for (i = 0; i < commentLines(); i++) {
  4326.         fputs(commentGet(i), out);
  4327.         putc('\n', out);
  4328.      }
  4329.  
  4330.      fclose(out);
  4331.       } else
  4332.      (*io->notifyError) ("Unable to open file.");
  4333.    }
  4334. }
  4335.  
  4336.  
  4337.  
  4338.  
  4339.  
  4340. FUNCTION void doit()
  4341. {
  4342.    int quitflg, i;
  4343.    nodep root, curNode;
  4344.    board theBoard;
  4345.    extern coordList *lastletters, *lastmarks;
  4346.  
  4347.    curPlayer = t_Black;
  4348.    xcur = ycur = quitflg = 0;
  4349.    root = 0;
  4350.    madechanges = 0;
  4351.    change = 1;
  4352.    if (input != stdin) {
  4353.       root = parse(0);
  4354.       fclose(input);
  4355.       change = 0;
  4356.    }
  4357.    if (!root)
  4358.       root = newNode();
  4359.    curNode = root;
  4360.    initBoard(&theBoard);
  4361.    (*io->setCursor) (xcur, ycur);
  4362.    (*io->refreshIO) ();
  4363.    if (mailFlag) {
  4364.       while (curNode->child)
  4365.      curNode = treeDown(curNode);
  4366.       change = 1;
  4367.    }
  4368.    step(curNode, &theBoard);
  4369.    while (!quitflg) {
  4370.       nodep tNode;
  4371.       command c;
  4372.       property *prop;
  4373.  
  4374.       if (prop = getprop(curNode, t_Player)) {
  4375.      extern Token lastTurn;
  4376.      curPlayer = prop->data.player;
  4377.      lastTurn = t_EOF;
  4378.      ispl = 1;
  4379.       } else
  4380.      ispl = 0;
  4381.  
  4382.       c = (command) (*io->idle) (curNode);
  4383.  
  4384.       if ((int) c >= (int) C_CHOSECHILD && (int) c < (int) C_NEXTCMD) {
  4385.      nodep new;
  4386.      new = nthChild(curNode, (int) c - (int) C_CHOSECHILD);
  4387.      if (new) {
  4388.         curNode = nthChild(curNode, (int) c - (int) C_CHOSECHILD);
  4389.         step(curNode, &theBoard);
  4390.      }
  4391.       } else
  4392.      switch (c) {
  4393.         case C_LOAD:
  4394.            if (okExit(root)) {
  4395.           char filename[50];
  4396.           if ((*io->queryStr) ("Load file? ", filename, 48)) {
  4397.              root = curNode = loadFile(filename, root, &theBoard);
  4398.              step(curNode, &theBoard);
  4399.           }
  4400.            }
  4401.            break;
  4402.         case C_BACKFILE:
  4403.  
  4404.            if (currentfile > 0 && okExit(root)) {
  4405.           currentfile--;
  4406.           root = curNode = loadFile(files[currentfile], root, &theBoard);
  4407.           step(curNode, &theBoard);
  4408.            } else
  4409.           (*io->notifyError) ("No previous file.");
  4410.            break;
  4411.  
  4412.  
  4413.         case C_NEXTFILE:
  4414.            if (currentfile + 1 < filecount && okExit(root)) {
  4415.           currentfile++;
  4416.           root = curNode = loadFile(files[currentfile], root, &theBoard);
  4417.           step(curNode, &theBoard);
  4418.            } else
  4419.           (*io->notifyError) ("No next file.");
  4420.            break;
  4421.  
  4422.         case C_INFO:
  4423.            if (doinfo())
  4424.           initBoard(&theBoard);
  4425.            step(curNode, &theBoard);
  4426.            if (xcur >= boardsize)
  4427.           xcur = boardsize - 1;
  4428.            if (ycur >= boardsize)
  4429.           ycur = boardsize - 1;
  4430.            break;
  4431.         case C_SAVESCREEN:
  4432.            savescreen(&theBoard);
  4433.            break;
  4434.         case C_REDRAW:
  4435.            {
  4436.           int savex, savey;
  4437.           savex = xcur;
  4438.           savey = ycur;
  4439.           initBoard(&theBoard);
  4440.           (*io->refreshIO) ();
  4441.           step(curNode, &theBoard);
  4442.           xcur = savex;
  4443.           ycur = savey;
  4444.           break;
  4445.            }
  4446.         case C_NOTHING:
  4447.            break;
  4448.         case C_TOPLAY:
  4449.            if (okChange())
  4450.           addPlayer(curNode, (curPlayer == t_Black) ? t_White : t_Black);
  4451.            break;
  4452.         case C_PASSMOVE:{
  4453.           int mod_cur_node;
  4454.           mod_cur_node = passMove(curNode, curPlayer);
  4455.           if (mod_cur_node)
  4456.              step(curNode, &theBoard);
  4457.           else {
  4458.              curNode = treeDown(curNode);
  4459.              stepDown(curNode, &theBoard);
  4460.           }
  4461.            }
  4462.            break;
  4463.  
  4464.  
  4465.         case C_TOGGLESTONE:{
  4466.           extern Token lastTurn;
  4467.           curPlayer = (curPlayer == t_Black) ? t_White : t_Black;
  4468.           lastTurn = t_EOF;
  4469.            }
  4470.  
  4471.            break;
  4472.         case C_TUTORSWAP:
  4473.            tutor = !tutor;
  4474.            break;
  4475.         case C_MOVE:
  4476.            if (tutor) {
  4477.           nodep save;
  4478.           save = curNode;
  4479.           if (curNode = makeTutor(curNode, curPlayer, xcur, ycur)) {
  4480.              step(curNode, &theBoard);
  4481.           } else {
  4482.              (*io->notifyError) ("Wrong move.");
  4483.              curNode = save;;
  4484.           }
  4485.            } else {
  4486.           if (okChange() && legal(&theBoard, curNode, curPlayer, xcur, ycur)) {
  4487.              int mod_cur_node;
  4488.              mod_cur_node = makeMove(curNode, curPlayer, xcur, ycur);
  4489.              curPlayer = (curPlayer == t_Black) ? t_White : t_Black;
  4490.              if (mod_cur_node)
  4491.             step(curNode, &theBoard);
  4492.              else {
  4493.             curNode = treeDown(curNode);
  4494.             stepDown(curNode, &theBoard);
  4495.              }
  4496.           }
  4497.            }
  4498.  
  4499.            break;
  4500.         case C_ADDVAR:
  4501.            if (okChange()) {
  4502.           makeVariation(curNode);
  4503.           step(curNode, &theBoard);
  4504.            }
  4505.            break;
  4506.         case C_DELNODE:
  4507.            if (okChange()) {
  4508.           deleteNode(&curNode);
  4509.           step(curNode, &theBoard);
  4510.            }
  4511.            break;
  4512.         case C_PASTE:
  4513.            if (okChange())
  4514.           if (pasteTree(curNode))
  4515.              step(curNode, &theBoard);
  4516.           else
  4517.              (*io->notifyError) ("Nothing to paste.");
  4518.            break;
  4519.  
  4520.         case C_TREECUT:
  4521.            if (okChange()) {
  4522.           nodep prevNode;
  4523.           int savex, savey;
  4524.           savex = xcur;
  4525.           savey = ycur;
  4526.           prevNode = curNode->parent;
  4527.           cutTree(curNode);
  4528.           curNode = prevNode;
  4529.           if (!curNode) {
  4530.              initNodes();
  4531.              root = curNode = newNode();
  4532.           }
  4533.           step(curNode, &theBoard);
  4534.           xcur = savex;
  4535.           ycur = savey;
  4536.           break;
  4537.            }
  4538.         case C_ADDBLACK:
  4539.            if (okChange()) {
  4540.           coordList *cl;
  4541.           property *prop;
  4542.           if (boardGet(&theBoard, xcur, ycur) == P_BLACK) {
  4543.              addStone(curNode, t_AddEmpty, xcur, ycur);
  4544.              setPiece(&theBoard, xcur, ycur, P_NOTHING);
  4545.           } else {
  4546.              addStone(curNode, t_AddBlack, xcur, ycur);
  4547.              setPiece(&theBoard, xcur, ycur, P_BLACK);
  4548.           }
  4549.           if (prop = getprop(curNode, t_Letter))
  4550.              lastletters = prop->data.stones;
  4551.           for (i = 0, cl = lastletters; cl; i++, cl = cl->next)
  4552.              (*io->plotLetter) (cl->x, cl->y, i % 26 + 'a');
  4553.            }
  4554.            break;
  4555.         case C_ADDWHITE:
  4556.            if (okChange()) {
  4557.           coordList *cl;
  4558.           property *prop;
  4559.           if (boardGet(&theBoard, xcur, ycur) == P_WHITE) {
  4560.              addStone(curNode, t_AddEmpty, xcur, ycur);
  4561.              setPiece(&theBoard, xcur, ycur, P_NOTHING);
  4562.           } else {
  4563.              addStone(curNode, t_AddWhite, xcur, ycur);
  4564.              setPiece(&theBoard, xcur, ycur, P_WHITE);
  4565.           }
  4566.           if (prop = getprop(curNode, t_Letter))
  4567.              lastletters = prop->data.stones;
  4568.  
  4569.           for (i = 0, cl = lastletters; cl; i++, cl = cl->next)
  4570.              (*io->plotLetter) (cl->x, cl->y, i % 26 + 'a');
  4571.  
  4572.            }
  4573.            break;
  4574.         case C_ADDLETTER:
  4575.            if (okChange()) {
  4576.  
  4577.  
  4578.  
  4579.           int sx, sy;
  4580.  
  4581.           for (; lastletters; lastletters = lastletters->next)
  4582.              (*io->plotPiece) (&theBoard, lastletters->x, lastletters->y);
  4583.           lastletters = 0;
  4584.  
  4585.           sx = xcur;
  4586.           sy = ycur;
  4587.  
  4588.  
  4589.           if (addMark(curNode, t_Letter, xcur, ycur))
  4590.              (*io->plotPiece) (&theBoard, xcur, ycur);
  4591.           stepDown(curNode, &theBoard);
  4592.           xcur = sx;
  4593.           ycur = sy;
  4594.            }
  4595.            break;
  4596.         case C_ADDMARK:
  4597.            if (okChange()) {
  4598.           int sx, sy;
  4599.  
  4600.           for (; lastmarks; lastmarks = lastmarks->next)
  4601.              (*io->plotPiece) (&theBoard, lastmarks->x, lastmarks->y);
  4602.           lastmarks = 0;
  4603.  
  4604.           sx = xcur;
  4605.           sy = ycur;
  4606.           if (addMark(curNode, t_Mark, xcur, ycur))
  4607.              (*io->plotPiece) (&theBoard, xcur, ycur);
  4608.  
  4609.           stepDown(curNode, &theBoard);
  4610.           xcur = sx;
  4611.           ycur = sy;
  4612.            }
  4613.            break;
  4614.         case C_EDCOMMENT:
  4615.            if (okChange()) {
  4616.           edComment(curNode);
  4617.           step(curNode, &theBoard);
  4618.            }
  4619.            break;
  4620.         case C_ADDNAME:
  4621.            if (okChange()) {
  4622.           makeName(curNode);
  4623.           step(curNode, &theBoard);
  4624.            }
  4625.            break;
  4626.         case C_DOWN:
  4627.            tNode = treeDown(curNode);
  4628.            if (tNode != curNode) {
  4629.           curNode = tNode;
  4630.           stepDown(curNode, &theBoard);
  4631.            }
  4632.            break;
  4633.         case C_UP:
  4634.            curNode = treeUp(curNode);
  4635.            step(curNode, &theBoard);
  4636.            break;
  4637.         case C_WALKDOWN:
  4638.            tNode = treeNext(curNode);
  4639.            if (tNode->parent == curNode) {
  4640.           stepDown(tNode, &theBoard);
  4641.            } else {
  4642.           step(tNode, &theBoard);
  4643.            }
  4644.            curNode = tNode;
  4645.            break;
  4646.         case C_WALKUP:
  4647.            curNode = treeLast(curNode);
  4648.            step(curNode, &theBoard);
  4649.            break;
  4650.         case C_SEARCHCOMMENT:
  4651.            {
  4652.           nodep tBegin;
  4653.           tBegin = curNode;
  4654.           tNode = curNode;
  4655.           do {
  4656.              tNode = treeNext(tNode);
  4657.           }
  4658.           while (tNode != tBegin && !getprop(tNode, t_Comment));
  4659.           if (tNode != curNode) {
  4660.              if (tNode->parent == curNode) {
  4661.             stepDown(tNode, &theBoard);
  4662.              } else {
  4663.             step(tNode, &theBoard);
  4664.              }
  4665.              curNode = tNode;
  4666.           }
  4667.            }
  4668.            break;
  4669.         case C_SEARCHBACKCOMMENT:
  4670.            tNode = curNode;
  4671.            curNode = curNode;
  4672.            do {
  4673.           curNode = treeLast(curNode);
  4674.            }
  4675.            while (curNode != tNode && !getprop(curNode, t_Comment));
  4676.            step(curNode, &theBoard);
  4677.            break;
  4678.         case C_UPFORK:
  4679.            while (curNode->parent) {
  4680.           curNode = curNode->parent;
  4681.           if (treeCountSiblings(curNode) > 1)
  4682.              break;
  4683.            }
  4684.            step(curNode, &theBoard);
  4685.            break;
  4686.         case C_DOWNFORK:
  4687.            {
  4688.           while (curNode->child) {
  4689.              curNode = treeDown(curNode);
  4690.              if (treeCountSiblings(curNode) > 1)
  4691.             break;
  4692.           }
  4693.           step(curNode, &theBoard);
  4694.            }
  4695.            break;
  4696.         case C_END:
  4697.            while (curNode->child) {
  4698.           curNode = treeDown(curNode);
  4699.            }
  4700.            step(curNode, &theBoard);
  4701.            break;
  4702.         case C_BEGINNING:
  4703.            curNode = root;
  4704.            step(curNode, &theBoard);
  4705.            break;
  4706.         case C_SCORE:
  4707.            doScore(&theBoard, curNode);
  4708.            break;
  4709.         case C_GOTO:
  4710.            {
  4711.           char buf[7];
  4712.           nodep new;
  4713.           if ((*io->queryStr) ("Move to node # ?", buf, 5)) {
  4714.              searchNodeNum = atoi(buf);
  4715.              if (searchNodeNum == 0 && strcmp(buf, "0"))
  4716.             searchNodeNum = -1;
  4717.              if (searchNodeNum >= 0) {
  4718.             if (new = search(root)) {
  4719.                curNode = new;
  4720.                step(curNode, &theBoard);
  4721.                (*io->notifyClear) ();
  4722.             } else {
  4723.                (*io->notifyClear) ();
  4724.                (*io->notifyError) ("Node not found.");
  4725.             }
  4726.  
  4727.              }
  4728.           }
  4729.            }
  4730.            break;
  4731.         case C_QUIT:
  4732.            if (okExit(root))
  4733.           quitflg++;
  4734.            break;
  4735.         case C_WRITE:
  4736.            {
  4737.           char filename[50];
  4738.           if ((*io->queryStr) ("Save name? ", filename, 48)) {
  4739.              if (!strcmp("*", filename)) {
  4740.             if (!writeTree(name_buf, root))
  4741.                madechanges = 0;
  4742.              } else {
  4743.             if (!writeTree(filename, root))
  4744.                madechanges = 0;
  4745.              }
  4746.           }
  4747.            }
  4748.            break;
  4749.         case C_SAVESHORT:
  4750.            saveShort = !saveShort;
  4751.            break;
  4752.         case C_CURLEFT:
  4753.            xcur = (xcur - 1 + boardsize) % boardsize;
  4754.            (*io->setCursor) (xcur, ycur);
  4755.            (*io->refreshIO) ();
  4756.            break;
  4757.         case C_CURRIGHT:
  4758.            xcur = (xcur + 1) % boardsize;
  4759.            (*io->setCursor) (xcur, ycur);
  4760.            (*io->refreshIO) ();
  4761.            break;
  4762.         case C_CURUP:
  4763.            ycur = (ycur - 1 + boardsize) % boardsize;
  4764.            (*io->setCursor) (xcur, ycur);
  4765.            (*io->refreshIO) ();
  4766.            break;
  4767.         case C_CURDOWN:
  4768.            ycur = (ycur + 1) % boardsize;
  4769.            (*io->setCursor) (xcur, ycur);
  4770.            (*io->refreshIO) ();
  4771.            break;
  4772.         case C_UPLEFT:
  4773.            ycur = (ycur - 1 + boardsize) % boardsize;
  4774.            xcur = (xcur - 1 + boardsize) % boardsize;
  4775.            (*io->setCursor) (xcur, ycur);
  4776.            (*io->refreshIO) ();
  4777.            break;
  4778.         case C_UPRIGHT:
  4779.            xcur = (xcur + 1) % boardsize;
  4780.            ycur = (ycur - 1 + boardsize) % boardsize;
  4781.            (*io->setCursor) (xcur, ycur);
  4782.            (*io->refreshIO) ();
  4783.            break;
  4784.         case C_DOWNLEFT:
  4785.            xcur = (xcur - 1 + boardsize) % boardsize;
  4786.            ycur = (ycur + 1) % boardsize;
  4787.            (*io->setCursor) (xcur, ycur);
  4788.            (*io->refreshIO) ();
  4789.            break;
  4790.         case C_DOWNRIGHT:
  4791.            xcur = (xcur + 1) % boardsize;
  4792.            ycur = (ycur + 1) % boardsize;
  4793.            (*io->setCursor) (xcur, ycur);
  4794.            (*io->refreshIO) ();
  4795.            break;
  4796.      }
  4797.    }
  4798. }
  4799. SHAR_EOF
  4800. fi
  4801. if test -f 'edit.c'
  4802. then
  4803.     echo shar: "will not over-write existing file 'edit.c'"
  4804. else
  4805. cat << \SHAR_EOF > 'edit.c'
  4806. /* "mgt" Copyright (c) 1991 Shodan  */
  4807.  
  4808. #include "mgt.h"
  4809.  
  4810. int first;
  4811. nodep buffer = 0;
  4812.  
  4813.  
  4814. FUNCTION void writeStrEscaped(output, s)
  4815. FILE *output;
  4816. char *s;
  4817. {
  4818.    while (*s) {
  4819.       if (*s == ')' || *s == '(' || *s == ']' || *s == '[')
  4820.      fputc('\\', output);
  4821.       fputc(*(s++), output);
  4822.    }
  4823. }
  4824.  
  4825.  
  4826. #define WRITE(short,long) if (saveShort) fputs(short,output);else fputs(long,output)
  4827.  
  4828.  
  4829. static char *infoshort[] =
  4830. {"PB", "BR", "PW", "WR",
  4831.  "GN", "EV", "RO", "DT", "PC", "TM", "RE", "GC",
  4832.  "SO", "US", "KM"};
  4833.  
  4834. static char *infolong[] =
  4835. {
  4836.    "PlayerBlack", "BlackRank", "PlayerWhite", "WhiteRank", "GameName", "EVent", "ROund",
  4837.    "DaTe", "PlaCe", "TiMe", "REsult", "GameComment", "SOurce", "USer", "KoMi"};
  4838.  
  4839.  
  4840.  
  4841. static void writeFirst(output)
  4842. FILE *output;
  4843. {
  4844.    int p;
  4845.    if (saveShort) {
  4846.       fprintf(output, "GM[1]VW[]SZ[%d]", boardsize);
  4847.       if (handicap)
  4848.      fprintf(output, "HA[%d]", handicap);
  4849.    } else {
  4850.       fprintf(output, "GaMe[1]\nVieW[]\nSiZe[%d]\n", boardsize);
  4851.       if (handicap)
  4852.      fprintf(output, "HAndicap[%d]\n", handicap);
  4853.    }
  4854.  
  4855.    for (p = 0; p <= t_Komi - FIRSTINFO; p++) {
  4856.       if (info[p]) {
  4857.      WRITE(infoshort[p], infolong[p]);
  4858.      fputc('[', output);
  4859.      writeStrEscaped(output, info[p]);
  4860.      WRITE("]", "]\n");
  4861.       }
  4862.    }
  4863. }
  4864.  
  4865.  
  4866.  
  4867. FUNCTION void writeNode(output, n)
  4868. FILE *output;
  4869. nodep n;
  4870. {
  4871.    property *prop;
  4872.    char str[1445];
  4873.  
  4874.    WRITE(";", ";\n");
  4875.    if (first) {
  4876.       writeFirst(output);
  4877.       first = 0;
  4878.    }
  4879.    prop = n->p;
  4880.    while (prop) {
  4881.       switch (prop->t) {
  4882.      case t_AddBlack:
  4883.         if (writeCoordList(prop->data.stones, str)) {
  4884.            WRITE("AB", "AddBlack");
  4885.            fputs(str, output);
  4886.         }
  4887.         break;
  4888.      case t_AddWhite:
  4889.         if (writeCoordList(prop->data.stones, str)) {
  4890.            WRITE("AW", "AddWhite");
  4891.            fputs(str, output);
  4892.         }
  4893.         break;
  4894.      case t_White:
  4895.         if (writeCoordList(prop->data.stones, str)) {
  4896.            WRITE("W", "White");
  4897.            fputs(str, output);
  4898.         }
  4899.         break;
  4900.      case t_Black:
  4901.         if (writeCoordList(prop->data.stones, str)) {
  4902.            WRITE("B", "Black");
  4903.            fputs(str, output);
  4904.         }
  4905.         break;
  4906.      case t_AddEmpty:
  4907.         if (writeCoordList(prop->data.stones, str)) {
  4908.            WRITE("AE", "AddEmpty");
  4909.            fputs(str, output);
  4910.         }
  4911.         break;
  4912.      case t_Mark:
  4913.         if (writeCoordList(prop->data.stones, str)) {
  4914.            WRITE("M", "Mark");
  4915.            fputs(str, output);
  4916.         }
  4917.         break;
  4918.      case t_Letter:
  4919.         if (writeCoordList(prop->data.stones, str)) {
  4920.            WRITE("L", "Letter");
  4921.            fputs(str, output);
  4922.         }
  4923.         break;
  4924.      case t_Name:
  4925.         if (strlen(prop->data.comment)) {
  4926.            WRITE("N[", "Name[");
  4927.            writeStrEscaped(output, prop->data.comment);
  4928.            WRITE("]", "]\n");
  4929.         }
  4930.         break;
  4931.      case t_Pass:
  4932.         if (prop->data.player == t_Black)
  4933.            WRITE("B", "Black");
  4934.         else
  4935.            WRITE("W", "White");
  4936.         WRITE("[tt]", "[tt]\n");
  4937.         break;
  4938.  
  4939.      case t_Player:
  4940.         WRITE("PL[", "PLayer[");
  4941.         if (prop->data.player == t_Black)
  4942.            fputc('B', output);
  4943.         else
  4944.            fputc('W', output);
  4945.         WRITE("]", "]\n");
  4946.         break;
  4947.      case t_Comment:
  4948.         if (strlen(prop->data.comment)) {
  4949.            WRITE("C[", "Comment[");
  4950.            writeStrEscaped(output, prop->data.comment);
  4951.            WRITE("]", "]\n");
  4952.         }
  4953.         break;
  4954.       }
  4955.       prop = prop->next;
  4956.    }
  4957. }
  4958.  
  4959.  
  4960.  
  4961. FUNCTION void WriteSubTree(output, root, sib)
  4962. FILE *output;
  4963. nodep root;
  4964. int sib;
  4965. {
  4966.    WRITE("(", "(\n");
  4967.    do {
  4968.       if (sib && root->nextSibling) {
  4969.      WriteSubTree(output, root, 0);
  4970.      while (root->nextSibling) {
  4971.         root = root->nextSibling;
  4972.         WriteSubTree(output, root, 0);
  4973.      }
  4974.      root = NULL;
  4975.       } else {
  4976.      writeNode(output, root);
  4977.      root = root->child;
  4978.      sib = 1;
  4979.       }
  4980.    }
  4981.    while (root);
  4982.    WRITE(")", ")\n");
  4983. }
  4984.  
  4985.  
  4986.  
  4987. FUNCTION int writeCoordList(list, str)
  4988. coordList *list;
  4989. char *str;
  4990. {
  4991.    *str = 0;
  4992.    while (list) {
  4993.       sprintf(str + strlen(str), "[%c%c]", list->x + 'a', list->y + 'a');
  4994.       list = list->next;
  4995.    }
  4996.    if (!(strlen(str)))
  4997.       return 0;
  4998.    if (!saveShort)
  4999.       strcat(str, "\n");
  5000.    return 1;
  5001. }
  5002.  
  5003.  
  5004.  
  5005. FUNCTION int writeTree(name, root)
  5006. char *name;
  5007. nodep root;
  5008. {
  5009.    FILE *output;
  5010.  
  5011.    if (output = fopen(name, "w")) {
  5012.       first = 1;
  5013.       WriteSubTree(output, root, 1);
  5014.       fclose(output);
  5015.       return 0;
  5016.    } else {
  5017.       (*io->notifyError) ("Error saving file.");
  5018.       return 1;
  5019.    }
  5020. }
  5021.  
  5022.  
  5023.  
  5024. static void clearSpace(prop, x, y)
  5025. property *prop;
  5026. int x, y;
  5027. {
  5028.    while (prop) {
  5029.       switch (prop->t) {
  5030.      case t_AddEmpty:
  5031.      case t_AddBlack:
  5032.      case t_AddWhite:
  5033.      case t_Black:
  5034.      case t_White:
  5035.      case t_Mark:
  5036.      case t_Letter:
  5037.         clearCoord(x, y, &(prop->data.stones));
  5038.         break;
  5039.       }
  5040.       prop = prop->next;
  5041.    }
  5042. }
  5043.  
  5044.  
  5045. FUNCTION int addMark(n, t, x, y)
  5046. nodep n;
  5047. Token t;
  5048. int x, y;
  5049. {
  5050.    property *prop;
  5051.  
  5052.    if (prop = getprop(n, t)) {
  5053.       if ((getCoord(x, y, prop->data.stones))) {
  5054.      clearCoord(x, y, &(prop->data.stones));
  5055.      return 1;
  5056.       }
  5057.    } else {
  5058.       prop = (property *) malloc(sizeof(property));
  5059.       if (!prop)
  5060.      barf("Memory allocation failure (markStone)");
  5061.       prop->next = n->p;
  5062.       n->p = prop;
  5063.       prop->data.stones = 0;
  5064.       prop->t = t;
  5065.  
  5066.    }
  5067.    setCoord(x, y, &(prop->data.stones));
  5068.    return 0;
  5069. }
  5070.  
  5071.  
  5072.  
  5073.  
  5074. FUNCTION void addStone(n, t, x, y)
  5075. nodep n;
  5076. Token t;
  5077. int x, y;
  5078. {
  5079.    property *prop;
  5080.  
  5081.    clearSpace(n->p, x, y);
  5082.    if (!(prop = getprop(n, t))) {
  5083.       prop = (property *) calloc(1, sizeof(property));
  5084.       if (!prop)
  5085.      barf("Memory allocation failure (addStone)");
  5086.       prop->next = n->p;
  5087.       n->p = prop;
  5088.       prop->data.stones = 0;
  5089.       prop->t = t;
  5090.    }
  5091.    setCoord(x, y, &(prop->data.stones));
  5092.  
  5093. }
  5094.  
  5095. FUNCTION int makeMove(n, t, x, y)
  5096. nodep n;
  5097. Token t;
  5098. int x, y;
  5099. {
  5100.    nodep new;
  5101.    property *prop;
  5102.    int ret;
  5103.    ret = 0;
  5104.  
  5105.    if (!(n->p)) {
  5106.       new = n;
  5107.       ret = 1;
  5108.    } else {
  5109.  
  5110.       new = newNode();
  5111.       if (n->child)
  5112.      n->child->parent = new;
  5113.       new->parent = n;
  5114.       new->child = n->child;
  5115.       n->child = new;
  5116.    }
  5117.  
  5118.  
  5119.    prop = (property *) calloc(1, sizeof(property));
  5120.    if (!prop)
  5121.       barf("Memory allocation failure (makeMove)");
  5122.    new->p = prop;
  5123.    prop->data.stones = 0;
  5124.    prop->t = t;
  5125.  
  5126.    setCoord(x, y, &(prop->data.stones));
  5127.    return ret;
  5128.  
  5129. }
  5130.  
  5131. FUNCTION int passMove(n, t)
  5132. nodep n;
  5133. Token t;
  5134. {
  5135.    nodep new;
  5136.    property *prop;
  5137.    int ret;
  5138.    ret = 0;
  5139.  
  5140.    if (!(n->p)) {
  5141.       new = n;
  5142.       ret = 1;
  5143.    } else {
  5144.  
  5145.       new = newNode();
  5146.       if (n->child)
  5147.      n->child->parent = new;
  5148.       new->parent = n;
  5149.       new->child = n->child;
  5150.       n->child = new;
  5151.    }
  5152.  
  5153.  
  5154.    prop = (property *) calloc(1, sizeof(property));
  5155.    if (!prop)
  5156.       barf("Memory allocation failure (passMove)");
  5157.    new->p = prop;
  5158.    prop->data.player = t;
  5159.    prop->t = t_Pass;
  5160.  
  5161.    return ret;
  5162.  
  5163. }
  5164.  
  5165.  
  5166. FUNCTION void addPlayer(n, t)
  5167. nodep n;
  5168. Token t;
  5169. {
  5170.    property *prop;
  5171.    if (!(prop = getprop(n, t_Player))) {
  5172.       prop = (property *) calloc(1, sizeof(property));
  5173.       if (!prop)
  5174.      barf("Memory allocation failure (addPlayer)");
  5175.       addprop(n, prop);
  5176.    }
  5177.    prop->data.player = t;
  5178.    prop->t = t_Player;
  5179. }
  5180.  
  5181.  
  5182. FUNCTION void makeVariation(n)
  5183. nodep n;
  5184. {
  5185.    nodep new, last;
  5186.  
  5187.    if (!(n->child)) {
  5188.       new = newNode();
  5189.       new->parent = n;
  5190.       n->child = new;
  5191.    } else {
  5192.       new = newNode();
  5193.       new->parent = n;
  5194.       last = treeLastSibling(n->child);
  5195.       last->nextSibling = new;
  5196.       new->lastSibling = last;
  5197.    }
  5198. }
  5199.  
  5200.  
  5201. FUNCTION void cutTree(n)
  5202. nodep n;
  5203. {
  5204.    freeNode(buffer);
  5205.    if (n->nextSibling)
  5206.       n->nextSibling->lastSibling = n->lastSibling;
  5207.    if (n->lastSibling)
  5208.       n->lastSibling->nextSibling = n->nextSibling;
  5209.    else if (n->parent)
  5210.       n->parent->child = n->nextSibling;
  5211.    n->nextSibling = 0;
  5212.    n->lastSibling = 0;
  5213.    buffer = n;
  5214. }
  5215.  
  5216.  
  5217. FUNCTION boolean pasteTree(n)
  5218. nodep n;
  5219. {
  5220.    nodep last, sib;
  5221.    if (buffer) {
  5222.       for (last = buffer; last->child; last = last->child);
  5223.       if (n->child) {
  5224.      n->child->parent = last;
  5225.      for (sib = n->child->nextSibling; sib; sib = sib->nextSibling)
  5226.         sib->parent = last;
  5227.      last->child = n->child;
  5228.       }
  5229.       n->child = buffer;
  5230.       buffer->parent = n;
  5231.       buffer = (nodep) 0;
  5232.       return true;
  5233.    }
  5234.    return false;
  5235. }
  5236.  
  5237.  
  5238. FUNCTION void edComment(n)
  5239. nodep n;
  5240. {
  5241.    property *prop;
  5242.  
  5243.    if (!(prop = getprop(n, t_Comment))) {
  5244.       prop = (property *) calloc(1, sizeof(property));
  5245.       prop->t = t_Comment;
  5246.       prop->next = n->p;
  5247.       n->p = prop;
  5248.    }
  5249.    (*io->editComment) (prop->data.comment, &(prop->data.comment));
  5250.    if (!(prop->data.comment)) {
  5251.       n->p = prop->next;
  5252.       free(prop);
  5253.    }
  5254. }
  5255.  
  5256.  
  5257.  
  5258. FUNCTION void deleteNode(n)
  5259. nodep *n;
  5260. {
  5261.    nodep last;
  5262.    if (!((*n)->child)) {
  5263.       freeProps(*n);
  5264.       (*n)->p = 0;
  5265.    } else {
  5266.       if ((*n)->parent && (*n)->parent->child == *n)
  5267.      (*n)->parent->child = (*n)->child;
  5268.       if ((*n)->lastSibling) {
  5269.      (*n)->child->lastSibling = (*n)->lastSibling;
  5270.      (*n)->lastSibling->nextSibling = (*n)->child;
  5271.       }
  5272.       /* new parent for all of child's sibs */
  5273.  
  5274.       for (last = (*n)->child; last->nextSibling; last = last->nextSibling)
  5275.      last->parent = (*n)->parent;
  5276.       last->parent = (*n)->parent;
  5277.  
  5278.       /* Last of child's sibs get's to point to next sib of main node */
  5279.       last->nextSibling = (*n)->nextSibling;
  5280.  
  5281.       if ((*n)->nextSibling)
  5282.      (*n)->nextSibling = last;
  5283.       last = *n;
  5284.       *n = (*n)->child;
  5285.       delNode(last);
  5286.    }
  5287. }
  5288.  
  5289.  
  5290. FUNCTION void makeName(n)
  5291. nodep n;
  5292. {
  5293.    char newname[41];
  5294.    property *prop;
  5295.  
  5296.    (*io->queryStr) ("Name: ", newname, 40);
  5297.  
  5298.    if (prop = getprop(n, t_Name))
  5299.       free(prop->data.comment);
  5300.    else {
  5301.       prop = (property *) calloc(1, sizeof(property));
  5302.       addprop(n, prop);
  5303.       prop->t = t_Name;
  5304.    }
  5305.    prop->data.comment = dupStr(newname);
  5306. }
  5307.  
  5308.  
  5309. FUNCTION void replaceComment(n, str)
  5310. nodep n;
  5311. char *str;
  5312. {
  5313.    property *prop;
  5314.  
  5315.    if (!(prop = getprop(n, t_Comment))) {
  5316.       prop = (property *) calloc(1, sizeof(property));
  5317.       prop->t = t_Comment;
  5318.       prop->next = n->p;
  5319.       n->p = prop;
  5320.    } else
  5321.       free(prop->data.comment);
  5322.    prop->data.comment = dupStr(str);
  5323. }
  5324. SHAR_EOF
  5325. fi
  5326. if test -f 'mgt.c'
  5327. then
  5328.     echo shar: "will not over-write existing file 'mgt.c'"
  5329. else
  5330. cat << \SHAR_EOF > 'mgt.c'
  5331. /* "mgt" Copyright (c) 1991 Shodan  */
  5332.  
  5333.  
  5334. #include <signal.h>
  5335. #include "mgt.h"
  5336.  
  5337. int retVal = 0;
  5338. interface *io;            /* current interface routines */
  5339. int boardsize;            /* global for board size */
  5340. char *info[LASTINFO - FIRSTINFO + 2];
  5341. int handicap;
  5342. char *commentBuf;        /* pointer to current node's comment */
  5343. extern interface asciiInterface;
  5344. int prisoners[2];
  5345. FILE *input = 0;
  5346. char name_buf[512];
  5347. char *files[MAX_FILES];
  5348. int filecount, currentfile;
  5349.  
  5350. #ifdef DEBUG
  5351. FILE *debug;
  5352. unsigned long totalmemory;
  5353. #endif
  5354.  
  5355. #ifdef MGT_IBM
  5356. extern unsigned _stklen = 32000;
  5357. #endif
  5358.  
  5359. typedef struct {
  5360.    char *arg;
  5361.    int *flag;
  5362.    char **str;
  5363. }  argType;
  5364.  
  5365.  
  5366. int mailFlag = 0;
  5367. int saveShort = 0;
  5368. int tutor = 0;
  5369. char *saveName;
  5370.  
  5371.  
  5372.  
  5373. static argType argTable[] =
  5374. {
  5375.    {"-m", &mailFlag, &saveName},
  5376.    {"-s", &saveShort, NULL},
  5377.    {"-t", &tutor, NULL}
  5378. };
  5379.  
  5380.  
  5381. FUNCTION main(argc, argv)
  5382. int argc;
  5383. char **argv;
  5384. {
  5385.  
  5386. #ifdef DEBUG
  5387.    debug = fopen("debug", "w");
  5388. #endif
  5389.  
  5390.    io = &asciiInterface;
  5391.    input = stdin;
  5392.    init(argv, &argc);
  5393.    parseLine(argc, argv);
  5394.    doit();
  5395.    myexit();
  5396. }
  5397.  
  5398.  
  5399.  
  5400. FUNCTION void die()
  5401. {
  5402.    signal(SIGINT, SIG_DFL);
  5403.    myexit();
  5404. }
  5405.  
  5406.  
  5407. FUNCTION void myexit()
  5408. {
  5409.    (*io->clearScreen) ();
  5410.    (*io->refreshIO) ();
  5411.    (*io->close) ();
  5412.    printf("Thank you for using mgt\n");
  5413.    exit(retVal);
  5414. }
  5415.  
  5416.  
  5417.  
  5418. FUNCTION void openfile(f)
  5419. char *f;
  5420. {
  5421. #ifdef MGT_LIB
  5422.    char game_lib[] = MGT_LIB;
  5423. #endif                /* MGT_LIB */
  5424.    strcpy(name_buf, f);
  5425.    if (!(input = fopen(f, "r")))
  5426.       strcpy(name_buf, "");
  5427. #ifdef MGT_LIB
  5428.    /* if not in local directory, try library */
  5429.    if (!input) {
  5430.       strcpy(name_buf, game_lib);
  5431.       strcat(name_buf, f);
  5432.       input = fopen(name_buf, "r");
  5433.    }
  5434. #endif                /* MGT_LIB */
  5435. }
  5436.  
  5437.  
  5438. FUNCTION void barf(s)
  5439. char *s;
  5440. {
  5441.    int i;
  5442.    for (i = 24; i--;)
  5443.       fprintf(stderr, "\n");
  5444.    fprintf(stderr, "%s\n", s);
  5445.    exit(1);
  5446. }
  5447.  
  5448.  
  5449. FUNCTION void initEnv()
  5450. {
  5451.    extern char *getenv();
  5452.    char *env;
  5453.  
  5454.    if (env = getenv("MGT"))
  5455.       while (*env) {
  5456.      while (*env && *env != '_')
  5457.         env++;
  5458.      if (*env)
  5459.         env++;
  5460.      if (*env)
  5461.         (*io->readEnv) (&env);
  5462.       }
  5463. }
  5464.  
  5465.  
  5466. FUNCTION void init(argv, argc)
  5467. char *argv[];
  5468. int *argc;
  5469. {
  5470.    initEnv();
  5471.    (*io->open) (argv, argc);
  5472.    signal(SIGINT, die);
  5473.    readInit();
  5474. }
  5475.  
  5476.  
  5477.  
  5478. FUNCTION void helpCommandLine(errMesg)
  5479. char *errMesg;
  5480. {
  5481.    (*io->close) ();
  5482.    fprintf(stderr, "\nERROR: %s\n\n", errMesg);
  5483.    fprintf(stderr, "                   MGT %s\n", VERSION);
  5484.    fprintf(stderr, "\nUsage: mgt [opts] [files]\n");
  5485.    fprintf(stderr, "[opts] is any of:\n");
  5486.    fprintf(stderr, "-m filename        mail mode.  Autosave on quit.\n");
  5487.    fprintf(stderr, "-s                 use short format when saving.\n\n");
  5488.    exit(2);
  5489. }
  5490.  
  5491.  
  5492. FUNCTION void parseLine(argc, argv)
  5493. int argc;
  5494. char **argv;
  5495. {
  5496.    int i;
  5497.  
  5498.    filecount = 0;
  5499.  
  5500.    while (++argv, --argc > 0) {
  5501.       if (**argv != '-') {
  5502.      files[filecount++] = *argv;
  5503.      if (filecount == MAX_FILES)
  5504.         helpCommandLine("Too many files specified");
  5505.       } else {
  5506.      for (i = 0; i < sizeof(argTable) / sizeof(argType); i++)
  5507.         if (!strcmp(argTable[i].arg, *argv)) {
  5508.            if (argTable[i].str)
  5509.           if (--argc)
  5510.              *(argTable[i].str) = (*++argv);
  5511.           else
  5512.              helpCommandLine("String expected on option");
  5513.            (*(argTable[i].flag))--;
  5514.            break;
  5515.         }
  5516.      if (i == sizeof(argTable) / sizeof(argType))
  5517.         helpCommandLine("Bad option");
  5518.       }
  5519.    }
  5520.    if (!filecount)
  5521.       input = stdin;
  5522.    else {
  5523.       currentfile = 0;
  5524.       openfile(files[0]);
  5525.       if (!input)
  5526.      helpCommandLine("File not found");
  5527.    }
  5528.  
  5529. }
  5530. SHAR_EOF
  5531. fi
  5532. if test -f 'parse.c'
  5533. then
  5534.     echo shar: "will not over-write existing file 'parse.c'"
  5535. else
  5536. cat << \SHAR_EOF > 'parse.c'
  5537. /* "mgt" Copyright (c) 1991 Shodan  */
  5538.  
  5539. #include <string.h>
  5540. #include "mgt.h"
  5541.  
  5542.  
  5543. struct {
  5544.    char *str;
  5545.    Token val;
  5546. }  tokens[] = {
  5547.    {
  5548.       "W", t_White
  5549.    },
  5550.    {
  5551.       "B", t_Black
  5552.    },
  5553.    {
  5554.       "C", t_Comment
  5555.    },
  5556.    {
  5557.       "AW", t_AddWhite
  5558.    },
  5559.    {
  5560.       "AB", t_AddBlack
  5561.    },
  5562.    {
  5563.       "L", t_Letter
  5564.    },
  5565.    {
  5566.       "AE", t_AddEmpty
  5567.    },
  5568.    {
  5569.       "N", t_Name
  5570.    },
  5571.    {
  5572.       "M", t_Mark
  5573.    },
  5574.    {
  5575.       "SZ", t_Size
  5576.    },
  5577.    {
  5578.       "GN", t_GameName
  5579.    },
  5580.    {
  5581.       "GC", t_GameComment
  5582.    },
  5583.    {
  5584.       "EV", t_Event
  5585.    },
  5586.    {
  5587.       "RO", t_Round
  5588.    },
  5589.    {
  5590.       "DT", t_Date
  5591.    },
  5592.    {
  5593.       "PC", t_Place
  5594.    },
  5595.    {
  5596.       "PB", t_PlayerBlack
  5597.    },
  5598.    {
  5599.       "PW", t_PlayerWhite
  5600.    },
  5601.    {
  5602.       "RE", t_Result
  5603.    },
  5604.    {
  5605.       "US", t_User
  5606.    },
  5607.    {
  5608.       "TM", t_TimeLimit
  5609.    },
  5610.    {
  5611.       "SO", t_Source
  5612.    },
  5613.    {
  5614.       "BR", t_BlackRank
  5615.    },
  5616.    {
  5617.       "WR", t_WhiteRank
  5618.    },
  5619.    {
  5620.       "HA", t_Handicap
  5621.    },
  5622.    {
  5623.       "KM", t_Komi
  5624.    }, {
  5625.       "PL", t_Player
  5626.    }
  5627.  
  5628. };
  5629.  
  5630.  
  5631. char buf[1028], *curin, started;
  5632.  
  5633. FUNCTION void readInit()
  5634. {
  5635.    int p;
  5636.    buf[0] = '\0';
  5637.    curin = &buf[0];
  5638.    started = 1;
  5639.    boardsize = 19;
  5640.    handicap = 0;
  5641.    for (p = 0; p <= LASTINFO - FIRSTINFO + 1; p++) {
  5642.       if (info[p])
  5643.      free(info[p]);
  5644.       info[p] = 0;
  5645.    }
  5646. }
  5647.  
  5648.  
  5649. static char *readLine()
  5650. {
  5651.    curin = &buf[0];
  5652.    buf[0] = '\0';
  5653.    return fgets(&buf[0], 1023, input);
  5654. }
  5655.  
  5656.  
  5657. static char readChar()
  5658. {
  5659.    if (*curin)
  5660.       return *(curin++);
  5661.    curin = &buf[0];
  5662.    buf[0] = '\0';
  5663.    fgets(&buf[0], 1023, input);
  5664.    return 0;
  5665. }
  5666.  
  5667.  
  5668.  
  5669. static int getCoordStr(co)
  5670. coord *co;
  5671. {
  5672.    if (strlen(curin) < 4 && curin[strlen(curin) - 1] != '\n') {
  5673.       char *dest;
  5674.       for (dest = buf; *curin; curin++, dest++)
  5675.      *dest = *curin;
  5676.       *dest = 0;
  5677.       fgets(dest, 1023, input);
  5678.       curin = buf;
  5679.    }
  5680.    if (curin[0] == '[' && curin[1] >= 'a' && curin[1] <= 's'
  5681.        && curin[2] >= 'a' && curin[2] <= 's' && curin[3] == ']') {
  5682.       co->x = curin[1] - 'a';
  5683.       co->y = curin[2] - 'a';
  5684.       curin += 4;
  5685.       while (*curin == ' ' || *curin == '\t')
  5686.      curin++;
  5687.       if (*curin == '\n')
  5688.      readLine();
  5689.       return 1;
  5690.    } else
  5691.       return 0;
  5692. }
  5693.  
  5694.  
  5695. static void getCoordList(clp)
  5696. coordList **clp;
  5697. {
  5698.    coord co;
  5699.    while (getCoordStr(&co)) {
  5700.       setCoord(co.x, co.y, clp);
  5701.    }
  5702. }
  5703.  
  5704. static void addPass(n, t)
  5705. nodep n;
  5706. Token t;
  5707. {
  5708.    property *p;
  5709.    if (!(p = (property *) calloc(1, sizeof(property))))
  5710.       barf("Memory allocation error (addPass)");
  5711.    p->t = t_Pass;
  5712.    p->data.player = t;
  5713.    addprop(n, p);
  5714.  
  5715. }
  5716.  
  5717.  
  5718.  
  5719. static void doPlayer(n)
  5720. nodep n;
  5721.  
  5722. {
  5723.    property *p;
  5724.  
  5725.    if (curin[0] == '[' && curin[2] == ']' && (curin[1] == 'B' || curin[1] == 'W')) {
  5726.       p = (property *) calloc(1, sizeof(property));
  5727.       if (!p)
  5728.      barf("Memory allocation failure (doPlayer)");
  5729.       p->t = t_Player;
  5730.       p->data.player = curin[1] == 'B' ? t_Black : t_White;
  5731.       curin += 3;
  5732.       addprop(n, p);
  5733.    }
  5734. }
  5735.  
  5736.  
  5737. static Token tokenize()
  5738. {
  5739.    int i, len;
  5740.    char buf[4];
  5741.  
  5742.    len = 0;
  5743.    do {
  5744.       if (!*curin || *curin == '\n') {
  5745.      if (!readLine())
  5746.         return t_EOF;
  5747.       }
  5748.       if (*curin == ')') {
  5749.      curin++;
  5750.      return t_Close;
  5751.       }
  5752.       if (*curin == '(') {
  5753.      curin++;
  5754.      return t_Open;
  5755.       }
  5756.       if (*curin == ';') {
  5757.      curin++;
  5758.      return t_NewNode;
  5759.       }
  5760.       if (*curin >= 'A' && *curin <= 'Z')
  5761.      buf[len++] = *curin;
  5762.       curin++;
  5763.    } while (len < 3 && *curin != '[');
  5764.    buf[len] = 0;
  5765.    if (len == 1 || len == 2)
  5766.       for (i = 0; i < sizeof(tokens) / sizeof(tokens[0]); i++)
  5767.      if (!strcmp(buf, tokens[i].str))
  5768.         return tokens[i].val;
  5769.    while (*curin != ']') {
  5770.       if (!*++curin) {
  5771.      if (!readLine())
  5772.         return t_EOF;
  5773.       }
  5774.    }
  5775.    return t_WS;
  5776. }
  5777.  
  5778.  
  5779.  
  5780. static void addMoveArrayProp(t, n)
  5781. Token t;
  5782. nodep n;
  5783. {
  5784.    property *p;
  5785.  
  5786. #ifdef DEBUG
  5787.    totalmemory += sizeof(property);
  5788.    fprintf(debug, "%ld %ld\n", totalmemory, coreleft());
  5789. #endif
  5790.    if (!(p = getprop(n, t))) {
  5791.       p = (property *) calloc(1, sizeof(property));
  5792.  
  5793. #ifdef DEBUG
  5794.       totalmemory += sizeof(coordList);
  5795.       fprintf(debug, "%ld %ld\n", totalmemory, coreleft());
  5796. #endif
  5797.  
  5798.       if (!p)
  5799.      barf("Memory allocation failure (addMoveArrayProp)");
  5800.  
  5801.       p->data.stones = 0;
  5802.       p->t = t;
  5803.       addprop(n, p);
  5804.    }
  5805.    getCoordList(&(p->data.stones));
  5806. }
  5807.  
  5808.  
  5809. static void doSize()
  5810. {
  5811.    int size;
  5812.    char *s, c, b[25];
  5813.    s = &b[0];
  5814.    readChar();
  5815.    while ((c = readChar()) != ']')
  5816.       if (c && c != '\\')
  5817.      *s++ = c;
  5818.    *s = 0;
  5819.    size = atoi(b);
  5820.    if ((size > 1) && (size <= 19))
  5821.       boardsize = size;
  5822. }
  5823.  
  5824.  
  5825.  
  5826. static void doHandicap()
  5827. {
  5828.    int size;
  5829.    char *s, c, b[25];
  5830.    s = &b[0];
  5831.    readChar();
  5832.    while ((c = readChar()) != ']')
  5833.       if (c && c != '\\')
  5834.      *s++ = c;
  5835.    *s = 0;
  5836.    size = atoi(b);
  5837.    if ((size > 1) && (size <= 17))
  5838.       handicap = size;
  5839. }
  5840.  
  5841.  
  5842. /* gets text.  Assumes we start on a '['.  Returns pointer to a buffer which
  5843.  * should be freed */
  5844.  
  5845. static char *getText()
  5846. {
  5847.    int c;
  5848.    char *s;
  5849.    char *buffer;
  5850.    int space = COMMENTALLOC;
  5851.    int blocks = 1;
  5852.  
  5853.    buffer = (char *) malloc(COMMENTALLOC);
  5854.    if (!buffer)
  5855.       barf("Memory Allocation Failure (getText)");
  5856.    s = buffer;
  5857.  
  5858.    (void) readChar();
  5859.    while ((c = readChar()) != ']') {
  5860.       if (!c) {
  5861.      c = readChar();
  5862.      if (!c || c == ']')
  5863.         break;
  5864.       }
  5865.       if (space <= 1) {
  5866.      buffer = (char *) realloc(buffer, ++blocks * COMMENTALLOC);
  5867.      if (!buffer)
  5868.         barf("Memory Allocation Failure (getText)");
  5869.      s = buffer - space + (blocks - 1) * COMMENTALLOC;
  5870.      space += COMMENTALLOC;
  5871.       }
  5872.       if (c == '\\')
  5873.      c = readChar();
  5874.       if (c) {
  5875.      *s++ = c;
  5876.      space--;
  5877.       }
  5878.    }
  5879.    if (s != buffer && *(s - 1) == '\n')
  5880.       s--;
  5881.    *s = 0;
  5882.    return buffer;
  5883. }
  5884.  
  5885.  
  5886. static void doComment(n, t)
  5887. nodep n;
  5888. Token t;
  5889. {
  5890.    property *p;
  5891.    char *buffer;
  5892.  
  5893.    p = (property *) calloc(1, sizeof(property));
  5894.    if (!p)
  5895.       barf("Memory Allocation Failure (doComment)");
  5896.    buffer = getText();
  5897.    p->t = t;
  5898.    p->data.comment = dupStr(buffer);
  5899.    addprop(n, p);
  5900.    free(buffer);
  5901. }
  5902.  
  5903.  
  5904. static void doInfo(t)
  5905. Token t;
  5906. {
  5907.    char *buffer;
  5908.  
  5909.    buffer = getText();
  5910.    info[(int) t - FIRSTINFO] = dupStr(buffer);
  5911.    free(buffer);
  5912. }
  5913.  
  5914.  
  5915. FUNCTION void addChild(n, c)    /* add child c to node n */
  5916. nodep n, c;
  5917. {
  5918.    if (n) {
  5919.       if (n->child) {
  5920.      nodep s;
  5921.      s = treeLastSibling(child(n));
  5922.      s->nextSibling = c;
  5923.      c->lastSibling = s;
  5924.      c->parent = n;
  5925.       } else {
  5926.      n->child = c;
  5927.      c->parent = n;
  5928.       }
  5929.    }
  5930. }
  5931.  
  5932.  
  5933. FUNCTION nodep parse(lev)
  5934. int lev;
  5935. {
  5936.    nodep r, n, new;
  5937.    Token t;
  5938.  
  5939.    if (started) {
  5940.       started = 0;
  5941.  
  5942.       while (*curin != '(') {
  5943.      if (!readLine())
  5944.         break;
  5945.       }
  5946.    }
  5947.    r = n = 0;
  5948.    for (;;) {
  5949.       t = tokenize();
  5950.       switch (t) {
  5951.      case t_Size:
  5952.         doSize();
  5953.         break;
  5954.      case t_White:
  5955.      case t_Black:
  5956.         if (curin[1] == 't' && curin[2] == 't' && curin[0] == '[' && curin[3] == ']') {
  5957.            addPass(n, t);
  5958.            break;
  5959.         }
  5960.      case t_AddWhite:
  5961.      case t_AddBlack:
  5962.      case t_AddEmpty:
  5963.      case t_Mark:
  5964.      case t_Letter:
  5965.         if (n)
  5966.            addMoveArrayProp(t, n);
  5967.         else
  5968.            fprintf(stderr, "Error - property w/o node in data\n");
  5969.         break;
  5970.      case t_Player:
  5971.         if (n)
  5972.            doPlayer(n);
  5973.         else
  5974.            fprintf(stderr, "Error - property w/o node in data\n");
  5975.         break;
  5976.      case t_Name:
  5977.      case t_Comment:
  5978.         if (n)
  5979.            doComment(n, t);
  5980.         else
  5981.            fprintf(stderr, "Error - property w/o node in data\n");
  5982.         break;
  5983.      case t_NewNode:
  5984.         new = newNode();
  5985.         if (!r)
  5986.            r = new;
  5987.         else
  5988.            addChild(n, new);
  5989.         n = new;
  5990.         break;
  5991.      case t_Open:
  5992.         if (lev == 1 && !r)
  5993.            n = r = newNode();
  5994.         if (new = parse(lev + 1)) {
  5995.            addChild(n, new);
  5996.            if (!r)
  5997.           r = new;
  5998.         }
  5999.         break;
  6000.      case t_Close:
  6001.      case t_EOF:
  6002.         return r;
  6003.  
  6004.      case t_GameName:
  6005.      case t_GameComment:
  6006.      case t_Event:
  6007.      case t_Round:
  6008.      case t_Date:
  6009.      case t_Place:
  6010.      case t_PlayerBlack:
  6011.      case t_PlayerWhite:
  6012.      case t_Result:
  6013.      case t_User:
  6014.      case t_TimeLimit:
  6015.      case t_Source:
  6016.      case t_BlackRank:
  6017.      case t_WhiteRank:
  6018.  
  6019.         doInfo(t);
  6020.         break;
  6021.      case t_Komi:{
  6022.            char *ch, *end;
  6023.            doInfo(t_Komi);
  6024.            end = ch = info[(int) t_Komi - FIRSTINFO];
  6025.            while (*end)
  6026.           end++;
  6027.            for (end--; *end == '0' && (end != ch); end--);
  6028.            *++end = 0;
  6029.         }
  6030.         break;
  6031.      case t_Handicap:
  6032.         doHandicap();
  6033.         break;
  6034.      default:
  6035.         break;
  6036.       }
  6037.    }
  6038. }
  6039. SHAR_EOF
  6040. fi
  6041. if test -f 'play.c'
  6042. then
  6043.     echo shar: "will not over-write existing file 'play.c'"
  6044. else
  6045. cat << \SHAR_EOF > 'play.c'
  6046. /* "mgt" Copyright (c) 1991 Shodan  */
  6047.  
  6048.  
  6049. #include "mgt.h"
  6050. #include <string.h>
  6051. #include <stdio.h>
  6052.  
  6053. /* void printboard(char *s,pBoard b) { FILE *fil; int i,j;
  6054.  * fil=fopen("dump","a+"); if (!fil) {printf("can't open file");getch();}
  6055.  * fprintf(fil,"%s\n",s); for(i=0;i<boardsize;i++){ for(j=0;j<boardsize;j++)
  6056.  * fputc( b->b[i][j]==P_NOTHING?'.':(b->b[i][j]==P_BLACK?'*':'O'),fil);
  6057.  * fputc('\n',fil); } fclose(fil); } */
  6058.  
  6059.  
  6060.  
  6061.  
  6062. FUNCTION int legal(b, n, player, i, j)
  6063. pBoard b;
  6064. nodep n;
  6065. int i, j;
  6066. Token player;
  6067. {
  6068.    board a, copy;
  6069.    int same, x, y, savex, savey, savemove;
  6070.    boolean islegal;
  6071.    extern int moveNum;
  6072.    int savepris[2];
  6073.  
  6074.    savemove = moveNum;
  6075.    savex = xcur;
  6076.    savey = ycur;
  6077.    savepris[0] = prisoners[0];
  6078.    savepris[1] = prisoners[1];
  6079.    copyBoard(b, ©);
  6080.  
  6081.    islegal = true;
  6082.  
  6083.    if (b->b[i][j] != P_NOTHING) {
  6084.       (*io->notifyError) ("There's already a piece there.");
  6085.       return false;
  6086.    }
  6087.    placeStone(©, i, j, (player == t_Black) ? P_BLACK : P_WHITE);
  6088.    if (!alive(©, i, j)) {
  6089.       (*io->notifyError) ("That move is suicide.");
  6090.       islegal = false;
  6091.    }
  6092.    if (islegal && (n = n->parent)) {
  6093.       boardClear(&a);
  6094.       buildTree0(n, &a);
  6095.       same = true;
  6096.       for (x = boardsize; same && x--;)
  6097.      for (y = boardsize; same && y--;) {
  6098.         same = (copy.b[x][y] == a.b[x][y]);
  6099.      }
  6100.       if (same) {
  6101.      (*io->notifyError) ("Can't retake the ko yet.");
  6102.      islegal = false;
  6103.       }
  6104.    }
  6105.    xcur = savex;
  6106.    ycur = savey;
  6107.    prisoners[0] = savepris[0];
  6108.    moveNum = savemove;
  6109.    prisoners[1] = savepris[1];
  6110.  
  6111.    return islegal;
  6112. }
  6113.  
  6114.  
  6115.  
  6116.  
  6117. FUNCTION boolean inRange(i, j)
  6118. {
  6119.    return i >= 0 && i < boardsize && j >= 0 && j < boardsize;
  6120. }
  6121.  
  6122. FUNCTION boolean alive0(b, m, i, j, t)
  6123. pBoard b;
  6124. pBoard m;
  6125. int i, j;
  6126. piece t;
  6127. {
  6128.    piece pt;
  6129.  
  6130.    pt = b->b[i][j];
  6131.    if ((pt != P_NOTHING && pt != t) || m->b[i][j] != P_NOTHING)
  6132.       return 0;
  6133.    m->b[i][j] = (pt == t) ? (piece) 1 : (piece) 2;
  6134.    if (pt == P_NOTHING)
  6135.       return 1;
  6136.    return
  6137.       (j < boardsize - 1 && alive0(b, m, i, j + 1, t)) ||
  6138.       (i < boardsize - 1 && alive0(b, m, i + 1, j, t)) ||
  6139.       (i && alive0(b, m, i - 1, j, t)) ||
  6140.       (j && alive0(b, m, i, j - 1, t));
  6141. }
  6142.  
  6143. FUNCTION boolean alive(b, i, j)    /* Does group at i,j have liberties? */
  6144. pBoard b;
  6145. int i, j;
  6146. {
  6147.    board m;
  6148.  
  6149.    boardClear(&m);
  6150.    return alive0(b, &m, i, j, b->b[i][j]);
  6151. }
  6152.  
  6153. void removeStones0(b, i, j, t)
  6154. pBoard b;
  6155. int i, j;
  6156. piece t;
  6157. {
  6158.    if (b->b[i][j] != t)
  6159.       return;
  6160.    b->b[i][j] = P_NOTHING;
  6161.    prisoners[(int) t - 1]++;
  6162.    if (j < boardsize - 1)
  6163.       removeStones0(b, i, j + 1, t);
  6164.    if (i < boardsize - 1)
  6165.       removeStones0(b, i + 1, j, t);
  6166.    if (i)
  6167.       removeStones0(b, i - 1, j, t);
  6168.    if (j)
  6169.       removeStones0(b, i, j - 1, t);
  6170. }
  6171.  
  6172.  
  6173.  
  6174. FUNCTION void removeStones(b, i, j)
  6175. pBoard b;
  6176. int i, j;
  6177. {
  6178.    removeStones0(b, i, j, b->b[i][j]);
  6179. }
  6180.  
  6181. FUNCTION boolean tryKill(b, i, j, t)
  6182. pBoard b;
  6183. int i, j;
  6184. piece t;
  6185. {
  6186.    piece w;
  6187.    if (!inRange(i, j))
  6188.       return false;
  6189.    w = b->b[i][j];
  6190.    if (w != P_NOTHING && w != t && !alive(b, i, j)) {
  6191.       removeStones(b, i, j);
  6192.       return true;
  6193.    }
  6194.    return false;
  6195. }
  6196.  
  6197. FUNCTION void placeStone(b, i, j, t)
  6198. pBoard b;
  6199. int i, j;
  6200. piece t;
  6201. {
  6202.    if (inRange(i, j)) {
  6203.       b->b[i][j] = t;
  6204.       xcur = i;
  6205.       ycur = j;
  6206.       if (j)
  6207.      tryKill(b, i, j - 1, t);
  6208.       if (j < boardsize - 1)
  6209.      tryKill(b, i, j + 1, t);
  6210.       if (i)
  6211.      tryKill(b, i - 1, j, t);
  6212.       if (i < boardsize - 1)
  6213.      tryKill(b, i + 1, j, t);
  6214.    }
  6215. }
  6216.  
  6217. FUNCTION void boardSet(b, i, j, p)
  6218. pBoard b;
  6219. int i, j;
  6220. piece p;
  6221. {
  6222.    b->b[i][j] = p;
  6223. }
  6224.  
  6225. FUNCTION piece boardGet(b, i, j)
  6226. pBoard b;
  6227. int i, j;
  6228. {
  6229.    return b->b[i][j];
  6230. }
  6231.  
  6232.  
  6233. FUNCTION void boardClear(b)
  6234. pBoard b;
  6235. {
  6236.    memset((char *) (b->b), 0, 361 * sizeof(piece));
  6237.  
  6238.    /* int i, j; for (i = boardsize; i--;) for (j = boardsize; j--;) b->b[i][j]
  6239.     * = P_NOTHING; */
  6240. }
  6241.  
  6242. FUNCTION void copyBoard(a, b)
  6243. pBoard a, b;
  6244. {
  6245.    int i, j;
  6246.    for (i = boardsize; i--;)
  6247.       for (j = boardsize; j--;)
  6248.      b->b[i][j] = a->b[i][j];
  6249. }
  6250.  
  6251.  
  6252. int look(stone, array, index, i)
  6253. int stone, array[], *index, i;
  6254. {
  6255.    if (stone == P_NOTHING)
  6256.       array[(*index)++] = i;
  6257.    else if (stone == P_BLACK)
  6258.       return 1;
  6259.    else if (stone == P_WHITE)
  6260.       return 2;
  6261.    return 0;
  6262. }
  6263.  
  6264.  
  6265. int fillregion(b, x, y)
  6266. pBoard b;
  6267. int x, y;
  6268. {
  6269.    int goup[19], godown[19], up = 0, down = 0, found = 0, i;
  6270.  
  6271.    for (i = x; i < boardsize && b->b[i][y] == P_NOTHING; i++) {
  6272.       b->b[i][y] = P_CHECKED;
  6273.       if (y > 0)
  6274.      found |= look(b->b[i][y - 1], goup, &up, i);
  6275.       if (y < boardsize - 1)
  6276.      found |= look(b->b[i][y + 1], godown, &down, i);
  6277.    }
  6278.    if (i != boardsize) {
  6279.       if (b->b[i][y] == P_BLACK)
  6280.      found |= 1;
  6281.       if (b->b[i][y] == P_WHITE)
  6282.      found |= 2;
  6283.    }
  6284.    for (i = x - 1; i >= 0 && b->b[i][y] == P_NOTHING; i--) {
  6285.       b->b[i][y] = P_CHECKED;
  6286.       if (y > 0)
  6287.      found |= look(b->b[i][y - 1], goup, &up, i);
  6288.       if (y < boardsize - 1)
  6289.      found |= look(b->b[i][y + 1], godown, &down, i);
  6290.    }
  6291.    if (i != -1) {
  6292.       if (b->b[i][y] == P_BLACK)
  6293.      found |= 1;
  6294.       if (b->b[i][y] == P_WHITE)
  6295.      found |= 2;
  6296.    }
  6297.    while (up)
  6298.       found |= fillregion(b, goup[--up], y - 1);
  6299.    while (down)
  6300.       found |= fillregion(b, godown[--down], y + 1);
  6301.    return found;
  6302. }
  6303.  
  6304.  
  6305. FUNCTION void scoreBoard(b, score)
  6306. pBoard b;
  6307. int score[];
  6308. {
  6309.    int x, y, i, j, owner;
  6310.    piece newval;
  6311.  
  6312.    score[0] = 0;
  6313.    score[1] = 0;
  6314.    for (i = 0; i < boardsize; i++)
  6315.       for (j = 0; j < boardsize; j++) {
  6316.      owner = fillregion(b, i, j);
  6317.      if (!owner)
  6318.         owner = 3;
  6319.      switch (owner) {
  6320.         case 3:
  6321.            newval = P_DAME;
  6322.            break;
  6323.         case 2:
  6324.            newval = P_WHITETERR;
  6325.            break;
  6326.         case 1:
  6327.            newval = P_BLACKTERR;
  6328.            break;
  6329.      }
  6330.      for (x = 0; x < boardsize; x++)
  6331.         for (y = 0; y < boardsize; y++)
  6332.            if (b->b[x][y] == P_CHECKED) {
  6333.           b->b[x][y] = newval;
  6334.           if (owner != 3)
  6335.              score[owner - 1]++;
  6336.            }
  6337.       }
  6338. }
  6339. SHAR_EOF
  6340. fi
  6341. if test -f 'tree.c'
  6342. then
  6343.     echo shar: "will not over-write existing file 'tree.c'"
  6344. else
  6345. cat << \SHAR_EOF > 'tree.c'
  6346. /* "mgt" Copyright (c) 1991 Shodan  */
  6347.  
  6348. #include "mgt.h"
  6349.  
  6350.  
  6351. static int newNodeNum;
  6352.  
  6353.  
  6354. FUNCTION boolean getCoord(x, y, list)
  6355. int x, y;
  6356. coordList *list;
  6357. {
  6358.    for (; list; list = list->next)
  6359.       if (list->x == x && list->y == y)
  6360.      return true;
  6361.    return false;
  6362. }
  6363.  
  6364.  
  6365.  
  6366. FUNCTION coordList *addCoord(x, y)
  6367. int x, y;
  6368. {
  6369.    coordList *co;
  6370.  
  6371.    if (!(co = (coordList *) malloc(sizeof(coordList))))
  6372.       barf("Memory allocation failure (addCoord)");
  6373.    co->next = 0;
  6374.    co->x = x;
  6375.    co->y = y;
  6376.    return co;
  6377. }
  6378.  
  6379.  
  6380.  
  6381. FUNCTION void setCoord(x, y, startlist)
  6382. int x, y;
  6383. coordList **startlist;
  6384. {
  6385.    coordList *list;
  6386.    if (!*startlist)
  6387.       *startlist = addCoord(x, y);
  6388.    else {
  6389.       for (list = *startlist; list->next; list = list->next)
  6390.      if (x == list->x && y == list->y)
  6391.         return;
  6392.       list->next = addCoord(x, y);
  6393.    }
  6394. }
  6395.  
  6396.  
  6397. FUNCTION void clearCoord(x, y, startlist)
  6398. int x, y;
  6399. coordList **startlist;
  6400.  
  6401. {
  6402.    coordList *last, *list;
  6403.  
  6404.    last = 0;
  6405.    list = *startlist;
  6406.    while (list && (x != list->x || y != list->y)) {
  6407.       last = list;
  6408.       list = list->next;
  6409.    }
  6410.    if (list) {
  6411.       if (last)
  6412.      last->next = list->next;
  6413.       else
  6414.      *startlist = list->next;
  6415.       free(list);
  6416.    }
  6417. }
  6418.  
  6419.  
  6420. FUNCTION void initNodes()
  6421. {
  6422.    newNodeNum = 0;
  6423. }
  6424.  
  6425. FUNCTION nodep newNode()
  6426. {
  6427.    nodep new;
  6428. #ifdef DEBUG
  6429.    totalmemory += sizeof(node);
  6430.    fprintf(debug, "%ld %ld\n", totalmemory, coreleft());
  6431. #endif
  6432.    new = (nodep) calloc(1, sizeof(node));
  6433.    if (!new)
  6434.       barf("Memory allocation failure (newnode)");
  6435.    new->nodeNum = newNodeNum++;
  6436.    return new;
  6437. }
  6438.  
  6439. FUNCTION void freeNode(n)
  6440. nodep n;
  6441. {
  6442.    if (n) {
  6443.       freeNode(n->nextSibling);
  6444.       freeNode(n->child);
  6445.       delNode(n);
  6446.    }
  6447. }
  6448.  
  6449. FUNCTION char *dupStr(s)
  6450. char *s;
  6451. {
  6452.    char *c;
  6453. #ifdef DEBUG
  6454.    totalmemory += strlen(s) + 1;
  6455.    fprintf(debug, "%ld %ld\n", totalmemory, coreleft());
  6456. #endif
  6457.    c = (char *) malloc((unsigned) strlen(s) + 1);
  6458.    if (!c)
  6459.       barf("Memory allocation failure (dupstr)");
  6460.    strcpy(c, s);
  6461.    return c;
  6462. }
  6463.  
  6464.  
  6465.  
  6466. FUNCTION void freeProps(n)
  6467. nodep n;
  6468. {
  6469.    property *prop, *lastprop;
  6470.    coordList *cl, *lastcl;
  6471.    prop = n->p;
  6472.    while (prop) {
  6473.       switch (prop->t) {
  6474.      case t_AddEmpty:
  6475.      case t_AddBlack:
  6476.      case t_AddWhite:
  6477.      case t_Mark:
  6478.      case t_Letter:
  6479.      case t_Black:
  6480.      case t_White:
  6481.         cl = prop->data.stones;
  6482.         while (cl) {
  6483.            lastcl = cl;
  6484.            cl = cl->next;
  6485.            free(lastcl);
  6486.         }
  6487.         break;
  6488.      case t_Name:
  6489.      case t_Comment:
  6490.         free(prop->data.comment);
  6491.         break;
  6492.  
  6493.       }
  6494.  
  6495.       lastprop = prop;
  6496.       prop = prop->next;
  6497.       free(lastprop);
  6498.    }
  6499. }
  6500.  
  6501.  
  6502. FUNCTION void delNode(n)
  6503. nodep n;
  6504. {
  6505.    freeProps(n);
  6506.    free(n);
  6507. }
  6508.  
  6509. FUNCTION void addprop(n, p)
  6510. nodep n;
  6511. property *p;
  6512. {
  6513.    p->next = n->p;
  6514.    n->p = p;
  6515. }
  6516.  
  6517. FUNCTION property *getprop(n, t)
  6518. nodep n;
  6519. Token t;
  6520. {
  6521.    property *p;
  6522.    p = n->p;
  6523.    while (p && p->t != t)
  6524.       p = p->next;
  6525.    return p;
  6526. }
  6527.  
  6528. FUNCTION int treeCountSiblings(n)
  6529. nodep n;
  6530. {
  6531.    int i;
  6532.    nodep n1;
  6533.  
  6534.    n1 = n->child;
  6535.    i = 0;
  6536.    while (n1) {
  6537.       n1 = n1->nextSibling;
  6538.       i++;
  6539.    }
  6540.    return i;
  6541. }
  6542.  
  6543. FUNCTION nodep nthChild(n, c)    /* nodep, int */
  6544. nodep n;
  6545. int c;
  6546. {
  6547.  
  6548.    if (n->child) {
  6549.       n = child(n);
  6550.       while (c-- && n)
  6551.      n = nextSibling(n);
  6552.    } else {
  6553.       n = 0;
  6554.    }
  6555.    return n;
  6556. }
  6557.  
  6558. /* TREE WALK functions KEEP TRACK OF DEPTH AS WELL */
  6559.  
  6560. FUNCTION nodep parent(n)
  6561. nodep n;
  6562. {
  6563.    return n->parent;
  6564. }
  6565.  
  6566. FUNCTION nodep child(n)
  6567. nodep n;
  6568. {
  6569.    return n->child;
  6570. }
  6571.  
  6572. FUNCTION nodep lastSibling(n)
  6573. nodep n;
  6574. {
  6575.    return n->lastSibling;
  6576. }
  6577.  
  6578. FUNCTION nodep nextSibling(n)
  6579. nodep n;
  6580. {
  6581.    return n->nextSibling;
  6582. }
  6583.  
  6584. FUNCTION nodep treeLastSibling(n)
  6585. nodep n;
  6586. {
  6587.    while (n->nextSibling) {
  6588.       n = n->nextSibling;
  6589.    }
  6590.    return n;
  6591. }
  6592.  
  6593. /* go to next node down the tree. Stop if at bottom. */
  6594. FUNCTION nodep treeDown(n)
  6595. nodep n;
  6596. {
  6597.    if (n->child) {
  6598.       BUG("treeDown: going down\n");
  6599.       return child(n);
  6600.    } else {
  6601.       BUG("treeDown: stop\n");
  6602.       return n;
  6603.    }
  6604. }
  6605.  
  6606. /* backup, stop if at top */
  6607. FUNCTION nodep treeUp(n)
  6608. nodep n;
  6609. {
  6610.    if (n->parent) {
  6611.       BUG("treeUp: going up\n");
  6612.       return parent(n);
  6613.    } else {
  6614.       BUG("treeUp: staying\n");
  6615.       return n;
  6616.    }
  6617. }
  6618.  
  6619.  
  6620. /* go to next node backing up the tree only */
  6621. FUNCTION nodep treeNextUp(n)
  6622. nodep n;
  6623. {
  6624.    if (n->nextSibling) {
  6625.       BUG("nextSibling ");
  6626.       return nextSibling(n);
  6627.    } else if (n->parent) {
  6628.       BUG("nextup-parent ");
  6629.       while (n->parent && !n->nextSibling)
  6630.      n = parent(n);
  6631.       if (n->nextSibling)
  6632.      return nextSibling(n);
  6633.       else
  6634.      return n;
  6635.    } else if (n->child) {
  6636.       BUG("child ");
  6637.       return child(n);
  6638.    } else {
  6639.       BUG("current ");
  6640.       return n;
  6641.    }
  6642. }
  6643.  
  6644.  
  6645. /* go to next node, backup if neccessary */
  6646. FUNCTION nodep treeNext(n)
  6647. nodep n;
  6648. {
  6649.    nodep r;
  6650.  
  6651.    BUG("treeNext:");
  6652.    if (n != (r = treeDown(n))) {
  6653.       BUG("going down ");
  6654.    } else {
  6655.       BUG("going up ");
  6656.       r = treeNextUp(n);
  6657.    }
  6658.    BUG("\n");
  6659.    return r;
  6660. }
  6661.  
  6662.  
  6663.  
  6664. FUNCTION nodep lastChildOfLastSibling(n)
  6665. nodep n;
  6666. {
  6667.  
  6668.    while (n->nextSibling)
  6669.       n = nextSibling(n);
  6670.    if (n->child)
  6671.       return lastChildOfLastSibling(child(n));
  6672.    else
  6673.       return n;
  6674. }
  6675.  
  6676. /* go to next node, backup if neccessary */
  6677. FUNCTION nodep treeLast(n)
  6678. nodep n;
  6679. {
  6680.    nodep r;
  6681.  
  6682.    if (n->lastSibling) {
  6683.       n = lastSibling(n);
  6684.       if (n->child)
  6685.      r = lastChildOfLastSibling(child(n));
  6686.       else
  6687.      r = n;
  6688.    } else if (n->parent) {
  6689.       r = parent(n);
  6690.    } else if (n->child) {
  6691.       r = lastChildOfLastSibling(child(n));
  6692.    } else {
  6693.       r = n;
  6694.    }
  6695.    return r;
  6696. }
  6697. SHAR_EOF
  6698. fi
  6699. if test -f 'mgt.h'
  6700. then
  6701.     echo shar: "will not over-write existing file 'mgt.h'"
  6702. else
  6703. cat << \SHAR_EOF > 'mgt.h'
  6704. /* "mgt" Copyright (c) 1991 Shodan  */
  6705.  
  6706. #define VERSION "2.3"
  6707.  
  6708. #ifdef DEBUG
  6709. #define BUG(s) fprintf(debug,s)
  6710. #else
  6711. #define BUG(s)
  6712. #endif
  6713.  
  6714. #define FUNCTION
  6715. #define false 0
  6716. #define true 1
  6717.  
  6718. #define MAX(a,b) ((a)>(b)?a:b)
  6719. #define MIN(a,b) ((a)<(b)?a:b)
  6720.  
  6721. #define MAX_FILES 200
  6722. #define MAXCOMMENTWIDTH 50
  6723. #define COMMENTALLOC 4096
  6724.  
  6725. typedef int boolean;
  6726.  
  6727. typedef enum {
  6728.    C_QUIT = 0,
  6729.    C_DOWN, C_UP,
  6730.    C_WALKDOWN, C_WALKUP,
  6731.    C_END, C_BEGINNING,
  6732.    C_SEARCHCOMMENT, C_SEARCHBACKCOMMENT,
  6733.    C_DOWNFORK, C_UPFORK,
  6734.    C_GOTO,
  6735.    C_WRITE,
  6736.    C_ADDBLACK, C_ADDWHITE,
  6737.    C_ADDVAR,
  6738.    C_TREECUT,
  6739.    C_ADDLETTER, C_ADDMARK,
  6740.    C_LOAD, C_PASTE,
  6741.    C_EDCOMMENT,
  6742.    C_DELNODE, C_ADDNAME, C_SCORE, C_PASSMOVE, C_TOPLAY, C_TOGGLESTONE, C_BACKFILE, C_NEXTFILE,
  6743.    C_REDRAW, C_SAVESHORT, C_TUTORSWAP, C_SAVESCREEN, C_INFO, C_MOVE,
  6744.    C_DOWNLEFT, C_CURDOWN, C_DOWNRIGHT, C_CURLEFT,
  6745.    C_CURRIGHT, C_UPLEFT, C_CURUP, C_UPRIGHT,
  6746.    C_LASTCOMMAND, C_UNDO
  6747. }  command;
  6748.  
  6749.  
  6750. /* C_COMMENTSCROLLDOWN, C_COMMENTSCROLLUP, C_TREESCROLLDOWN, C_TREESCROLLUP, */
  6751.  
  6752. #define C_NOTHING ((command) 75)
  6753. #define C_CHOSECHILD ((command) 76)
  6754. #define C_NEXTCMD ((command) 127)
  6755.  
  6756. typedef enum {
  6757.    t_White,
  6758.    t_Black,
  6759.    t_Open,
  6760.    t_Close,
  6761.    t_NewNode,
  6762.    t_Comment,
  6763.    t_AddWhite,
  6764.    t_AddBlack,
  6765.    t_Letter,
  6766.    t_Mark,
  6767.    t_AddEmpty,
  6768.    t_Name,
  6769.    t_Pass,
  6770.    t_Player,
  6771.    t_Size,
  6772.    t_Handicap,
  6773.    t_PlayerBlack,
  6774.    t_BlackRank,
  6775.    t_PlayerWhite,
  6776.    t_WhiteRank,
  6777.    t_GameName,
  6778.    t_Event,
  6779.    t_Round,
  6780.    t_Date,
  6781.    t_Place,
  6782.    t_TimeLimit,
  6783.    t_Result,
  6784.    t_GameComment,
  6785.    t_Source,
  6786.    t_User,
  6787.    t_Komi,
  6788.  
  6789.    t_WS,
  6790.    t_EOF
  6791. }
  6792.    Token;
  6793.  
  6794.  
  6795. #define FIRSTINFO ((int)t_PlayerBlack)
  6796. #define LASTINFO  ((int)t_User)
  6797.  
  6798.  
  6799. typedef enum {
  6800.    P_NOTHING = 0, P_BLACK, P_WHITE, P_DAME, P_BLACKTERR, P_WHITETERR, P_CHECKED
  6801. }
  6802.    piece;
  6803.  
  6804. typedef piece boardType[19][19];
  6805.  
  6806. typedef struct {
  6807.    boardType b;
  6808. }
  6809.    board, *pBoard;
  6810.  
  6811.  
  6812. typedef int (*pfi) ();
  6813.  
  6814. typedef struct {
  6815.    char *name;
  6816.    char *option;
  6817.    char *storage;
  6818.    pfi open, close, refreshIO, plotPiece, displayComment;
  6819.    pfi clearComment, initializeBoard, clearScreen, idle;
  6820.    pfi drawTree, highlightLast, readEnv, notifyMessage;
  6821.    pfi notifyClear, queryStr, setCursor, plotMark, plotLetter;
  6822.    pfi getPoint, editComment, askYN, notifyError, displayInfo;
  6823.    pfi getInfoToChange, editInfo;
  6824. }
  6825.    interface, *interfaceP;
  6826.  
  6827.  
  6828. typedef struct {
  6829.    char x, y;
  6830. }
  6831.    coord;
  6832.  
  6833.  
  6834. typedef struct coordstruct {
  6835.    char x, y;
  6836.    struct coordstruct *next;
  6837. }  coordList;
  6838.  
  6839.  
  6840. typedef struct propertyRec {
  6841.    struct propertyRec *next;
  6842.    Token t;
  6843.    union {
  6844.       coordList *stones;
  6845.       char *comment;
  6846.       Token player;
  6847.    }  data;
  6848. }
  6849.    property;
  6850.  
  6851.  
  6852. typedef struct noderec {
  6853.    property *p;
  6854.    int nodeNum;
  6855.    struct noderec *parent, *child, *nextSibling, *lastSibling;
  6856. }
  6857.    node, *nodep;
  6858.  
  6859.  
  6860. /* board coordinates used to indicate a pass */
  6861.  
  6862. #define PASSVAL 25
  6863.  
  6864.  
  6865.  
  6866. #include "proto.h"
  6867. #include <stdio.h>
  6868.  
  6869. #ifdef MGT_IBM
  6870. #include <alloc.h>
  6871. #endif
  6872.  
  6873.  
  6874. extern char *info[LASTINFO - FIRSTINFO + 2];
  6875. extern int handicap;
  6876.  
  6877. extern int prisoners[];
  6878. extern interface *io;
  6879. extern int boardsize;
  6880. extern FILE *input;
  6881. extern int xcur, ycur;
  6882. extern Token curPlayer;
  6883. extern int mailFlag;
  6884. extern int saveShort;
  6885. extern int tutor;
  6886. extern char *saveName;
  6887. extern int retVal;
  6888. extern char name_buf[512];
  6889. extern filecount, currentfile;
  6890. extern char *files[MAX_FILES];
  6891.  
  6892. #ifdef DEBUG
  6893. extern FILE *debug;
  6894. extern unsigned long totalmemory;
  6895. #endif
  6896. SHAR_EOF
  6897. fi
  6898. if test -f 'proto.h'
  6899. then
  6900.     echo shar: "will not over-write existing file 'proto.h'"
  6901. else
  6902. cat << \SHAR_EOF > 'proto.h'
  6903. extern void clearLast();
  6904. extern void highlightLast();
  6905. extern void doPlace();
  6906. extern void doProps();
  6907. extern void doPropComment();
  6908. extern void buildTree0();
  6909. extern void buildTree();
  6910. extern void setPiece();
  6911. extern void updateBoard();
  6912. extern char *commentGet();    /* int */
  6913. extern int commentLines();
  6914. extern void formatComment();
  6915. extern int okChange();
  6916. extern int okExit();
  6917. extern nodep search();    /* return 0 on failure */
  6918. extern void step();
  6919. extern void stepDown();
  6920. extern void doScore();
  6921. extern nodep loadFile();
  6922. extern nodep makeTutor();
  6923. extern void doit();
  6924. extern void writeStrEscaped();
  6925. extern void writeNode();
  6926. extern void WriteSubTree();
  6927. extern int writeCoordList();
  6928. extern int writeTree();
  6929. extern int addMark();
  6930. extern void addStone();
  6931. extern int makeMove();
  6932. extern int passMove();
  6933. extern void addPlayer();
  6934. extern void makeVariation();
  6935. extern void cutTree();
  6936. extern boolean pasteTree();
  6937. extern void edComment();
  6938. extern void deleteNode();
  6939. extern void makeName();
  6940. extern void replaceComment();
  6941. extern main();
  6942. extern void die();
  6943. extern void myexit();
  6944. extern void openfile();
  6945. extern void barf();
  6946. extern void initEnv();
  6947. extern void init();
  6948. extern void helpCommandLine();
  6949. extern void parseLine();
  6950. extern void readInit();
  6951. extern void addChild();    /* add child c to node n */
  6952. extern nodep parse();
  6953. extern int legal();
  6954. extern boolean inRange();
  6955. extern boolean alive0();
  6956. extern boolean alive();    /* Does group at i,j have liberties? */
  6957. extern void removeStones();
  6958. extern boolean tryKill();
  6959. extern void placeStone();
  6960. extern void boardSet();
  6961. extern piece boardGet();
  6962. extern void boardClear();
  6963. extern void copyBoard();
  6964. extern void scoreBoard();
  6965. extern boolean getCoord();
  6966. extern coordList *addCoord();
  6967. extern void setCoord();
  6968. extern void clearCoord();
  6969. extern void initNodes();
  6970. extern nodep newNode();
  6971. extern void freeNode();
  6972. extern char *dupStr();
  6973. extern void freeProps();
  6974. extern void delNode();
  6975. extern void addprop();
  6976. extern property *getprop();
  6977. extern int treeCountSiblings();
  6978. extern nodep nthChild();    /* nodep, int */
  6979. extern nodep parent();
  6980. extern nodep child();
  6981. extern nodep lastSibling();
  6982. extern nodep nextSibling();
  6983. extern nodep treeLastSibling();
  6984. extern nodep treeDown();
  6985. extern nodep treeUp();
  6986. extern nodep treeNextUp();
  6987. extern nodep treeNext();
  6988. extern nodep lastChildOfLastSibling();
  6989. extern nodep treeLast();
  6990. SHAR_EOF
  6991. fi
  6992. if test -f 'mou.h'
  6993. then
  6994.     echo shar: "will not over-write existing file 'mou.h'"
  6995. else
  6996. cat << \SHAR_EOF > 'mou.h'
  6997. /*****************************************************************************
  6998.  * PROJECT:  Mouse routines with 'real' graphic cursor in text mode.
  6999.  *****************************************************************************
  7000.  * MODULE:  MOU.H
  7001.  *****************************************************************************
  7002.  * DESCRIPTION:
  7003.  *   Header file for the mouse routines.
  7004.  *
  7005.  *****************************************************************************
  7006.  * MODIFICATION NOTES:
  7007.  *    Date     Author Comment
  7008.  * 07-Jan-1991   dk   Fixed bugs and set up for release to Usenet.
  7009.  * 26-Oct-1990   dk   Initial file.
  7010.  *****************************************************************************
  7011.  *
  7012.  * DISCLAIMER:
  7013.  *
  7014.  * Programmers may incorporate any or all code into their programs,
  7015.  * giving proper credit within the source. Publication of the
  7016.  * source routines is permitted so long as proper credit is given
  7017.  * to Dave Kirsch.
  7018.  *
  7019.  * Copyright (C) 1990, 1991 by Dave Kirsch.  You may use this program, or
  7020.  * code or tables extracted from it, as desired without restriction.
  7021.  * I can not and will not be held responsible for any damage caused from
  7022.  * the use of this software.
  7023.  *
  7024.  *****************************************************************************
  7025.  * This source works with Turbo C 2.0 and MSC 6.0 and above.
  7026.  *****************************************************************************/
  7027.  
  7028. /********************************************************/
  7029. /* 26-Oct-1990 - dk                                     */
  7030. /*                                                      */
  7031. /*  Standard types and constants I use in my programs.  */
  7032. /*                                                      */
  7033. /********************************************************/
  7034.  
  7035. typedef unsigned char       byte;
  7036. typedef unsigned short int  word;
  7037. typedef unsigned short int  mouseboolean;
  7038. typedef unsigned long  int  dword;
  7039.  
  7040. #define FALSE 0
  7041. #define TRUE (!FALSE)
  7042.  
  7043. #ifdef __TURBOC__
  7044.   #define FAST pascal     /* for fast calling of functions -- Turbo C */
  7045. #else
  7046.   #define FAST _fastcall  /* for fast calling of functions -- MicroSoft C 6.0 */
  7047.   #define asm _asm
  7048. #endif
  7049. #define LOCAL   near   /* function can not be called outside of this module */
  7050. #define PRIVATE static /* function is private */
  7051. #define STATIC  static /* private variables */
  7052.  
  7053. #ifndef MK_FP
  7054.   #define MK_FP(seg,ofs)  ((void far *) \
  7055.                              (((unsigned long)(seg) << 16) | (unsigned)(ofs)))
  7056. #endif
  7057.  
  7058. #ifndef poke
  7059. #define poke(a,b,c)     (*((int  far*)MK_FP((a),(b))) = (int)(c))
  7060. #define pokeb(a,b,c)    (*((char far*)MK_FP((a),(b))) = (char)(c))
  7061. #define peek(a,b)       (*((int  far*)MK_FP((a),(b))))
  7062. #define peekb(a,b)      (*((char far*)MK_FP((a),(b))))
  7063. #endif
  7064.  
  7065. /***************************************************/
  7066. /* Mon 07-Jan-1991 - dk                            */
  7067. /*                                                 */
  7068. /*  Variables and defines for the mouse routines.  */
  7069. /*                                                 */
  7070. /***************************************************/
  7071.  
  7072. /* Size of mouse "click" ahead buffer. */
  7073. #define MOUSEBUFFERSIZE 16
  7074.  
  7075. /* Bit defines for mouse driver function 12 -- define handler. */
  7076. #define MOUSEMOVE      1
  7077. #define LEFTBPRESS     2
  7078. #define LEFTBRELEASE   4
  7079. #define RIGHTBPRESS    8
  7080. #define RIGHTBRELEASE 16
  7081. #define MIDBPRESS     32
  7082. #define MIDBRELEASE   64
  7083.  
  7084. #define LEFTBDOWN  1
  7085. #define RIGHTBDOWN 2
  7086. #define MIDBDOWN   4
  7087.  
  7088. /* Shift states for byte a 0:417h
  7089.    bit 7 =1 INSert active
  7090.    bit 6 =1 Caps Lock active
  7091.    bit 5 =1 Num Lock active
  7092.    bit 4 =1 Scroll Lock active
  7093.    bit 3 =1 either Alt pressed
  7094.    bit 2 =1 either Ctrl pressed
  7095.    bit 1 =1 Left Shift pressed
  7096.    bit 0 =1 Right Shift pressed
  7097. */
  7098.  
  7099. #define SHIFT_RIGHTSHIFT 0x01
  7100. #define SHIFT_LEFTSHIFT  0x02
  7101. #define SHIFT_SHIFT      0x03 /* Either shift key. */
  7102. #define SHIFT_CTRL       0x04
  7103. #define SHIFT_ALT        0x08
  7104. #define SHIFT_SCROLLLOCK 0x10
  7105. #define SHIFT_NUMLOCK    0x20
  7106. #define SHIFT_CAPSLOCK   0x40
  7107. #define SHIFT_INS        0x80
  7108.  
  7109. /* Mouse information record */
  7110. struct minforectype {
  7111.   word buttonstat;
  7112.   word    cx, cy;
  7113.   byte shiftstate;
  7114. };
  7115.  
  7116. #define MOUINFOREC struct minforectype
  7117.  
  7118. extern word mousehidden;           /* Is the mouse on? Additive flag */
  7119. extern mouseboolean mouseinstalled;     /* Is the mouse installed? */
  7120.  
  7121. extern volatile word mousex, mousey; /* Mouse coordinates in characters. */
  7122.  
  7123. /* Initialize the mouse routines -- must be called. */
  7124. void    FAST MOUinit(void);
  7125.  
  7126. /* Deinitialize the mouse routines -- must be called on shutdown.
  7127.    Failure to call it will most likely result in a system crash if the mouse
  7128.    is moved. */
  7129. void    FAST MOUdeinit(void);
  7130.  
  7131. /* Hide the mouse cursor */
  7132. void    FAST MOUhide(void);
  7133.  
  7134. /* Hide the mouse cursor if it moves or is in a specific rectangular region
  7135.    of the screen. */
  7136. void    FAST MOUconditionalhide(int x1, int y1, int x2, int y2);
  7137.  
  7138. /* Show the mouse cursor */
  7139. void    FAST MOUshow(void);
  7140.  
  7141. /* return TRUE if there are events waiting in the buffer. */
  7142. mouseboolean FAST MOUcheck(void);
  7143.  
  7144. /* look at the next event in the buffer, but don't pull it out. */
  7145. void    FAST MOUpreview(MOUINFOREC *mouinforec);
  7146.  
  7147. /* get and remove next event from the buffer. */
  7148. void    FAST MOUget(MOUINFOREC *mouinforec);
  7149.  
  7150. /* return the current status of the mouse buttons (see defines above). */
  7151. word    FAST MOUbuttonstatus(void);
  7152.  
  7153. /* Set the mouse cursor to a specific screen position. */
  7154. void FAST MOUsetpos(word x, word y);
  7155. SHAR_EOF
  7156. fi
  7157. if test -f 'Smart-Go.def'
  7158. then
  7159.     echo shar: "will not over-write existing file 'Smart-Go.def'"
  7160. else
  7161. cat << \SHAR_EOF > 'Smart-Go.def'
  7162.                    DEFINITION OF THE SMART-GO FORMAT
  7163.  
  7164. From the Dissertation of Anders Kierulf
  7165.  
  7166. "Smart Game Board:
  7167. a Workbench for Game-Playing
  7168. Programs, with Go and Othello
  7169. as Case Studies"
  7170.  
  7171. Entered by Greg Hale with permission for distribution. See the many sample 
  7172. files from the 'My Go Teacher' series for examples. 
  7173.     
  7174. ------------
  7175.  
  7176. A standard file format to exchange machine-readable games, problems,
  7177. and opening libraries would save time and work.  That goal may not be
  7178. too far away.  A standard for exchanging collections of Othello games
  7179. is being worked out by Erik Jensen, Emmanuel Lazard, and Brian Rose in
  7180. collaboration with the author.  For Go, a new standard has recently
  7181. been proposed [Connelley 89, High 89]; it seems to suffer from a wealth
  7182. of features, but any standard for exchanging Go games is welcome, and
  7183. will be supported by the Smart Game Board.
  7184.  
  7185. The current file format is specialized for the needs of the Smart Game
  7186. Board.  It is based on an earlier proposal for a standard for Go games
  7187. [Kierulf 87b] which was not widely adopted.  The following description
  7188. is not a new proposal; it is intended for those who want to read or
  7189. white files that are compatible with the Smart Game Board.
  7190.  
  7191. The game collections (documents) of the Smart Game Board are stored as
  7192. text files.  This has the advantage that files can be manipulated with
  7193. standard text utilities, and that it's easier to exchange games by
  7194. electronic mail.  The disadvantage is that text files are less compact
  7195. than binary files.
  7196.  
  7197. The Smart Game Board stores the game trees of each document, with all
  7198. their nodes and properties, and nothing more.  Thus the file format
  7199. reflects the regular internal structure of a tree of property lists.
  7200. There are no exceptions; if a game needs to store some information on
  7201. file with the document, a (game-specific) property must be defined for
  7202. that purpose.
  7203.  
  7204. I will first define the syntax of the game collections, then discuss
  7205. syntax and semantic of various properties.
  7206.  
  7207.  
  7208. GAME COLLECTIONS
  7209.  
  7210. A collection of game sis simply the concatenation of the game trees.
  7211. The structure of each tree is indicated by parentheses.  A tree is
  7212. written as "(" followed by a sequence of nodes (as long as the tree is
  7213. unbranched) and a tree for each son, and terminated by ")".  Each node
  7214. is preceded by a separator, and contains a list of zero or more
  7215. properties.
  7216.  
  7217. Thus the main branch of the game is stored first in the file, and
  7218. programs can easily read that part (until the first closing
  7219. parenthesis) and ignore the rest.
  7220.  
  7221. The conventions of EBNF are discussed in [Wirth 85].  A quick summary:
  7222.  
  7223. "..." : terminal symbols
  7224. [...] : option: occurs at most once
  7225. {...} : repetition: any number of times, including zero
  7226. (...) : grouping
  7227.   |   : exclusive-or
  7228.  
  7229. The overall definition of the file format is as follows:
  7230.  
  7231.         Collection      = {GameTree}.
  7232.         GameTree        = "(" Sequence {GameTree} ")".
  7233.         Sequence        = Node {Node}.
  7234.         Node            = ";" {Property}
  7235.  
  7236. Any text before the first opening parenthesis is reserved for future
  7237. extensions and is ignored when reading a file.  Spaces, tabs, line
  7238. breaks and so on can be inserted anywhere between properties and are
  7239. also ignored.
  7240.  
  7241.  
  7242. GAME-INDEPENDENT PROPERTIES
  7243.  
  7244. Each property is identified by one or two capital letters.  The
  7245. property value is enclosed in brackets; lists of points or integers are
  7246. written as a sequence of property values.  Within text, a closing
  7247. bracket is prefixed by a backslash, and a backslash is doubled.  Moves
  7248. and points are game-specific and are defined later.
  7249.  
  7250.         Property        = PropIdent PropValue {PropValue}.
  7251.         PropIdent       = UpperCase [UpperCase | Digit].
  7252.         PropValue       = "[" [Number | Text | Real | Triple
  7253.                                   | Color | Move | Point | ... ] "]"
  7254.         Number          = ["+" | "-"] Digit {Digit}.
  7255.         Text            = { any character; "\]" = "]", "\\" = "\"}.
  7256.         Real            = { Number ["." {Digit}].
  7257.         Triple          = ("1" | "2").
  7258.         Color           = ("B" | "W").
  7259.  
  7260. Move and Point are game-specific and are described later.  The
  7261. following properties are understood by all games.  The property type is
  7262. given in brackets.
  7263.  
  7264.         "B" : Black move                [move, game-specific]
  7265.         "W" : White move                [move, game-specific]
  7266.         "C" : Comment                   [Text]
  7267.         "N" : Node Name                 [Text]
  7268.  
  7269. The purpose of providing both a node name and a comment is to have a
  7270. short identifier like "doesn't work" or "Dia. 15" that can be displayed
  7271. directly with the properties of the node, even if the comment is turned
  7272. off or shown in a separate window.  There is no limit to the length of
  7273. texts; programs must be able to ignore the rest of texts that are too
  7274. long for them to handle.  Reasonable limits are 32 characters for node
  7275. names and at least 2000 characters for comments.
  7276.  
  7277.         "V" : Node value                [number]
  7278.  
  7279. Positive values are good for Black, negative values are good for
  7280. White.  The interpretation of particular values is game-specific.
  7281.  
  7282.         "CH": Check mark                [triple]
  7283.         "GB": good for black            [triple]
  7284.         "GW": good for white            [triple]
  7285.         "TE": good move (tesuji)        [triple]
  7286.         "BM": bad move                  [triple]
  7287.  
  7288. The normal value for such properties is one, properties that are
  7289. doubled for emphasis have the value two.
  7290.  
  7291.         "BL": time left for Black       [real]
  7292.         "WL": time left for White       [real]
  7293.  
  7294. All times are given in seconds, or fractions thereof {Hale: these can
  7295. be negative, indicating player is playing past time limit set}.
  7296.  
  7297.         "FG": figure                    [none]
  7298.  
  7299. The figure property is used to divide a game into different figures for
  7300. printing: a new figure starts at the node with a figure property.
  7301.  
  7302.         "AB": add black stones          [point list, game specific]
  7303.         "AW": add white stones          [point list, game specific]
  7304.         "AE": add empty stones          [point list, game specific]
  7305.         "PL": player to play first      [color]
  7306.  
  7307. The above properties are used to set up positions in games with only
  7308. black and white stones.  The following properties are all part of the
  7309. game info:
  7310.  
  7311.         "GN": game name                 [text]
  7312.         "GC": game comment              [text]
  7313.         "EV": event (tournament)        [text]
  7314.         "RO": round                     [text]
  7315.         "DT": date                      [text]
  7316.         "PC": place                     [text]
  7317.         "PB": black player name         [text]
  7318.         "PW": white player name         [text]
  7319.         "RE": result, outcome           [text]
  7320.         "US": user (who entered game)   [text]
  7321.         "TM": time limit per player     [text]
  7322.         "SO": source (book, journal...) [text]
  7323.  
  7324. The format in these game-info strings is free, but to be able to search
  7325. for specific games in game collections, it is recommended to adhere to
  7326. the following conventions:
  7327.  
  7328.         - Date is ISO-standard: "YYYY-MM-DD".
  7329.         - Result as "0" (zero) for a draw, "B+score" for a black win,
  7330.                 and "W+score" for a white win, e.g. "B+2.5", "W+64"
  7331.         - Time limit as a number, in minutes.
  7332.  
  7333. In addition, names, events, and places should be spelled the same im all games.
  7334.  
  7335. The following properties may only be present at the root node:
  7336.  
  7337.         "GM": game [number] (Go=1, Othello=2, chess=3, Nine Mens Morris=5)
  7338.         "SZ": board size        [number]
  7339.         "VW": partial view      [point list, game-specific]
  7340.         "BS": black species     [number] (human=0, modem=-1, computer>0)
  7341.         "WS": white species     [number]
  7342.  
  7343. The game number helps the program reject games it cannot handle (this
  7344. property was mandatory as long as an application could play different
  7345. games).  The view gives two corner points of a rectangular subsection;
  7346. an empty list denotes the whole board.  The species denotes the kind of
  7347. player (the source of the more input), with different version of
  7348. computer algorithms denoted by positive numbers (default algorithm =
  7349. 1).
  7350.  
  7351. Computer algorithms may add the following properties:
  7352.  
  7353.         "EL": evaluation of computer move       [number]
  7354.         "EX": expected next move                [move, game-specific]
  7355.  
  7356. Some games support markings on the board: selected points,
  7357. triangles/crosses, or letters (a sequence of letters is shown on the
  7358. points given in the list, starting with "A"):
  7359.  
  7360.         "SL": selected points                   [point list, game-specific]
  7361.         "M" : marked points                     [point list, game-specific]
  7362.         "L" : letters on points                 [point list, game-specific]
  7363.  
  7364.  
  7365. GO-SPECIFIC PROPERTIES
  7366.  
  7367. In my proposal for a standard [Kierul 87b], I intentionally broke with
  7368. the tradition of labeling moves (and points) with letters "A"-"T"
  7369. (excluding "i") and numbers 1-19.  Two lowercase letters in the range
  7370. "a"-"s" were used instead, for reasons of simplicity and compactness.
  7371. This was criticized mainly because it was not human-readable, but as
  7372. that is not an important feature of this file format, I continue to use
  7373. that notation.
  7374.  
  7375. (Hale: diagram omitted)
  7376.  
  7377. The first letter designated the column (left to right), the second the
  7378. row (top to bottom).  The upper left part of the board is used for
  7379. smaller boards, e.g. letters "a"-"m" for 13*13.  (Column before row
  7380. follows the principle "horizontal before vertical" used in x-y
  7381. coordinate systems.  The upper left corner as origin of the board
  7382. corresponds to the way we read, and most modern computers use it as
  7383. origin of the screen coordinates to simplify integration of text and
  7384. graphics.)  A pass move is written as "tt".
  7385.  
  7386. The board must be quadratic, no smaller than 2x2, and no larger than
  7387. 19x19.
  7388.  
  7389. Additional game info properties are defined for Go:
  7390.  
  7391.         "BR": Black's rank              [text]
  7392.         "WR": White's rank              [text]
  7393.         "HA": handicap                  [number]
  7394.         "KM": komi                      [real]
  7395.  
  7396. Sets of board points can be marked as territory, as secure stones, or
  7397. just as a region of the board (e.g. to designate eye space):
  7398.  
  7399.         "TB": Black's territory         [point list]
  7400.         "TW": White's territory         [point list]
  7401.         "SC": secure stones             [point list]
  7402.         "RG": region of the board       [point list]
  7403.  
  7404. SHAR_EOF
  7405. fi
  7406. if test -f 'README'
  7407. then
  7408.     echo shar: "will not over-write existing file 'README'"
  7409. else
  7410. cat << \SHAR_EOF > 'README'
  7411. -----------------------------------------------------------------------
  7412.  
  7413.            "mgt" Copyright 1991 Shodan
  7414.         All Rights Reserved.
  7415.         Program by Greg Hale
  7416.  
  7417. Permission to use, copy, modify, and distribute this software and its
  7418. documentation for any purpose and without fee is hereby granted,
  7419. provided that this entire comment and copyright notice appear in all
  7420. copies and that both that copyright notice and this permission notice
  7421. appear in supporting documentation.  No representations are made about
  7422. the suitability of this software for any purpose.  It is provided "as
  7423. is" without express or implied warranty.
  7424.  
  7425. -----------------------------------------------------------------------
  7426.  
  7427. To compile under UNIX, type 'make'
  7428.  
  7429. Under VMS, delete the mou.c file and then type '@build'
  7430.  
  7431. Under MS-DOS with Borland-C, type 'make -f makefile.bc'
  7432.  
  7433. -----------------------------------------------------------------------
  7434.               THERE IS NO X VERSION OF THIS PROGRAM
  7435. -----------------------------------------------------------------------
  7436.  
  7437. *** Be sure to get the From My Go Teacher tutorial materials available
  7438. *** on anonymous ftp at ftp.u.washington.edu.
  7439.  
  7440. -----------------------------------------------------------------------
  7441.  
  7442. Please send copies of extensions to:  hale@scam.berkeley.edu
  7443.  
  7444. Thanks to the following for suggestions, debugging, code writing, and testing:
  7445.  
  7446.            mgt - you know why he's here :)
  7447.  
  7448.     Kurt Wallnau - for playing and suggesting
  7449.     Jeff Boscole - for sleepless nights of debugging and testing
  7450.     Thos Sumner  - for extensive help with explaining some UNIX particulars
  7451.  
  7452.     Adrian Mariano - (adrian@u.washington.edu) 
  7453.              - massive code extensions, plus IBM version
  7454.     Tim Casey      (tcasey@triton.umn.edu)
  7455.     Mike Dobbins - lots of testing, suggestions and comment editor rewrite
  7456.     Eric Osman   - for getting things to work under VMS
  7457.     Steve Hollasch - debugging assistance
  7458.     Huayong Yang - comments, bug reports
  7459.         Jan van der Steen - bug reports and FIXES
  7460.  
  7461. --------------------------------------
  7462. Changes:
  7463.  
  7464. 3/13/93 V2.3
  7465.     o Rewrite of the comment editor; edits comments up to 120 lines
  7466.       long; additional and user settable edit control commands
  7467.         o No limit on size of displayable comments
  7468.         o Added a vi-like edit mode for the comment editor
  7469.     o Fixed a few parsing bugs
  7470.  
  7471. 4/30/92 V2.2
  7472.     o Increased speed of moving backwards through game record or
  7473.       jumping to an arbitrary node.
  7474.     o Tutor mode
  7475.     o Support for informational properties
  7476.     o Support for PLayer property, and passing (as a move)
  7477.     o Removed restriction on number of letters or marks
  7478.     o Detection of ko during game play
  7479.     o For the IBM version: Mouse support and improved display
  7480.  
  7481. 4/5/91 V2.1
  7482.     o Short format game record support
  7483.     o Filename wild card support
  7484.     o Additional comment editor features
  7485.     o Improved game scoring
  7486.  
  7487. 2/1/91 V2.0
  7488.     o mgt is more optimized.
  7489.     o IBM version support
  7490.     o revision of display
  7491.     o fixed lots of little bugs
  7492.     o more commands
  7493.     o basic editing of comments
  7494.     o save & load
  7495.     o play-by-mail facility added.
  7496.  
  7497. 2/6/90 V1.0
  7498.     o First release.  All is holding together fine, but no
  7499.       optimization has been done yet.  That is next on the list.  
  7500.       My apologies to the CPU's. :(
  7501. SHAR_EOF
  7502. fi
  7503. if test -f 'Makefile'
  7504. then
  7505.     echo shar: "will not over-write existing file 'Makefile'"
  7506. else
  7507. cat << \SHAR_EOF > 'Makefile'
  7508. #   There is NO X version of this program
  7509. #
  7510. #        "mgt" Copyright 1991 Shodan
  7511. #        All Rights Reserved.
  7512. #        Program by Greg Hale and Adrian Mariano
  7513. #
  7514. #Permission to use, copy, modify, and distribute this software and its
  7515. #documentation for any purpose and without fee is hereby granted,
  7516. #provided that this entire comment and copyright notice appear in all
  7517. #copies and that both that copyright notice and this permission notice
  7518. #appear in supporting documentation.  No representations are made about
  7519. #the suitability of this software for any purpose.  It is provided "as
  7520. #is" without express or implied warranty.
  7521. #
  7522. #Please send copies of extensions to:
  7523. #
  7524. # hale@scam.berkeley.edu
  7525. # 128.32.138.4    scam.berkeley.edu
  7526. #
  7527. #Donations for the 'From My Go Teacher' series may be sent to:
  7528. #    Shodan
  7529. #    P.O. Box 4456
  7530. #    Berkeley, CA 94704
  7531. #    (415) 574-5572
  7532. #
  7533. #
  7534. # Makefile for mgt
  7535. # by Greg Hale and Adrian Mariano
  7536. #
  7537. # *** C compile flags.
  7538. #
  7539. # -O: optimize
  7540. # -DDEBUG: turn on program debugging
  7541. #
  7542. # *** CONFIGURATION ***
  7543. #
  7544. # Choose one of
  7545. #   -DMGT_UNIX  Compile under UNIX
  7546. #   -DMGT_IBM   Compile on IBM PC under Turbo C (Use the other Makefile!)
  7547. #
  7548. #   -DMGT_LIB="/usr/hale/mgt.lib/":   defines a library directory for games
  7549. #
  7550.  
  7551. DEFS=-DMGT_UNIX
  7552.  
  7553. # If you read this Makefile, you may notice many references to an 
  7554. # X Windows program.  This program has been released and is available
  7555. # at the standard archive sites.
  7556.  
  7557.  
  7558. E    =
  7559. O     = .o
  7560.  
  7561. CC    = cc
  7562. CFLAGS    = -O $(DEFS)
  7563.  
  7564. LD     = cc
  7565. LDFLAGS    =
  7566. LIBS    = 
  7567. CUR_LIBS = -lcurses -ltermcap
  7568. X11_LIBS =
  7569.  
  7570. # DIRECTORIES - CONFIGURE DESTINATIONS
  7571. # BINDIR is where it is installed
  7572. BINDIR        =        /usr/games
  7573. MAN             =        mgt.doc
  7574. SHAR         =        mgt.sh
  7575.  
  7576. # files which make up the shell archive along with sources
  7577.  
  7578. FILES =     Smart-Go.def README Makefile format mgt.6 \
  7579.         Spec.io Makefile.bc Build.com mailgo mailgo.6 mgtdoc.asc \
  7580.         Sample.01 Sample.02 Rules Prop.lst README.IBM wrapmgt.6 \
  7581.         wrapmgt.c mgt2short mgt2short.6 mgtshort.bat mgtshort.cmd
  7582.  
  7583. SH_OBJS =     help$O build$O comment$O doit$O \
  7584.         edit$O mgt$O parse$O play$O tree$O
  7585.  
  7586. SH_SRCS =    help.c ascii.c build.c comment.c doit.c \
  7587.         edit.c mgt.c parse.c play.c tree.c
  7588.  
  7589. ASC_OBJS= ascii$O
  7590.  
  7591. OBJECTS =    help$O ascii$O build$O comment$O doit$O \
  7592.         edit$O mgt$O parse$O play$O tree$O
  7593.  
  7594.  
  7595. SRCS =        help.c asc_ibm.inc asc_unix.inc mou.c \
  7596.         ascii.c build.c comment.c doit.c edit.c \
  7597.         mgt.c parse.c play.c tree.c
  7598.  
  7599. HDRS =         mgt.h proto.h mou.h
  7600.  
  7601.  
  7602. all : begin curses wrapmgt man end
  7603.  
  7604. begin :
  7605.     @echo Begin...
  7606.  
  7607. end :
  7608.     @echo ...End
  7609.         
  7610. curses : mgt$E
  7611.     @echo Completed curses based version.
  7612.  
  7613. mgt$E : $(SH_OBJS) $(ASC_OBJS)
  7614.     $(LD) $(LDFLAGS) -o mgt$E $(SH_OBJS) $(ASC_OBJS) $(CUR_LIBS)
  7615.  
  7616. wrapmgt$E : wrapmgt.o
  7617.     $(LD) -o wrapmgt$E wrapmgt.o
  7618.  
  7619. ascii.o: ascii.c asc_unix.inc
  7620.  
  7621. $(MAN): mgt.6
  7622.     @echo "Creating mgt manual..."
  7623.     @nroff -man mgt.6 > $(MAN)
  7624.     @echo "done."
  7625.  
  7626. mailgo.doc: mailgo.6
  7627.     @echo "Creating mailgo manual..."
  7628.     @nroff -man mailgo.6 > mailgo.doc
  7629.     @echo "done."
  7630.  
  7631. wrapmgt.doc: wrapmgt.6
  7632.     @echo "Creating wrapmgt manual..."
  7633.     @nroff -man wrapmgt.6 > wrapmgt.doc
  7634.     @echo "done."
  7635.  
  7636. mgt2short.doc: mgt2short.6
  7637.     @echo "Creating mgt2short manual..."
  7638.     @nroff -man mgt2short.6 > mgt2short.doc
  7639.     @echo "done."
  7640.  
  7641. man: $(MAN) wrapmgt.doc mailgo.doc mgt2short.doc
  7642.  
  7643. clean:
  7644.     @echo "removing extra files..."
  7645.     @-rm -f *$O $(SHAR) xmgt$E mgt$E
  7646.     @echo "done."
  7647.  
  7648. proto:
  7649.     @echo "making proto.h file..."
  7650.     @-rm -f ./proto.h
  7651.     @egrep "FUNCTION" $(SH_SRCS) | sed "s/(.*)/();/" | sed "s/^.*://" | sed "s/FUNCTION/extern/"  | cat > ./proto.h
  7652.     @echo "done."
  7653.  
  7654. lint:
  7655.     @echo "making lint file..."
  7656.     @-rm -f ./lint.out
  7657.     @lint -u $(DEFS) $(SH_SRCS) > ./lint.out
  7658.     @echo "done."
  7659.  
  7660. new: proto clean all
  7661.  
  7662. mgtdoc.asc: $(MAN)
  7663.     @echo "Making ascii doc file..."
  7664.     @cat $(MAN) | col -b > mgtdoc.asc;
  7665.     @echo "done."
  7666.  
  7667.  
  7668. shar: mgtdoc.asc
  7669.     @shar $(SRCS) $(HDRS) $(FILES) > $(SHAR)
  7670.  
  7671. install : $(PROGRAM) $(ARCHIVE)
  7672.     @-install $(PROGRAM) $(BINDIR)/$(PROGRAM)
  7673.  
  7674. SHAR_EOF
  7675. fi
  7676. if test -f 'format'
  7677. then
  7678.     echo shar: "will not over-write existing file 'format'"
  7679. else
  7680. cat << \SHAR_EOF > 'format'
  7681. #!/bin/csh -f
  7682. foreach f ( $* )
  7683. indent -ndj -i3 -ip0 -npcs -cli3 -di3 -npsl -ncdb -l80 $f
  7684. end
  7685.  
  7686. SHAR_EOF
  7687. chmod +x 'format'
  7688. fi
  7689. if test -f 'mgt.6'
  7690. then
  7691.     echo shar: "will not over-write existing file 'mgt.6'"
  7692. else
  7693. cat << \SHAR_EOF > 'mgt.6'
  7694. .\" Define keep macros as poor (wo)man's substitute for broken .DS/.DE macros
  7695. .deKS        \" start keep
  7696. .sp        \" make a little head room
  7697. .ev 1        \" collect text in new environment
  7698. .in 0n        \" set zero indent relative to previous environment
  7699. .nf        \" assume no-fill mode
  7700. .di GO        \" start diversion called GO
  7701. ..
  7702. .deKE        \" end keep
  7703. .br        \" get last partial line
  7704. .di        \" end diversion
  7705. .ne \\n(dn    \" declare space needed for GO
  7706. .nf        \" bring GO back "as is"
  7707. .GO        \" output GO text
  7708. .ev        \" return to previous environment
  7709. .sp.5        \" a little room for the toes
  7710. ..
  7711. .TH MGT 6  "13 March 1993"
  7712. .SH NAME
  7713. mgt - game record display/editor for the oriental game of go
  7714. .SH SYNOPSIS
  7715. .B mgt
  7716. [\-m filename] [\-s] [-t] [files]
  7717. .SH DESCRIPTION
  7718. Go is an ancient oriental strategy game based on the capturing of territory.
  7719. The players alternate putting stones on the board, 
  7720. trying to surround as many empty intersections as possible.  
  7721. .LP
  7722. .B Mgt
  7723. allows the user to examine Go game tree files created through the 
  7724. Macintosh(tm) programs 
  7725. .B Smart-Go (tm)
  7726. or
  7727. .B Go Explorer (tm). 
  7728. .B Mgt
  7729. also has basic Go game tree editing capabilities and may be used to
  7730. create or edit game tree files.
  7731. The on\-line material provided by a
  7732. rather extensive and growing database allows many hours of instructional
  7733. enjoyment of various studies and tutorials concerning the game of Go. 
  7734. .LP
  7735. .B Mailgo 
  7736. is a utility which manages E-mail Go games using  
  7737. .B mgt 
  7738. as the Go board editor.  It is included in the 
  7739. .B mgt 
  7740. package.  
  7741. .LP
  7742. The 
  7743. .B mgt 
  7744. program was originally developed to be a companion for the series, 
  7745. "From My Go Teacher",
  7746. archived at scam.berkeley.edu and ftp.u.washington.edu for ftp.
  7747. Also available is the Internet GO Board communications program, 'go',
  7748. also by Greg Hale, which connects up two terminals in real\-time
  7749. anywhere in the world.
  7750. .SH COMMAND LINE OPTIONS
  7751. .TP 8
  7752. .B \-m filename
  7753. Invoke a set of options used by the 
  7754. .B mailgo
  7755. program for managing email games.  If a filename is specified for
  7756. loading (see below), the game record is loaded, and 
  7757. .B mgt
  7758. automatically moves to the end of the main variation of the game record.
  7759. The game can be modified without confirmation.
  7760. If the game record has been modified, 
  7761. it will be automatically saved, on exit, to the filename 
  7762. specified after the \-m and 
  7763. .B mgt
  7764. will return success (zero).  If the game record has not been modified, 
  7765. or has not been allowed to be saved, then 
  7766. .B mgt 
  7767. will return failure (nonzero). 
  7768. .LP
  7769. .TP 8
  7770. .B \-s
  7771. Change save format used to write save files.  The default save format is
  7772. the long format Smart\-Go file.  Using this option results in 
  7773. short format Smart\-Go files.
  7774. .LP
  7775. .TP 8
  7776. .B \-t
  7777. Invoke tutor mode where you select variations by playing on the board.
  7778. The key for making a move has special behavior in this mode.  See the 
  7779. section on the "space or 0" keyboard command for a description.
  7780. .LP
  7781. .TP 8
  7782. .B files
  7783. These are the files to be loaded.  The Unix and IBM version support 
  7784. wildcards.  If no file is specified, 
  7785. .B mgt 
  7786. loads a blank board.  If you attempt to modify a file that was loaded,
  7787. .B mgt 
  7788. will prompt for confirmation the first time.  
  7789. .LP
  7790. .SH OPERATION
  7791. .B Mgt
  7792. can be used to view and edit game records, 
  7793. or as an electronic game board for a two person 
  7794. game.  There are many keyboard commands which execute 
  7795. the various editing and display functions.
  7796. .LP
  7797. .TP 8
  7798. Step down the game tree to the next move.  Stop at the end of a variation
  7799. and do not visit other variations.
  7800. .LP
  7801. .TP 8
  7802. <
  7803. Move back up the game tree.  (Previous move)
  7804. .LP
  7805. .TP 8
  7806.  .
  7807. Go to the next node using a tree traversal which will visit all nodes.
  7808. Sometimes the order of traversal can be confusing.
  7809. .LP
  7810. .TP 8
  7811. ,
  7812. Go to the previous node -- the opposite of "." forward movement.
  7813. .LP
  7814. .TP 8
  7815. e
  7816. Go to end of the current variation.
  7817. .LP
  7818. .TP 8
  7819. b
  7820. Go to beginning of the game tree. 
  7821. .LP
  7822. .TP 8
  7823. }
  7824. Go forward like the "." command until a comment.
  7825. .LP
  7826. .TP 8
  7827. {
  7828. Go backwards like the "," command until a comment.
  7829. .LP
  7830. .TP 8
  7831. g
  7832. Go to a specified node.  Type in the desired node number.
  7833. .LP
  7834. .TP 8
  7835. Move forward until there is a variation branch in the game tree.
  7836. .LP
  7837. .TP 8
  7838. Move backwards until there is a variation branch in the game tree.
  7839. .LP
  7840. .TP 8
  7841. k and i 
  7842. Scroll the game tree variation window up and down.
  7843. A \- at the top of the variation window, and 
  7844. a + at the bottom indicate that more variations are available.
  7845. .LP
  7846. .TP 8
  7847. j and u 
  7848. Scroll comment window up and down.
  7849. A \- at the top of the comment, and 
  7850. a + at the bottom indicate that more comments are available.
  7851. .LP
  7852. .TP 8
  7853. Load new file.  Will prompt for confirmation if the current file has been
  7854. modified.
  7855. .LP
  7856. .TP 8
  7857. r
  7858. Load previous file.  (Reverse through the file list)
  7859. .LP
  7860. .TP 8
  7861. f
  7862. Load next file.  (Forward through the file list)
  7863. .LP
  7864. .TP 8
  7865. Write out Smart\-Go file.  Will prompt for a filename.  The special 
  7866. filename * will save with the current name (which appears in the upper 
  7867. right corner).  
  7868. .LP
  7869. .TP 8
  7870. space or 0 
  7871. Make a move.  The current player turn is indicated by the > < 
  7872. around the captured stones on the lower right.
  7873. Normally, this adds the move to the game tree and moves to a new node.
  7874. In tutor mode, it checks the various game continuations.  If one of them 
  7875. contains the move you made, it moves to that variation.  If not, it prints 
  7876. an error message.  The game tree cannot be modified in tutor mode.
  7877. .LP
  7878. .TP 8
  7879. Pass.  Enter a pass move.
  7880. .LP
  7881. .TP 8
  7882. o
  7883. Other player.  Changes whose turn it is, adding a token in the game tree to 
  7884. force the change whenever this node is visited.  If the player is forced by 
  7885. such a token, the current player turn is indicated by } { characters on the 
  7886. lower right.  
  7887. .LP
  7888. .TP 8
  7889. t
  7890. Toggle stone color.  Changes whose turn it is without adding any tokens in 
  7891. the game tree.  This will not work if the game tree has a PLayer token 
  7892. (generated by the o key) at the current node.
  7893. .LP 
  7894. .TP 8 
  7895. Set/unset black stones. 
  7896. .LP 
  7897. .TP 8 
  7898. Set/unset white stones. 
  7899. .LP 
  7900. .TP 8 
  7901. q or ESC.  
  7902. Quit.  q will 
  7903. prompt for confirmation.  ESC will not prompt for confirmation.  
  7904. .LP 
  7905. .TP 8 
  7906. Create a variation below the current node.  The variation will initially
  7907. contain a null node.  You must move to that variation to make a move in
  7908. it.  If the "v" command is invoked at a node which is at the end of a
  7909. variation, variation "A" is created with a null node.  Subsequent
  7910. invocations of the "v" command will create the "B", "C"... variations. 
  7911. .LP 
  7912. .TP 8 
  7913. Cut tree.  Moves the 
  7914. current node and everything below it to a temporary holding buffer.  (Moves 
  7915. your location back to the parent of the node you are one when you invoke it.) 
  7916. .LP 
  7917. .TP 8 
  7918. Paste tree.  Pastes the temporary holding buffer in after the 
  7919. current node.  Usually the  opposite of cutting the tree. 
  7920. .LP 
  7921. .TP 8 
  7922. Edit the current comment.  
  7923. The editor has two models of operation.  The default model 
  7924. has been vaguely designed after emacs.
  7925. That means that the editor 
  7926. commands are either 'control-key'  or 'escape-key'.  The controls 
  7927. are configurable through an environment variable.  The notation
  7928. "^key" is used to indicate control keys, and "]key" is used to indicate
  7929. keys which should be preceeded by the escape character.
  7930.  
  7931. On some terminals, instead of ESC-key, you can press Alt-key or
  7932. Meta-key.  (On the IBM version, you can use the Alt key.)
  7933. Under VMS, the ESC key does not work.  VMS users may need to redefine
  7934. the edit keys.  
  7935.  
  7936. The second edit model was vaguely designed after vi.  That means that the 
  7937. editor has a command mode for cursor movement, etc. and an insert mode
  7938. for inserting text.  The vi model editor starts in insert mode.
  7939. The ESC key changes mode from insert mode to command mode.  If
  7940. pressed in command mode, the ESC key exits the comment editor 
  7941. and saves the comment.  The letters below are typed in
  7942. command mode to obtain the specified function. 
  7943. To leave command mode and enter insert mode, you must
  7944. use the function which is listed as the insert mode command.  This
  7945. defaults to 'R'.   To select the vi like mode of operation,
  7946. put _ASCEDVI in your MGT environment variable. 
  7947.  
  7948. Defaults are:
  7949. .in +4m
  7950. .ta
  7951. .ta \w'delete to end of line (kill)\ \ 'u +8m +
  7952. .nf
  7953.        Command    emacs    vi
  7954. cursor up    (previous line)    ^P    k
  7955. cursor down  (next line)    ^N    j
  7956. page up      (prev page)    ]p    ^B
  7957. page down    (next page)    ]n    ^F
  7958. cursor left  (back)    ^B    h
  7959. cursor right (forward)    ^F    l
  7960. beginning of line    ^A    0
  7961. end of line    ^E    $
  7962. beginning of comment    ]<    H
  7963. end of comment    ]>    L
  7964. delete one character    ^D    x
  7965. delete to end of line (kill)    ^K    D
  7966. toggle insert mode    ^I    R
  7967. save comment    ]z    w
  7968. exit, don't save comment    ^W    q
  7969. .fi
  7970. .in -4m
  7971.  
  7972. Pressing c on a comment larger than the 120 lines allocated for comments will 
  7973. cause the extra to be lost.  Also, on terminals which generate IBM PC arrow
  7974. key codes, the arrow keys will correctly move the cursor within the
  7975. comment editor.  The arrow keys only work in the emacs based model.
  7976. .LP 
  7977. .TP 8 
  7978. Delete node.  Deletes the current node, replacing it with its 
  7979. child.  If the current node has no child, then clear the properties of the 
  7980. current node. 
  7981. .LP 
  7982. .TP 8 
  7983. Name the current node.  You will be prompted for the 
  7984. name. 
  7985. .LP 
  7986. .TP 8 
  7987. Score the game.  After selecting this, move the cursor 
  7988. around and remove the dead groups with 0 or space.  You can undo one (and 
  7989. only one) kill with the u key.  Pressing return will 
  7990. score the game and print the (Japanese) score in the comment area.
  7991. If you missed some dead groups, continue removing them.  Press q when you 
  7992. wish to exit scoring mode.  You will be prompted to either keep the score 
  7993. information as a comment for the current node or restore the old comment.
  7994. .LP
  7995. .TP 8
  7996. Ctrl\-I
  7997. Enter info mode.  In this mode, the various informational properties of the 
  7998. current file are displayed and may be edited.  To edit an item, press the 
  7999. letter associated with it, and enter the new text.  This letter must be 
  8000. entered in upper case.  To see a list of letters, press ?.  
  8001. The comment window scrolling keys can be used to 
  8002. scroll the info display.  The supported info properties are:
  8003. Size,
  8004. Handicap,
  8005. playerBlack,
  8006. bLackrank,
  8007. playerWhite,
  8008. whIterank,
  8009. Gamename,
  8010. Event,
  8011. rouNd,
  8012. Date,
  8013. Place,
  8014. Time,
  8015. Result,
  8016. gameComment,
  8017. sOurce,
  8018. User,
  8019. Komi.  The capital letters in this list indicate which letter selects that 
  8020. info property.  
  8021. .LP
  8022. .TP 8
  8023. Ctrl\-T
  8024. Toggle tutor mode.  (See the section on space or 0 for explanation.)
  8025. .LP
  8026. .TP 8
  8027. Ctrl\-W
  8028. Toggle the format used for writing Smart\-Go files between long and short.  
  8029. .LP
  8030. .TP 8
  8031. Ctrl\-L 
  8032. Refresh the screen.
  8033. .LP
  8034. .TP 8
  8035. Ctrl\-F 
  8036. Save the current screen to a file.
  8037. .LP
  8038. .TP 8
  8039. Display a help screen.
  8040. .LP
  8041. .TP 8
  8042. 12346789 
  8043. Move the cursor around.  Assumes standard numeric keypad orientation.
  8044. .LP
  8045. .SH ENVIRONMENT SETTINGS
  8046. All of the characters used for the commands and the display are configurable 
  8047. via environment variables.  For the ascii interface, use:
  8048. .LP
  8049. .sp
  8050. .if n \{.nf
  8051. setenv MGT '_ASCCOM:q><.,eb}{][gwzxv\\!lm#^cdn
  8052.                     spotrfLWTFI012346789kiju&
  8053.             _ASCCHAR:@O:+\-.+|\-++++
  8054.             _ASCINV _ASCED:PNpnBFAE<>DKIzO'
  8055.        (command should appear all on one line with a 
  8056.         single space separating _ASC... from the
  8057.         previous string.)
  8058. .fi
  8059. \}
  8060. .if t \{.nf
  8061. setenv MGT '_ASCCOM:q><.,eb}{][gwzxv\\!lm#^cdnspotrfLWTFI012346789kiju&
  8062.             _ASCCHAR:@O=+\-.+|\-++++
  8063.             _ASCINV _ASCED:PNpnBFAE<>DKIzW' 
  8064. .fi 
  8065. .in +.25i 
  8066. (command should appear all 
  8067. on one line with a single space separating _ASC... from the previous string.) 
  8068. .in -.25i 
  8069. \} 
  8070. .LP 
  8071. to get the default characters.  (This is csh syntax.  For 
  8072. other shells, the syntax will be different.)  
  8073. Place this line in your .cshrc so the alternate characters are 
  8074. always in effect.  
  8075. .LP
  8076. The _ASCCOM string allows you to change the keyboard 
  8077. commands.  Upper case letters stand for control characters. 
  8078. .LP
  8079. The _ASCCHAR 
  8080. string specifies the display characters.  For example, to use # for black 
  8081. stones, change the @ to # in the _ASCCHAR string.
  8082. You need only include one of the two declarations ("_ASCCOM:" or 
  8083. "_ASCCHAR:") if you only want to change the commands or characters
  8084. but not both.
  8085. .LP
  8086. To set the default display type to inverse video, use _ASCINV in the 
  8087. MGT environment variable.
  8088. .LP
  8089. To set the comment editor commands, use _ASCED in the 
  8090. MGT environment variable.
  8091.  
  8092. For the _ASCED environment variable setting in the emacs based editor model, 
  8093. control keys are specified with a 
  8094. capital letter, and ESC keys are anything which is not a capital letter.
  8095. This is the key string for the defaults: PNpnBFAE<>DKIzO.  
  8096. Note that ^V, ^O, ^C and ^Z are poor characters to use for
  8097. anything if you have berkeley unix 
  8098. because the berkeley tty drivers interpret these characters.
  8099. The ^V character is the quoting character which quotes the following
  8100. character.  You will need to press it twice for mgt to see it.
  8101. The other characters have to be quoted by first pressing ^V or mgt
  8102. will not recognize your keypress.  You cannot use ^H or ^? for
  8103. anything because the editor always interprets these as destructive
  8104. backspace.  
  8105.  
  8106. For the _ASCED environment variable setting in the vi based editor model, 
  8107. no special processing is done on the characters.
  8108. In order to specify control keys, you must place actual control 
  8109. characters into your environment string.
  8110. The default string has
  8111. two control commands (^B and ^F) defined.
  8112. This is the default: kj^B^Fhl0$HLxDRwq.  The vi based editor model may
  8113. be selected be including _ASCEDVI in the environment variable.
  8114. .LP
  8115. If you wish to include control characters in your string, you can do
  8116. this most easily by editing a file which sets the environment.  Vi can
  8117. insert most of the control characters directly. 
  8118. .LP
  8119. In all cases, when you set your own keys, you must set all of the keys, 
  8120. and they must appear in the correct order.  If you give assign the
  8121. same key to different functions, then an arbitrary one will be used
  8122. by 
  8123. .B mgt 
  8124. and the other functions will be unavailable.
  8125. If multiple contradictory specifications occur in the
  8126. .B mgt
  8127. environment variable, the last that appear will be used by the program. 
  8128. Any option not specified will assume the default values identified above.
  8129. .LP
  8130. With the IBM version, the same effects may be achieved under DOS 4.0 or
  8131. DOS 5.0 with
  8132. a SET command placed in the AUTOEXEC.BAT file.  Under previous DOS 
  8133. versions, quotes were interpreted literally and "|", ">" and "<" characters
  8134. have special meanings and thus cannot be put into environment variables
  8135. with the SET command.
  8136. .LP
  8137. Under VMS, the command is just MGT = "_ASCCHAR:..."
  8138. .LP
  8139. .SH COMMENT FORMATTING
  8140. Comments are expected to consist of long lines, each of which is one 
  8141. paragraph.  A single long line will be formatted to fit the display. 
  8142. Line breaks will be ignored if they are preceeded by a space, but will be 
  8143. respected otherwise. 
  8144. .SH DISPLAYS
  8145. All displays have in common the purpose of displaying a go tree.
  8146. .LP
  8147. .ft CW
  8148. .KS
  8149. ASCII display:
  8150.     A B C D E F G H  S T
  8151.    +---------------  ---+   -Suppose this is the second
  8152.  19|. . . @ . . . .  . .|19| line of the comment.  Since
  8153.  18|. O O @ @ @ O .  . .|18| there is some more of the
  8154.  17|. @ @ O O O O .  . .|17| comment above us unseen, 
  8155.  16|. @ O + . . . .  . .|16| the - appears to the left
  8156.  15|. @ O . O . . .  . .|15| of 'Suppose'.
  8157.  14|. . @ O . . . .  . .|14|
  8158.  13|. . @ . . . . .  . .|13|
  8159.  12|. . . . . . . .  . .|12|
  8160.  11|. . . . . . . .  . .|11| And here, when there is
  8161.  10|. . . + . . . .  . .|10| more of the comment
  8162.   9|. . . . . . . .  . .| 9| below, the '+'
  8163.   8|. . . . . . . .  . .| 8|+appears to our left.
  8164.   7|. . . . . . . .  . .| 7|
  8165.   6|. . . . . . . .  . .| 6|   Node #173: Name
  8166.   5|. . . . . . . .  . .| 5|-B: variation 1 hit 'B' to see
  8167.   4|. . . + . . . .  . .| 4| C: variation 2 hit 'C'
  8168.   3|. . . . . . . .  . .| 3| D: variation 3 etc...            
  8169.   2|. . . . . . . .  . .| 2| E: variation 4
  8170.   1|. . . . . . . .  . .| 1|+F: variation 5
  8171.    +---------------  ---+    ? for help    read   long
  8172.     A B C D E F G H  S T     
  8173.  Black #11 at 'D19'               @: 0      > O: 0 <
  8174. .KE
  8175. .LP
  8176. The bottom line indicates that Black has just made move #11.  On the bottom 
  8177. right, the angle brackets around the white stone indicate that it is 
  8178. White's turn.  Above that, the word "read" indicates that the Smart\-Go file 
  8179. hasn't been modified, and "long" indicates that the default save format is 
  8180. the long format.  "Read" will change to "edit" if you modify the file, and 
  8181. it will say "tutor" if you enter tutor mode.
  8182. .SH FILES
  8183. wrapmgt - prepare short format Smart-Go files for mailing
  8184. .LP
  8185. mailgo - email go game management
  8186. .LP
  8187. mgt2short - script to convert Smart-Go files to short format
  8188. .LP
  8189. RULES - an introduction to the game in Smart-Go format.
  8190. .LP
  8191. The 
  8192. .B From My Go Teacher
  8193. tutorial lessons, and many professional game records all available at 
  8194. ftp.u.washington.edu.
  8195. .LP
  8196. Internet go, a program to play go over internet, available on
  8197. ftp.u.washington.edu.
  8198. .LP 
  8199. Smart\-Go.def, the Smart\-Go format definition.
  8200. .sp
  8201. .SH BUGS
  8202. .LP
  8203. Comment editing is limited to 120 screen lines.
  8204. .LP
  8205. Most, but not all, of the Smart-Go properties are supported.
  8206. .LP
  8207. Send bug reports to "adrian@u.washington.edu"
  8208. or "hale@scam.Berkeley.EDU"
  8209. .fi
  8210. .sp
  8211. .SH AUTHORS
  8212. Greg Hale
  8213. .LP
  8214. Jeff Boscole
  8215. .LP
  8216. Adrian Mariano (adrian@u.washington.edu)
  8217. .LP
  8218. Mike Dobbins (mdobbins@asns.tredydev.unisys.com)
  8219. .sp
  8220. .SH SEE ALSO
  8221. rec.games.go \- a newsgroup on the game
  8222. .br
  8223. Graded go problems for beginners, vol 1-4,
  8224. Ishi Press 
  8225. .br
  8226. In the Beginning, 
  8227. Ishi Press.
  8228. .br
  8229. The Treasure Chest Enigma, 
  8230. Ishi Press.
  8231.  
  8232. SHAR_EOF
  8233. fi
  8234. if test -f 'Spec.io'
  8235. then
  8236.     echo shar: "will not over-write existing file 'Spec.io'"
  8237. else
  8238. cat << \SHAR_EOF > 'Spec.io'
  8239.                         INTERFACE SPECIFICATION FOR MGT
  8240.  
  8241. If you wish to add a new interface to mgt, these are the functions you need to 
  8242. come up with.
  8243.  
  8244. void open()
  8245.         Initialize interface.  Any *interface* specific initialization is done
  8246.         here.
  8247.  
  8248. void close()
  8249.         Leave the interface.
  8250.  
  8251. void refreshIO()
  8252.         update screen to look like memory image.  Somewhat curses specific.
  8253.         Probably will be a null function null(){} in most interfaces.
  8254.  
  8255. void plotPiece(pBoard b, int i, int j)
  8256.         Plots the piece contained in b at i,j on the real screen.
  8257.         Board is read by call boardGet(b, i, j) which returns
  8258.         one of P_NOTHING, P_BLACK, P_WHITE, P_DAME, P_BLACKTERR,
  8259.         or P_WHITETERR. 
  8260.  
  8261.  
  8262. void clearComment()
  8263.         Clears comment window
  8264.  
  8265. void initBoard()
  8266.         Draw a blank board of size 'boardsize'
  8267.  
  8268. void clearScreen()
  8269.         clears screen. 
  8270.  
  8271. int idle(nodep n) 
  8272.         Gets the next command.  Acts like an event driven loop.
  8273.         Waits for keystroke.  Returns a command casted to an int
  8274.         to indicate the command for doit.c to process.
  8275.  
  8276. void drawTree(nodep n)
  8277.         Show the variations that are available in the var list on 
  8278.         the right when starting at node n. (in Ascii version)
  8279.         Interface-local variables exists to handle scrolling.
  8280.         scrolling should be handled by the interface alone.
  8281.  
  8282. void highlightLast(int x, y, movenum, turn)
  8283.         Show last move number, current turn, whose move it is,
  8284.         and the prisoner count.
  8285.         turn==0 means Black just moved.
  8286.         If x and y are equal to PASSVAL then the move was a pass.
  8287.         Use these to get current player turn and prisoner count
  8288.         extern int prisoners[black=0,white=1] ;
  8289.         extern int curPlayer;
  8290.  
  8291. void readEnv(char **env)
  8292.         Check *env for environment string.  Increment it to point to 
  8293.         the first character not used.
  8294.  
  8295. void notifyMessage(char *s)
  8296.         Print single line message someplace.
  8297.  
  8298. void notifyClear()
  8299.         Clear notify message area
  8300.  
  8301. int queryStr(char *query, char *dst, int maxLen)
  8302.         Print query out.  Get at most maxLen chars into dst.
  8303.         Return length of the result.
  8304.  
  8305. void setCursor(int i, int j)
  8306.         Move cursor (pointer) to position i,j on go board
  8307.  
  8308. void plotMark(pBoard b,int i,int j) 
  8309.         Plot mark at position i,j on displayed board.
  8310.         DOES NOT modify *b.
  8311.         Mark is erased by call to plotPiece
  8312.  
  8313. void plotLetter(int i, int j, char c)
  8314.         Puts letter c on the screen at board position i,j
  8315.  
  8316. int getPoint()    
  8317.         Allow user to specify a board position (Cursor
  8318.         keys, mouse, etc) Used when scoring the game.
  8319.         Uses globals xcur and ycur to
  8320.         store the position.  The return value 
  8321.         can be C_QUIT to abort score.  C_SCORE to calculate
  8322.         the score.  C_REDRAW to redraw screen, or C_NOTHING
  8323.         to kill the group we're on right now.
  8324.  
  8325. void editComment(char *inp, char **out)
  8326.         Edit a comment.  inp contains the input comment to be
  8327.         edited.  THIS MUST BE free()'d.  out contains the return
  8328.         pointer.  It should be allocated to the appropriate size
  8329.         and the new edited comment should be placed in the
  8330.         allocated space.
  8331.  
  8332. int askYN(char *query, int defalt)
  8333.         Prompt user with query.  The query will NOT end in " (y/n)? " 
  8334.         If needed by the interface, this should be added here. 
  8335.         Returns 1 for yes, 0 for no.  defalt contains the default 
  8336.         response (1 for yes, 0 for no).
  8337.  
  8338. void notifyError(char *errormsg)
  8339.         Display error message.  Give user a chance to see it, and
  8340.         clear message.  
  8341.  
  8342. void displayInfo(char *s)
  8343.         Formats and displays string s as a list of game information.  Each
  8344.         informational item starts on its own line but may contain newlines.
  8345.  
  8346. Token getInfoToChange()
  8347.         Passes back an informational token to change, or t_EOF to escape
  8348.         from the info editor.  (Scrolling of the info region should be 
  8349.         handled internally here.)
  8350.  
  8351. void editInfo(char *input, char **output, property info_item)
  8352.     Edits the info item corresponding to info_item.  The current
  8353.         text is given in input which should be freed.  The replacement
  8354.         text should be put in *output which needs to be allocated by 
  8355.         this function.  (This works like the comment editor.)
  8356. SHAR_EOF
  8357. fi
  8358. if test -f 'Makefile.bc'
  8359. then
  8360.     echo shar: "will not over-write existing file 'Makefile.bc'"
  8361. else
  8362. cat << \SHAR_EOF > 'Makefile.bc'
  8363. # Makefile for Borland C++ 2.0
  8364. # Place your library directory below
  8365.  
  8366. LIB=c:\prog\c\lib
  8367. MDL=c
  8368.  
  8369. mgt.exe: ascii.obj build.obj comment.obj doit.obj edit.obj\
  8370.          parse.obj play.obj tree.obj mgt.obj help.obj mou.obj
  8371.     tlink /c /x $(LIB)\c0$(MDL) $(LIB)\wildargs ascii build comment doit \
  8372.           edit mgt parse play tree mou help ,mgt,mgt,\
  8373.           $(LIB)\c$(MDL) 
  8374.  
  8375. ascii.obj: asc_ibm.inc ascii.c
  8376.  
  8377. .c.obj: 
  8378.     bccx -m$(MDL) -w-pia -G -Z -O -c -DMGT_IBM $*.c
  8379.  
  8380.  
  8381.  
  8382. SHAR_EOF
  8383. fi
  8384. if test -f 'Build.com'
  8385. then
  8386.     echo shar: "will not over-write existing file 'Build.com'"
  8387. else
  8388. cat << \SHAR_EOF > 'Build.com'
  8389. $!
  8390. $!      This file hacked by Adrian Mariano to correctly compile the
  8391. $!      mgt program.  I don't want to compile all .c files in the
  8392. $!      current directory.  
  8393. $!
  8394. $!    This procedure checks all .C files in the current directory, and
  8395. $!    compiles any whose .OBJ file is older.  Then, all files are
  8396. $!    linked.
  8397. $!
  8398. $!    CAUTION:    .H files are not checked, so if you change one,
  8399. $!            you'll need to delete the .OBJ files of any .C
  8400. $!            files that depend on that .H file.  That will allow
  8401. $!            this BUILD.COM to recompile those .C files.
  8402. $!
  8403. $!    Usage:
  8404. $!
  8405. $!        @build [-Dname[=value]] [-g] [-ename]
  8406. $!
  8407. $!    If -D is given, a corresponding /DEFINE is fed to the C compiler.
  8408. $!
  8409. $!    If -g is given, the linker is told to link a debug version.
  8410. $!
  8411. $!    If -e is given, name is used for name of executable.  If not,
  8412. $!    sources are searched for "main(" or "main (" and that source name
  8413. $!    is used for name of executable.
  8414. $!
  8415. $!    Author:  Eric Osman   8-8-90
  8416. $!
  8417. $ on warning then goto hey_stop
  8418. $ on control_y then goto hey_stop
  8419. $ cpl = "call do_cpl"
  8420. $ q = "sys$scratch:''f$getjpi("","pid")'"
  8421.  
  8422.     !! Find macro definitions and link switches
  8423.  
  8424. $ n = 1
  8425. $ macros = ""
  8426. $ link_switches = ""
  8427. $ plup: if n .le. 8
  8428. $ then    next = p'n'
  8429. $    n = n + 1
  8430. $    qual = f$edit (f$extr(0,2,next),"upcase")
  8431. $    if qual .eqs. "-D"
  8432. $    then    definition = f$extr(2,f$len(next)-2,next)
  8433. $        macros = macros + "/define=""" + definition + """"
  8434. $    else if qual .eqs. "-E"
  8435. $    then    exe_name = f$parse(f$extr(2,f$len(next)-2,next),".exe")
  8436. $    else if qual .eqs. "-G"
  8437. $    then    link_switches = link_switches + "/debug"
  8438. $    endif
  8439. $    endif
  8440. $    endif
  8441. $    goto plup
  8442. $ endif
  8443. $
  8444. $    !! Get all dates
  8445. $    !! Begin hack 
  8446. $
  8447. $ rename wrapmgt.c wrapmgt.tmp
  8448. $ rename mou.c mou.tmp
  8449. $
  8450. $!! end hack
  8451. $
  8452. $ write sys$output "[Getting list of sources and objects]"
  8453. $ dir/date/col=1/nohead/notrail/out=temp.txt *.c.0,*.obj.0/exclude=foo.*
  8454. $
  8455. $!! begin hack
  8456. $
  8457. $ rename mou.tmp mou.c
  8458. $ rename wrapmgt.tmp wrapmgt.c
  8459. $
  8460. $!! end hack
  8461. $
  8462. $ write sys$output "[Examining dates]"
  8463. $ close/nolog b_chan
  8464. $ close/nolog link_chan
  8465. $ open b_chan temp.txt
  8466. $ open/write link_chan temp.opt
  8467. $ num = 0
  8468. $ slup:
  8469. $ read/end=nomore b_chan file_line
  8470. $ read/end=nomore b_chan date_line
  8471. $ type = f$parse (file_line,,,"type")
  8472. $ name = f$parse (file_line,,,"name")
  8473. $ if "''type'" .eqs. ".C"
  8474. $ then    src_'num' = "''name'"
  8475. $    num = num + 1
  8476. $    write link_chan name + ".obj"
  8477. $    date_tag = name + "_SRC_DATE"
  8478. $ else date_tag = name + "_OBJ_DATE"
  8479. $ endif
  8480. $ date = f$edit(date_line,"trim")
  8481. $ 'date_tag' = f$cvt(f$el(0," ",date) + ":" + f$el(1," ",date))
  8482. $ goto slup
  8483. $ nomore: close b_chan
  8484. $ close link_chan
  8485. $ n_srces = num
  8486. $ num = 0
  8487. $ dlup:
  8488. $ src_name = src_'num'
  8489. $ src_date = 'src_name'_src_date
  8490. $ if f$type ('src_name'_obj_date) .eqs. ""
  8491. $ then obj_date = ""
  8492. $ else obj_date = 'src_name'_obj_date
  8493. $ endif
  8494. $ define/user x11 decw$include:
  8495. $ cpl 'src_name' "''src_date'" "''obj_date'"
  8496. $ num = num + 1
  8497. $ if num .lt. n_srces then goto dlup
  8498. $ delete temp.txt.
  8499. $
  8500.     !! Make option file specifying libraries to link with
  8501.  
  8502. $ app sys$input temp.opt
  8503. sys$share:vaxcrtl.exe/share
  8504. $
  8505.     !! If name of executable hasn't been specified, find which source
  8506.     !! has main routine in it.
  8507.  
  8508. $ if f$type (exe_name) .eqs. ""
  8509. $ then
  8510. $    def/user sys$output nl:
  8511. $    def/user sys$error nl:
  8512. $    search/out='q'.out/window=0 *.c "main(","main ("
  8513. $    close/nolog a
  8514. $    open a 'q'.out
  8515. $    read/end=better_ask a line
  8516. $    exe_name = f$parse (".exe;0",line)
  8517. $    close a
  8518. $    delete 'q'.out.
  8519. $    goto now_we_have_exe_name
  8520. $    better_ask:
  8521. $    close a
  8522. $    read/prompt="Name for executable file: " sys$command exe_name
  8523. $ endif
  8524. $ now_we_have_exe_name:
  8525. $
  8526.     !! Link objects
  8527.  
  8528. $ set verify
  8529. $ link /exe='exe_name' temp/opt 'link_switches'
  8530. $ delete temp.opt. ! 'f$ver(0)'
  8531. $ exit
  8532. $ hey_stop:
  8533. $ set noverify
  8534. $ exit
  8535.  
  8536. $ do_cpl:
  8537. $ subroutine
  8538. $ on warning then exit
  8539. $ on control_y then goto cleanup
  8540. $ src = p1 + ".c"
  8541. $ obj = p1 + ".obj"
  8542. $ if f$search (obj) .eqs. "" then goto cpl_it
  8543. $ if p2 .lts. p3
  8544. $ then
  8545. $    write sys$output "[''obj' already o.k.]"
  8546. $    exit
  8547. $ endif
  8548. $ cpl_it:
  8549. $ def/user sys sys$library:
  8550. $ set verify
  8551. $ cc 'src' 'macros'/include=(decw$include:,sys$library:)/deb/mach/list -
  8552.     /obj=temp.obj
  8553. $ rename temp.obj 'obj' ! 'f$ver(0)'
  8554. $ exit
  8555. $ cleanup:
  8556. $ set nover
  8557. $ exit %x610
  8558. $ endsubroutine
  8559.  
  8560. SHAR_EOF
  8561. fi
  8562. if test -f 'mailgo'
  8563. then
  8564.     echo shar: "will not over-write existing file 'mailgo'"
  8565. else
  8566. cat << \SHAR_EOF > 'mailgo'
  8567. #!/bin/sh
  8568. #
  8569. #  mailgo 2.0     E-mail go game management program by Adrian Mariano
  8570. #     3/24/93     I place it on the public domain.  Please send improvements
  8571. #                 to me at adrian@u.washington.edu.
  8572. #  Syntax: mailgo [-r] filename
  8573. #          mailgo --  
  8574. #          mailgo -n [filename]
  8575. #          mailgo -c 
  8576. #          mailgo -e filename
  8577. #  Filename should contain a mailgo go game
  8578. #  
  8579. #  -- reads game file from stdin
  8580. #  -r resends the file to the opponent
  8581. #  -n start a new game, using data in filename to get address
  8582. #  -c removes temporary files left when abnormally terminated: MailGo*
  8583. #  -e edits the mailgo header and/or the game record
  8584. #
  8585. #  Invokes the game processor in the environment variable MAILGO, or attempts
  8586. #  to run mgt from the inherited path if MAILGO is not set.
  8587. #
  8588. #  System V Unix users should change the assignment to the MAILER variable
  8589. #  from 'mail' to 'mailx' or 'elm' or some other compatible mailer.
  8590. #
  8591.  
  8592. MAILER=mail
  8593.  
  8594. if [ $# -eq 0 ]
  8595. then
  8596.   echo ' '
  8597.   echo 'Syntax: mailgo [-r] filename'
  8598.   echo '        mailgo --'
  8599.   echo '        mailgo -n [filename]'
  8600.   echo '        mailgo -c '
  8601.   echo '        mailgo -e filename'
  8602.   echo ' '
  8603.   echo 'Mailgo is a program to manage email go games.'
  8604.   echo 'Filename should contain a mailgo go game'
  8605.   echo '  '
  8606.   echo '  -- reads game file from stdin'
  8607.   echo '  -r resends the file to the opponent'
  8608.   echo '  -n start a new game, using data in filename to get address'
  8609.   echo '  -c removes temporary files left when abnormally terminated: MailGo*'
  8610.   echo '  -e edits the mailgo header and/or the game record'
  8611.   echo ' '
  8612.   exit
  8613. fi
  8614. case $1 in
  8615.   -c) if [ $# -ne 1 ]
  8616.        then
  8617.          echo Wrong number of parameters
  8618.          exit
  8619.        else
  8620.          rm -f MailGo* MailFile* MailOut*
  8621.          exit
  8622.        fi;;
  8623.   -r) if [ $# != 2 ]
  8624.        then
  8625.          echo Wrong number of parameters
  8626.          exit
  8627.        fi
  8628.        if grep "\---GoGaMeEnD---" $2 >/dev/null 2>&1
  8629.        then
  8630.          name=`sed -n '2,5s/TO: //p' $2`
  8631.          hisfile=`sed -n '2,5s/TOFILE: //p' $2`
  8632.          echo Remailing response to $name, $hisfile
  8633.          $MAILER -s "Remailed Go Game: $hisfile" $name < $2
  8634.          exit
  8635.        else
  8636.          echo Invalid input file $2
  8637.          exit
  8638.        fi;;
  8639.   -e) if [ $# -ne 2 ]
  8640.        then
  8641.          echo Wrong number of parameters
  8642.          exit
  8643.        fi
  8644.        if [ ! -s $2 ]
  8645.        then
  8646.          echo File $2 not found.
  8647.          exit
  8648.        fi
  8649. sed -n '/---GoGaMeStArT---/,/---GoGaMeEnD---/{s/---GoGaMe.*---//
  8650. p
  8651. }' $2 > MailGo$$
  8652.        if [ ! -s MailGo$$ ]
  8653.        then
  8654.          echo Invalid input file $2
  8655.          exit
  8656.        fi
  8657.        opponent=`sed -n '2,5s/TO: //p' MailGo$$`
  8658.        echo To address: $opponent
  8659.        echo -n "new address, <ret> for no change: "
  8660.        read res
  8661.        if [ $res ]
  8662.        then
  8663.          opponent=$res
  8664.        fi
  8665.        hisfile=`sed -n '2,5s/TOFILE: //p' MailGo$$`
  8666.        echo To game file: $hisfile
  8667.        echo -n "new file name, <ret> for no change: "
  8668.        read res
  8669.        if [ $res ]
  8670.        then
  8671.          hisfile=$res
  8672.        fi
  8673.        me=`sed -n '2,5s/FROM: //p' MailGo$$`
  8674.        echo From address: $me
  8675.        echo -n "new address, <ret> for no change: "
  8676.        read res
  8677.        if [ $res ]
  8678.        then
  8679.          me=$res
  8680.        fi
  8681.        myfile=`sed -n '2,5s/FROMFILE: //p' MailGo$$`
  8682.        echo From game file: $myfile
  8683.        echo -n "new file name, <ret> for no change: "
  8684.        read res
  8685.        if [ $res ]
  8686.        then
  8687.          myfile=$res
  8688.        fi
  8689.        if sed -n 6,7p MailGo$$ | grep FORMAT > /dev/null 2>&1
  8690.        then
  8691.          format=`sed -n '6,7s/FORMAT: //p' MailGo$$`
  8692.          if [ ! \( $format = 'L' -o $format = 'E' \) ] 
  8693.          then
  8694.            format='S'
  8695.          fi
  8696.        else
  8697.          format='L'
  8698.        fi
  8699.        echo Old game record format: $format
  8700.        echo -n "New game record format (Long/Short/Extrashort): "
  8701.        read res
  8702.        case $res in
  8703.          L | l) format='L' ;;
  8704.          E | e) format='E' ;;
  8705.          S | s) format='S' ;;
  8706.          *)  ;;
  8707.        esac
  8708.        case $format in
  8709.          L) sflag='';;
  8710.          *) sflag=-s;;
  8711.        esac
  8712.        if ${MAILGO-mgt} $sflag -m MailOut$$ MailGo$$
  8713.        then
  8714.          if [ -s MailOut$$ ]
  8715.          then
  8716.        echo >> MailOut$$
  8717.            cat <<END_END > MailFile$$
  8718. ---GoGaMeStArT---
  8719. TO: $opponent
  8720. TOFILE: $hisfile
  8721. FROM: $me
  8722. FROMFILE: $myfile
  8723. FORMAT: $format
  8724. END_END
  8725.            if [ $format = 'S' ]
  8726.            then
  8727.              sed 's/\(;[BC]\[\)/\
  8728. \1/g' MailOut$$ >>MailFile$$
  8729.            else
  8730.              cat MailOut$$ >> MailFile$$
  8731.            fi
  8732.            echo >> MailFile$$
  8733.            echo "---GoGaMeEnD---" >> MailFile$$
  8734.          else
  8735.            echo -n "---GoGaMeStArT---" > MailFile$$
  8736.            sed "s/TO:.*/TO: $opponent/
  8737.             s/TOFILE:.*/TOFILE: $hisfile/
  8738.                 s/FROM:.*/FROM: $me/
  8739.                 s/FROMFILE:.*/FROMFILE: $myfile/
  8740.                 s/FORMAT:.*/FORMAT: $format/" MailGo$$ >> MailFile$$
  8741.            echo "---GoGaMeEnD---" >> MailFile$$
  8742.            echo -n "empty mgt file"
  8743.            exit
  8744.          fi
  8745.        else
  8746.            echo -n "---GoGaMeStArT---" > MailFile$$
  8747.            sed "s/TO:.*/TO: $opponent/
  8748.             s/TOFILE:.*/TOFILE: $hisfile/
  8749.                 s/FROM:.*/FROM: $me/
  8750.                 s/FROMFILE:.*/FROMFILE: $myfile/
  8751.                 s/FORMAT:.*/FORMAT: $format/" MailGo$$ >> MailFile$$
  8752.            echo "---GoGaMeEnD---" >> MailFile$$
  8753.          echo "No move made, or mgt error"
  8754.        fi
  8755.        rm -f MailGo$$ MailOut$$
  8756.        echo -n "Do you wish to keep updates (y/N)? "
  8757.        read res
  8758.        case $res in
  8759.          Y | y) cat MailFile$$ > $2
  8760.             echo  Updates saved to: $2
  8761.             rm -f MailFile$$
  8762.             exit;;
  8763.          *) echo   NOT keeping updates.
  8764.             rm -f MailFile$$
  8765.             exit;;
  8766.        esac
  8767.   ;;
  8768.   -n) if [ $# -gt 2 ]
  8769.        then
  8770.          echo Wrong number of parameters
  8771.          exit
  8772.        fi
  8773.        if [ $# -eq 2 ]
  8774.        then
  8775.          if [ ! -s $2 ]
  8776.          then
  8777.            echo File $2 not found.
  8778.            exit
  8779.          fi
  8780.          opponent=`sed -n '2,5s/TO: //p' $2`
  8781.          echo Opponent address: $opponent
  8782.          hisfile=`sed -n '2,5s/TOFILE: //p' $2`
  8783.          echo His game file: $hisfile
  8784.          me=`sed -n '2,5s/FROM: //p' $2`
  8785.          echo Your address: $me
  8786.          myfile=`sed -n '2,5s/FROMFILE: //p' $2`
  8787.          echo Your game file: $myfile
  8788.        else
  8789.          echo -n "Opponent address: "
  8790.          read opponent
  8791.          echo -n "Opponent game filename: "
  8792.          read hisfile
  8793.          echo -n "Your address: "
  8794.          read me
  8795.          echo -n "Your game filename: "
  8796.          read myfile
  8797.        fi
  8798.        echo -n "Black player name: "
  8799.        read bpname
  8800.        echo -n "             rank: "
  8801.        read bprank
  8802.        echo -n "White player name: "
  8803.        read wpname
  8804.        echo -n "             rank: "
  8805.        read wprank
  8806.        echo -n "Board size (return for 19): "
  8807.        read bsize
  8808.        if [ "$bsize" -lt 7 -o "$bsize" -gt 19 ]
  8809.        then
  8810.          bsize=19
  8811.        fi
  8812.        echo -n "Handicap: "
  8813.        read handicap
  8814.        echo -n "Komi: "
  8815.        read komi
  8816.        echo -n "Game record format (Long/Short/Extrashort): "
  8817.        read format
  8818.        case $format in
  8819.          L | l) format='L' ;;
  8820.          E | e) format='E' ;;
  8821.          *)     format='S' ;;
  8822.        esac
  8823.        started=`date|awk '{print $3, $2, $6}'`
  8824.        if grep "W\[\]" $myfile >/dev/null 2>&1  
  8825.        then
  8826.          echo -n "File $myfile contains game possibly in progress.  Clobber (y/N)? "
  8827.          read res
  8828.          case $res in
  8829.            Y | y) ;;
  8830.            *)  echo -n "Your game filename: "
  8831.                read myfile;;
  8832.          esac
  8833.        fi
  8834.        cat <<END_END >$myfile
  8835. ---GoGaMeStArT---
  8836. FROM: $me
  8837. FROMFILE: $myfile
  8838. TO: $opponent
  8839. TOFILE: $hisfile
  8840. NEWGAME
  8841. FORMAT: $format
  8842. END_END
  8843.        cat <<END_END > MailGo$$
  8844. (
  8845. ;
  8846. GaMe[1]
  8847. VieW[]
  8848. SiZe[$bsize]
  8849. Comment[Black: $bpname, $bprank
  8850. White: $wpname, $wprank
  8851. `if [ "$handicap" ] ; then echo "Handicap: $handicap" ; fi`
  8852. `if [ "$komi" ] ; then echo "Komi: $komi" ; fi`
  8853. Started: $started]
  8854. PB[$bpname]
  8855. BR[$bprank]
  8856. PW[$wpname]
  8857. WR[$wprank]
  8858. `if [ "$komi" ] ; then echo KoMi[$komi] ; fi`
  8859. DT[$started]
  8860. `      case $bsize.$handicap in
  8861.          19.2) echo "PL[W]HA[2]AB[dp][pd]" ;;
  8862.          19.3) echo "PL[W]HA[3]AB[dp][pd][pp]" ;;
  8863.          19.4) echo "PL[W]HA[4]AB[dd][dp][pd][pp]" ;;
  8864.          19.5) echo "PL[W]HA[5]AB[dd][dp][jj][pd][pp]" ;;
  8865.          19.6) echo "PL[W]HA[6]AB[dd][dj][dp][pd][pj][pp]" ;;
  8866.          19.7) echo "PL[W]HA[7]AB[dd][dj][dp][jj][pd][pj][pp]" ;;
  8867.          19.8) echo "PL[W]HA[8]AB[dd][dj][dp][jd][jp][pd][pj][pp]" ;;
  8868.          19.9) echo "PL[W]HA[9]AB[dd][dj][dp][jd][jj][jp][pd][pj][pp]" ;;
  8869.          13.2) echo "PL[W]HA[2]AB[dj][jd]" ;;
  8870.          13.3) echo "PL[W]HA[3]AB[dj][jd][jj]" ;;
  8871.          13.4) echo "PL[W]HA[4]AB[dd][dj][jd][jj]" ;;
  8872.          13.5) echo "PL[W]HA[5]AB[dd][dj][gg][jd][jj]" ;;
  8873.          9.2) echo "PL[W]HA[2]AB[cg][gc]" ;;
  8874.          9.3) echo "PL[W]HA[3]AB[cg][gc][gg]" ;;
  8875.          9.4) echo "PL[W]HA[4]AB[cc][cg][gc][gg]" ;;
  8876.        esac`
  8877. )
  8878. END_END
  8879.        case $format in
  8880.          L) sflag='';;
  8881.          *) sflag=-s;;
  8882.        esac
  8883.        if ${MAILGO-mgt} $sflag -m MailOut$$ MailGo$$
  8884.        then
  8885.          if [ -s MailOut$$ ]
  8886.          then
  8887.            cat MailOut$$ >>$myfile
  8888.          else
  8889.            cat MailGo$$ >>$myfile
  8890.          fi
  8891.        else
  8892.          echo -n "No move made, or mgt error. Send anyway (y/N)? "
  8893.          read res
  8894.          case $res in
  8895.            Y | y) cat MailGo$$ >>$myfile;;
  8896.            *) echo   NOT mailing new game.
  8897.               rm -f MailGo$$ MailOut$$
  8898.               exit;;
  8899.          esac
  8900.        fi
  8901.        rm -f MailOut$$ MailGo$$
  8902.        echo Mailing new game to $opponent, $hisfile
  8903.        echo >> $myfile
  8904.        echo "---GoGaMeEnD---" >> $myfile
  8905.        $MAILER -s "New Go Game: $hisfile" $opponent <$myfile
  8906.        exit
  8907.        ;;
  8908. esac
  8909. if [ $# -ne 1 ]
  8910. then
  8911.   echo Wrong number of parameters
  8912.   exit
  8913. fi
  8914. if [ $1 = -- ]
  8915. then
  8916.   cat >/tmp/mailgo$$
  8917.   set /tmp/mailgo$$
  8918.   exec </dev/tty
  8919. elif [ ! -s $1 ]
  8920. then
  8921.   echo File $1 not found
  8922.   exit
  8923. fi
  8924. sed -n '/---GoGaMeStArT---/,/---GoGaMeEnD---/{s/---GoGaMe.*---//
  8925. p
  8926. }' $1 > MailGo$$
  8927. if [ ! -s MailGo$$ ]
  8928. then
  8929.   echo Invalid input file $1
  8930.   exit
  8931. fi
  8932. eval `sed -n '/---GoGaMeStArT---/,/(/{
  8933.   s/^TOFILE:  */fileout=/p
  8934.   s/^FROMFILE:  */hisfile=/p
  8935.   s/^FORMAT:  */format=/p
  8936.   s/^TO:  */me=/p
  8937.   s/^FROM:  */name=/p
  8938.   s/^NEWGAME/newgame=1/p
  8939.   }' $1`
  8940. if [ -z "$format" ] 
  8941. then
  8942.   format=L
  8943. elif [ "$format" != L -a "$format" != E ]
  8944. then
  8945.   format=S
  8946. fi
  8947. case $format in
  8948.   L) sflag='';;
  8949.   *) sflag='-s';;
  8950. esac
  8951. if ${MAILGO-mgt} $sflag -m MailOut$$ MailGo$$
  8952. then
  8953.   echo >> MailOut$$
  8954.   if [ "$newgame" = 1 -a -s $fileout ]
  8955.   then
  8956.     echo -n "File $fileout exists.  Clobber (y/N)? "
  8957.     read res
  8958.     case $res in
  8959.       Y | y) rm -f $fileout ;;
  8960.       *) echo -n "Output filename: "
  8961.          read fileout ;;
  8962.     esac
  8963.   fi
  8964.   cat <<EOF > MailFile$$
  8965. ---GoGaMeStArT---
  8966. TO: $name
  8967. TOFILE: $hisfile
  8968. FROM: $me
  8969. FROMFILE: $fileout
  8970. FORMAT: $format
  8971. EOF
  8972.   case $format in
  8973.     S) sed 's/\(;[BC]\[\)/\
  8974. \1/g' MailOut$$ >>MailFile$$;;
  8975.     *) cat MailOut$$ >>MailFile$$;;
  8976.   esac 
  8977.   echo "---GoGaMeEnD---" >> MailFile$$
  8978.   echo Mailing response to $name, $hisfile
  8979.   $MAILER -s "Go Game: $hisfile" $name < MailFile$$ 
  8980.   rm -f MailGo$$ MailOut$$ $1
  8981.   if grep "\---GoGaMeEnD---" $fileout > /dev/null 2>&1 || [ ! -s $fileout ]
  8982.   then
  8983.     mv MailFile$$ $fileout
  8984.   else
  8985.     echo Save file $fileout doesn\'t look like a mailgo file.  
  8986.     echo "Overwrite it anyway (y/N)?"
  8987.     read res
  8988.     case $res in
  8989.       y | Y) mv -f MailFile$$ $fileout;;
  8990.       *)     echo Game record left in MailFile$$;;
  8991.     esac
  8992.   fi
  8993. else
  8994.   echo No move made, or mgt error.  NOT mailing response.
  8995.   rm -f MailGo$$ MailOut$$
  8996. fi
  8997.  
  8998. SHAR_EOF
  8999. chmod +x 'mailgo'
  9000. fi
  9001. if test -f 'mailgo.6'
  9002. then
  9003.     echo shar: "will not over-write existing file 'mailgo.6'"
  9004. else
  9005. cat << \SHAR_EOF > 'mailgo.6'
  9006. .TH MAILGO 6  "23 November 1992"
  9007. .SH NAME
  9008. mailgo - shell script for using mgt to automate email go games
  9009. .SH SYNOPSIS
  9010. .B mailgo [\-r] [\-n] [\-c] [\-e] [filename]
  9011. .SH DESCRIPTION
  9012. .B mailgo
  9013. helps manage email games by processing Smart-Go game records received by
  9014. mail, invoking mgt, and automatically sending your next move back.
  9015. .LP
  9016. Invoking 
  9017. .B mailgo 
  9018. with no flags instructs the program to search the specified file for a
  9019. go game, ignoring mail headers or other such garbage.  
  9020. .B mailgo 
  9021. will invoke the game processor specified in the environment variable
  9022. MAILGO or of this variable is undefined, will attempt to run 
  9023. .B mgt
  9024. from the inherited path.  If you give the filename -- then 
  9025. .B mailgo
  9026. will read its input from stdin, allowing you to redirect messages
  9027. into 
  9028. .B mailgo
  9029. directly from your mailer.  Your mail program may not support
  9030. redirecting messages into external programs.  Check it's man
  9031. page to find out.
  9032. This option to use stdin as the input is only valid if you give
  9033. .B mailgo
  9034. no other arguments.  (Technical note:  mgt is instructed to read its 
  9035. input from /dev/tty if you use this feature.)
  9036. .LP
  9037. If your opponent loses your move, you can resend the game with the \-r
  9038. switch.
  9039. .LP
  9040. To start a new game, use the \-n switch.  Without a file, you will be 
  9041. prompted for your address, your opponent's address, and the filename for
  9042. both your and your opponent's local game record.  The game processor will
  9043. then be invoked for you to make the first move.  If a filename is specified,
  9044. the address and filename data is taken from that file.
  9045. .LP
  9046. The \-c switch causes the program to delete any extraneous files it
  9047. might have created during a previous run which was abnormally
  9048. terminated.  These files have the form: MailGo*
  9049. .LP
  9050. To edit the mailgo headers (including mail addresses, file names and game
  9051. record format) or the game record, use the \-e switch with the file name
  9052. of the mailgo file you wish to edit.  The file may be a saved mailgo
  9053. mail message or a processed mailgo game file.  The \-e option will not
  9054. mail changes because of the possibility of confusing addresses.  To mail
  9055. edited files, use 'mailgo <file>' for edited mail messages and 'mailgo -r
  9056. <file>' for edited files which have been previously processed by
  9057. .B mailgo.
  9058. .LP
  9059. .B mailgo 
  9060. also supports go board sizes of 9x9, 13x13 and 19x19.  Handicaps
  9061. maybe set to values of 2-4 for 9x9 games, 2-5 for 13x13 games and 2-9
  9062. for 19x19 games.  Any other board size or handicap must be set behind
  9063. .B mailgo
  9064. 's back.
  9065. .SH FILE FORMAT
  9066. .LP
  9067. .sp
  9068. .if
  9069.  Leading garbage ignored
  9070.  
  9071.  ---GoGaMeStArT---
  9072.  TO: opponent@hissite
  9073.  TOFILE: his_game_record
  9074.  FROM: me@mysite
  9075.  FROMFILE: my_game_record
  9076.  FORMAT: format_code
  9077.  (
  9078.  Smart\-Go game data
  9079.  )
  9080.  ---GoGaMeEnD---
  9081.  
  9082.  Trailing garbage ignored
  9083. .fi
  9084. .LP
  9085. The game data file contains a leading tag to indicate the start of 
  9086. the data.  It contains both addresses, as should be used to mail the
  9087. game files, and it contains the files to store the games in.  In the
  9088. example above, you are playing opponent@hissite, and the game is being
  9089. stored in my_game_record.
  9090. .LP
  9091. The file format used can be either long, short, or extrashort indicated by L, 
  9092. S, and E respectively.  The long format uses the full size Smart-Go file 
  9093. saved with no options from mgt.  The extrashort format uses mgt with the \-s 
  9094. option to save short format files.  This format may cause problems for some
  9095. mailers, however, because the lines will grow longer than 512 bytes.
  9096. In any game record format, if very long comments are created, there is a
  9097. danger of causing mailer problems. 
  9098. The short format is similar to the extrashort format but has extra newlines
  9099. inserted.  The short format is the default when selecting format from
  9100. the prompt, but the long format is the default if a file contains no FORMAT
  9101. line.
  9102. When 
  9103. .B mailgo
  9104. is used normally, the file specified on the command line is removed at
  9105. successful completion, and the new game is saved to the file specified in
  9106. the received game record.  If the destination file does not look like
  9107. a mailgo file, 
  9108. .B mailgo
  9109. will query for confirmation.
  9110. .LP
  9111. When a new game is started, the first mailgo message contains the line
  9112. NEWGAME inserted before the FORMAT line.  This is used to check for
  9113. the overwriting of old game records.  
  9114. .SH FILES
  9115. mgt
  9116. .LP
  9117. Smart-Go.def, the Smart\-Go format definition.
  9118. .sp
  9119. .SH BUGS
  9120. .LP
  9121. .B mailgo 
  9122. tries to handle the case where you start a new game but
  9123. do not make the first move.
  9124. If after the first move you have a reason to convince mgt that you have 
  9125. changed the game record without really changing anything, you should
  9126. enter and exit the comment editor. 
  9127. .fi
  9128. .sp
  9129. .SH AUTHOR
  9130. Adrian Mariano (adrian@u.washington.edu)
  9131.  
  9132. SHAR_EOF
  9133. fi
  9134. if test -f 'mgtdoc.asc'
  9135. then
  9136.     echo shar: "will not over-write existing file 'mgtdoc.asc'"
  9137. else
  9138. cat << \SHAR_EOF > 'mgtdoc.asc'
  9139.  
  9140.  
  9141.  
  9142.    26 February 1993                                                    MGT(6)
  9143.  
  9144.  
  9145.  
  9146.    NAME
  9147.      mgt - game record display/editor for the oriental game of go
  9148.  
  9149.    SYNOPSIS
  9150.      mgt [-m filename] [-s] [-t] [files]
  9151.  
  9152.    DESCRIPTION
  9153.      Go is an ancient oriental strategy game based on the capturing of terri-
  9154.      tory.  The players alternate putting stones on the board, trying to sur-
  9155.      round as many empty intersections as possible.
  9156.  
  9157.      Mgt allows the user to examine Go game tree files created through the
  9158.      Macintosh(tm) programs Smart-Go (tm) or Go Explorer (tm). Mgt also has
  9159.      basic Go game tree editing capabilities and may be used to create or
  9160.      edit game tree files.  The on-line material provided by a rather exten-
  9161.      sive and growing database allows many hours of instructional enjoyment
  9162.      of various studies and tutorials concerning the game of Go.
  9163.  
  9164.      Mailgo is a utility which manages E-mail Go games using mgt as the Go
  9165.      board editor.  It is included in the mgt package.
  9166.  
  9167.      The mgt program was originally developed to be a companion for the
  9168.      series, "From My Go Teacher", archived at scam.berkeley.edu and
  9169.      ftp.u.washington.edu for ftp.  Also available is the Internet GO Board
  9170.      communications program, 'go', also by Greg Hale, which connects up two
  9171.      terminals in real-time anywhere in the world.
  9172.  
  9173.    COMMAND LINE OPTIONS
  9174.  
  9175.      -m filename
  9176.              Invoke a set of options used by the mailgo program for managing
  9177.              email games.  If a filename is specified for loading (see
  9178.              below), the game record is loaded, and mgt automatically moves
  9179.              to the end of the main variation of the game record.  The game
  9180.              can be modified without confirmation.  If the game record has
  9181.              been modified, it will be automatically saved, on exit, to the
  9182.              filename specified after the -m and mgt will return success
  9183.              (zero).  If the game record has not been modified, or has not
  9184.              been allowed to be saved, then mgt will return failure
  9185.              (nonzero).
  9186.  
  9187.      -s      Change save format used to write save files.  The default save
  9188.              format is the long format Smart-Go file.  Using this option
  9189.              results in short format Smart-Go files.
  9190.  
  9191.      -t      Invoke tutor mode where you select variations by playing on the
  9192.              board.  The key for making a move has special behavior in this
  9193.              mode.  See the section on the "space or 0" keyboard command for
  9194.              a description.
  9195.  
  9196.      files   These are the files to be loaded.  The Unix and IBM version sup-
  9197.              port wildcards.  If no file is specified, mgt loads a blank
  9198.              board.  If you attempt to modify a file that was loaded, mgt
  9199.  
  9200.  
  9201.                                                                             1
  9202.  
  9203.  
  9204.  
  9205.  
  9206.  
  9207.  
  9208.    MGT(6)                                                    26 February 1993
  9209.  
  9210.  
  9211.              will prompt for confirmation the first time.
  9212.  
  9213.    OPERATION
  9214.      Mgt can be used to view and edit game records, or as an electronic game
  9215.      board for a two person game.  There are many keyboard commands which
  9216.      execute the various editing and display functions.
  9217.  
  9218.      >       Step down the game tree to the next move.  Stop at the end of a
  9219.              variation and do not visit other variations.
  9220.  
  9221.      <       Move back up the game tree.  (Previous move)
  9222.  
  9223.       .      Go to the next node using a tree traversal which will visit all
  9224.              nodes.  Sometimes the order of traversal can be confusing.
  9225.  
  9226.      ,       Go to the previous node -- the opposite of "." forward movement.
  9227.  
  9228.      e       Go to end of the current variation.
  9229.  
  9230.      b       Go to beginning of the game tree.
  9231.  
  9232.      }       Go forward like the "." command until a comment.
  9233.  
  9234.      {       Go backwards like the "," command until a comment.
  9235.  
  9236.      g       Go to a specified node.  Type in the desired node number.
  9237.  
  9238.      ]       Move forward until there is a variation branch in the game tree.
  9239.  
  9240.      [       Move backwards until there is a variation branch in the game
  9241.              tree.
  9242.  
  9243.      k and i Scroll the game tree variation window up and down.  A - at the
  9244.              top of the variation window, and a + at the bottom indicate that
  9245.              more variations are available.
  9246.  
  9247.      j and u Scroll comment window up and down.  A - at the top of the com-
  9248.              ment, and a + at the bottom indicate that more comments are
  9249.              available.
  9250.  
  9251.      #       Load new file.  Will prompt for confirmation if the current file
  9252.              has been modified.
  9253.  
  9254.      r       Load previous file.  (Reverse through the file list)
  9255.  
  9256.      f       Load next file.  (Forward through the file list)
  9257.  
  9258.      w       Write out Smart-Go file.  Will prompt for a filename.  The spe-
  9259.              cial filename * will save with the current name (which appears
  9260.              in the upper right corner).
  9261.  
  9262.      space or 0
  9263.              Make a move.  The current player turn is indicated by the > <
  9264.              around the captured stones on the lower right.  Normally, this
  9265.  
  9266.  
  9267.    2
  9268.  
  9269.  
  9270.  
  9271.  
  9272.  
  9273.  
  9274.    26 February 1993                                                    MGT(6)
  9275.  
  9276.  
  9277.              adds the move to the game tree and moves to a new node.  In
  9278.              tutor mode, it checks the various game continuations.  If one of
  9279.              them contains the move you made, it moves to that variation.  If
  9280.              not, it prints an error message.  The game tree cannot be modi-
  9281.              fied in tutor mode.
  9282.  
  9283.      p       Pass.  Enter a pass move.
  9284.  
  9285.      o       Other player.  Changes whose turn it is, adding a token in the
  9286.              game tree to force the change whenever this node is visited.  If
  9287.              the player is forced by such a token, the current player turn is
  9288.              indicated by } { characters on the lower right.
  9289.  
  9290.      t       Toggle stone color.  Changes whose turn it is without adding any
  9291.              tokens in the game tree.  This will not work if the game tree
  9292.              has a PLayer token (generated by the o key) at the current node.
  9293.  
  9294.      z       Set/unset black stones.
  9295.  
  9296.      x       Set/unset white stones.
  9297.  
  9298.      q or ESC.
  9299.              Quit.  q will prompt for confirmation.  ESC will not prompt for
  9300.              confirmation.
  9301.  
  9302.      v       Create a variation below the current node.  The variation will
  9303.              initially contain a null node.  You must move to that variation
  9304.              to make a move in it.  If the "v" command is invoked at a node
  9305.              which is at the end of a variation, variation "A" is created
  9306.              with a null node.  Subsequent invocations of the "v" command
  9307.              will create the "B", "C"... variations.
  9308.  
  9309.      !       Cut tree.  Moves the current node and everything below it to a
  9310.              temporary holding buffer.  (Moves your location back to the
  9311.              parent of the node you are one when you invoke it.)
  9312.  
  9313.      ^       Paste tree.  Pastes the temporary holding buffer in after the
  9314.              current node.  Usually the  opposite of cutting the tree.
  9315.  
  9316.      c       Edit the current comment. The editor has two models of opera-
  9317.              tion.  The default model has been vaguely designed after emacs.
  9318.              That means that the editor commands are either 'control-key'  or
  9319.              'escape-key'.  The controls are configurable through an environ-
  9320.              ment variable.  The notation "^key" is used to indicate control
  9321.              keys, and "]key" is used to indicate keys which should be pre-
  9322.              ceeded by the escape character.
  9323.  
  9324.              On some terminals, instead of ESC-key, you can press Alt-key or
  9325.              Meta-key.  (On the IBM version, you can use the Alt key.) Under
  9326.              VMS, the ESC key does not work.  VMS users may need to redefine
  9327.              the edit keys.
  9328.  
  9329.              The second edit model was vaguely designed after vi.  That means
  9330.              that the editor has a command mode for cursor movement, etc. and
  9331.  
  9332.  
  9333.                                                                             3
  9334.  
  9335.  
  9336.  
  9337.  
  9338.  
  9339.  
  9340.    MGT(6)                                                    26 February 1993
  9341.  
  9342.  
  9343.              an insert mode for inserting text.  The vi model editor starts
  9344.              in insert mode.  The ESC key changes mode from insert mode to
  9345.              command mode.  If pressed in command mode, the ESC key exits the
  9346.              comment editor and saves the comment.  The letters below are
  9347.              typed in command mode to obtain the specified function. To leave
  9348.              command mode and enter insert mode, you must use the function
  9349.              which is listed as the insert mode command.  This defaults to
  9350.              'R'.   To select the vi like mode of operation, put _ASCEDVI in
  9351.              your MGT environment variable.
  9352.  
  9353.              Defaults are:
  9354.                         Command                emacs   vi
  9355.                  cursor up    (previous line)  ^P      k
  9356.                  cursor down  (next line)      ^N      j
  9357.                  page up      (prev page)      ]p      ^B
  9358.                  page down    (next page)      ]n      ^F
  9359.                  cursor left  (back)           ^B      h
  9360.                  cursor right (forward)        ^F      l
  9361.                  begining of line              ^A      0
  9362.                  end of line                   ^E      $
  9363.                  beginning of comment          ]<      H
  9364.                  end of comment                ]>      L
  9365.                  delete one character          ^D      x
  9366.                  delete to end of line (kill)  ^K      D
  9367.                  toggle insert mode            ^I      R
  9368.                  save comment                  ]z      w
  9369.                  exit, don't save comment      ^W      q
  9370.  
  9371.              Pressing c on a comment larger than the 120 lines allocated for
  9372.              comments will cause the extra to be lost.  Also, on terminals
  9373.              which generate IBM PC arrow key codes, the arrow keys will
  9374.              correctly move the cursor within the comment editor.  The arrow
  9375.              keys only work in the emacs based model.
  9376.  
  9377.      d       Delete node.  Deletes the current node, replacing it with its
  9378.              child.  If the current node has no child, then clear the proper-
  9379.              ties of the current node.
  9380.  
  9381.      n       Name the current node.  You will be prompted for the name.
  9382.  
  9383.      s       Score the game.  After selecting this, move the cursor around
  9384.              and remove the dead groups with 0 or space.  You can undo one
  9385.              (and only one) kill with the u key.  Pressing return will score
  9386.              the game and print the (Japanese) score in the comment area.  If
  9387.              you missed some dead groups, continue removing them.  Press q
  9388.              when you wish to exit scoring mode.  You will be prompted to
  9389.              either keep the score information as a comment for the current
  9390.              node or restore the old comment.
  9391.  
  9392.      Ctrl-I  Enter info mode.  In this mode, the various informational pro-
  9393.              perties of the current file are displayed and may be edited.  To
  9394.              edit an item, press the letter associated with it, and enter the
  9395.              new text.  This letter must be entered in upper case.  To see a
  9396.              list of letters, press ?. The comment window scrolling keys can
  9397.  
  9398.  
  9399.    4
  9400.  
  9401.  
  9402.  
  9403.  
  9404.  
  9405.  
  9406.    26 February 1993                                                    MGT(6)
  9407.  
  9408.  
  9409.              be used to scroll the info display.  The supported info proper-
  9410.              ties are: Size, Handicap, playerBlack, bLackrank, playerWhite,
  9411.              whIterank, Gamename, Event, rouNd, Date, Place, Time, Result,
  9412.              gameComment, sOurce, User, Komi.  The capital letters in this
  9413.              list indicate which letter selects that info property.
  9414.  
  9415.      Ctrl-T  Toggle tutor mode.  (See the section on space or 0 for explana-
  9416.              tion.)
  9417.  
  9418.      Ctrl-W  Toggle the format used for writing Smart-Go files between long
  9419.              and short.
  9420.  
  9421.      Ctrl-L  Refresh the screen.
  9422.  
  9423.      Ctrl-F  Save the current screen to a file.
  9424.  
  9425.      ?       Display a help screen.
  9426.  
  9427.      12346789
  9428.              Move the cursor around.  Assumes standard numeric keypad orien-
  9429.              tation.
  9430.  
  9431.    ENVIRONMENT SETTINGS
  9432.      All of the characters used for the commands and the display are confi-
  9433.      gurable via environment variables.  For the ascii interface, use:
  9434.  
  9435.      setenv MGT '_ASCCOM:q><.,eb}{][gwzxv\!lm#^cdn
  9436.                          spotrfLWTFI012346789kiju&
  9437.                  _ASCCHAR:@O:+-.+|-++++
  9438.                  _ASCINV _ASCED:PNpnBFAE<>DKIzO'
  9439.             (command should appear all on one line with a
  9440.              single space separating _ASC... from the
  9441.              previous string.)
  9442.  
  9443.  
  9444.      to get the default characters.  (This is csh syntax.  For other shells,
  9445.      the syntax will be different.) Place this line in your .cshrc so the
  9446.      alternate characters are always in effect.
  9447.  
  9448.      The _ASCCOM string allows you to change the keyboard commands.  Upper
  9449.      case letters stand for control characters.
  9450.  
  9451.      The _ASCCHAR string specifies the display characters.  For example, to
  9452.      use # for black stones, change the @ to # in the _ASCCHAR string.  You
  9453.      need only include one of the two declarations ("_ASCCOM:" or
  9454.      "_ASCCHAR:") if you only want to change the commands or characters but
  9455.      not both.
  9456.  
  9457.      To set the default display type to inverse video, use _ASCINV in the MGT
  9458.      environment variable.
  9459.  
  9460.      To set the comment editor commands, use _ASCED in the MGT environment
  9461.      variable.
  9462.  
  9463.  
  9464.  
  9465.                                                                             5
  9466.  
  9467.  
  9468.  
  9469.  
  9470.  
  9471.  
  9472.    MGT(6)                                                    26 February 1993
  9473.  
  9474.  
  9475.      For the _ASCED environment variable setting in the emacs based editor
  9476.      model, control keys are specified with a capital letter, and ESC keys
  9477.      are anything which is not a capital letter.  This is the key string for
  9478.      the defaults: PNpnBFAE<>DKIzO. Note that ^V, ^O, ^C and ^Z are poor
  9479.      characters to use for anything if you have berkeley unix because the
  9480.      berkeley tty drivers interpret these characters.  The ^V character is
  9481.      the quoting character which quotes the following character.  You will
  9482.      need to press it twice for mgt to see it.  The other characters have to
  9483.      be quoted by first pressing ^V or mgt will not recognize your keypress.
  9484.  
  9485.      For the _ASCED environment variable setting in the vi based editor
  9486.      model, no special processing is done on the characters.  In order to
  9487.      specify control keys, you must place actual control characters into your
  9488.      environment string.  The default string has two control commands (^B and
  9489.      ^F) defined.  This is the default: kj^B^Fhl0$HLxDRwq.  The vi based edi-
  9490.      tor model may be selected be including _ASCEDVI in the environment vari-
  9491.      able.
  9492.  
  9493.      If you wish to include control characters in your string, you can do
  9494.      this most easily by editing a file which sets the environment.  Vi can
  9495.      insert most of the control characters directly.
  9496.  
  9497.      In all cases, when you set your own keys, you must set all of the keys,
  9498.      and they must appear in the correct order.  If you give assign the same
  9499.      key to different functions, then an arbitrary one will be used by mgt
  9500.      and the other functions will be unavailable.  If multiple contradictory
  9501.      specifications occur in the mgt environment variable, the last that
  9502.      appear will be used by the program. Any option not specified will assume
  9503.      the default values identified above.
  9504.  
  9505.      With the IBM version, the same effects may be achieved under DOS 4.0 or
  9506.      DOS 5.0 with a SET command placed in the AUTOEXEC.BAT file.  Under pre-
  9507.      vious DOS versions, quotes were interpreted literally and "|", ">" and
  9508.      "<" characters have special meanings and thus cannot be put into
  9509.      environment variables with the SET command.
  9510.  
  9511.      Under VMS, the command is just MGT = "_ASCCHAR:..."
  9512.  
  9513.    COMMENT FORMATTING
  9514.      Comments are expected to consist of long lines, each of which is one
  9515.      paragraph.  A single long line will be formatted to fit the display.
  9516.      Line breaks will be ignored if they are preceeded by a space, but will
  9517.      be respected otherwise.
  9518.  
  9519.    DISPLAYS
  9520.      All displays have in common the purpose of displaying a go tree.
  9521.  
  9522.  
  9523.  
  9524.  
  9525.  
  9526.  
  9527.  
  9528.  
  9529.  
  9530.  
  9531.    6
  9532.  
  9533.  
  9534.  
  9535.  
  9536.  
  9537.  
  9538.    26 February 1993                                                    MGT(6)
  9539.  
  9540.  
  9541.      ASCII display:
  9542.  
  9543.          A B C D E F G H  S T
  9544.         +---------------  ---+   -Suppose this is the second
  9545.       19|. . . @ . . . .  . .|19| line of the comment.  Since
  9546.       18|. O O @ @ @ O .  . .|18| there is some more of the
  9547.       17|. @ @ O O O O .  . .|17| comment above us unseen,
  9548.       16|. @ O + . . . .  . .|16| the - appears to the left
  9549.       15|. @ O . O . . .  . .|15| of 'Suppose'.
  9550.       14|. . @ O . . . .  . .|14|
  9551.       13|. . @ . . . . .  . .|13|
  9552.       12|. . . . . . . .  . .|12|
  9553.       11|. . . . . . . .  . .|11| And here, when there is
  9554.       10|. . . + . . . .  . .|10| more of the comment
  9555.        9|. . . . . . . .  . .| 9| below, the '+'
  9556.        8|. . . . . . . .  . .| 8|+appears to our left.
  9557.        7|. . . . . . . .  . .| 7|
  9558.        6|. . . . . . . .  . .| 6|   Node #173: Name
  9559.        5|. . . . . . . .  . .| 5|-B: variation 1 hit 'B' to see
  9560.        4|. . . + . . . .  . .| 4| C: variation 2 hit 'C'
  9561.        3|. . . . . . . .  . .| 3| D: variation 3 etc...
  9562.        2|. . . . . . . .  . .| 2| E: variation 4
  9563.        1|. . . . . . . .  . .| 1|+F: variation 5
  9564.         +---------------  ---+    ? for help    read   long
  9565.          A B C D E F G H  S T
  9566.       Black #11 at 'D19'               @: 0      > O: 0 <
  9567.  
  9568.      The bottom line indicates that Black has just made move #11.  On the
  9569.      bottom right, the angle brackets around the white stone indicate that it
  9570.      is White's turn.  Above that, the word "read" indicates that the
  9571.      Smart-Go file hasn't been modified, and "long" indicates that the
  9572.      default save format is the long format.  "Read" will change to "edit" if
  9573.      you modify the file, and it will say "tutor" if you enter tutor mode.
  9574.  
  9575.    FILES
  9576.      wrapmgt - prepare short format Smart-Go files for mailing
  9577.  
  9578.      mailgo - email go game management
  9579.  
  9580.      mgt2short - script to convert Smart-Go files to short format
  9581.  
  9582.      RULES - an introduction to the game in Smart-Go format.
  9583.  
  9584.      The From My Go Teacher tutorial lessons, and many professional game
  9585.      records all available at ftp.u.washington.edu.
  9586.  
  9587.      Internet go, a program to play go over internet, available on
  9588.      ftp.u.washington.edu.
  9589.  
  9590.      Smart-Go.def, the Smart-Go format definition.
  9591.  
  9592.  
  9593.  
  9594.  
  9595.  
  9596.  
  9597.                                                                             7
  9598.  
  9599.  
  9600.  
  9601.  
  9602.  
  9603.  
  9604.    MGT(6)                                                    26 February 1993
  9605.  
  9606.  
  9607.    BUGS
  9608.  
  9609.      Comment editing is limited to 120 screen lines.
  9610.  
  9611.      Most, but not all, of the Smart-Go properties are supported.
  9612.  
  9613.      Send bug reports to "adrian@u.washington.edu" or
  9614.      "hale@scam.Berkeley.EDU"
  9615.  
  9616.  
  9617.    AUTHORS
  9618.      Greg Hale
  9619.  
  9620.      Jeff Boscole
  9621.  
  9622.      Adrian Mariano (adrian@u.washington.edu)
  9623.  
  9624.      Mike Dobbins (mdobbins@asns.tredydev.unisys.com)
  9625.  
  9626.  
  9627.    SEE ALSO
  9628.      rec.games.go - a newsgroup on the game
  9629.      Graded go problems for beginners, vol 1-4, Ishi Press
  9630.      In the Beginning, Ishi Press.
  9631.      The Treasure Chest Enigma, Ishi Press.
  9632.  
  9633.  
  9634.  
  9635.  
  9636.  
  9637.  
  9638.  
  9639.  
  9640.  
  9641.  
  9642.  
  9643.  
  9644.  
  9645.  
  9646.  
  9647.  
  9648.  
  9649.  
  9650.  
  9651.  
  9652.  
  9653.  
  9654.  
  9655.  
  9656.  
  9657.  
  9658.  
  9659.  
  9660.  
  9661.  
  9662.  
  9663.    8
  9664.  
  9665.  
  9666.  
  9667. SHAR_EOF
  9668. fi
  9669. if test -f 'Sample.01'
  9670. then
  9671.     echo shar: "will not over-write existing file 'Sample.01'"
  9672. else
  9673. cat << \SHAR_EOF > 'Sample.01'
  9674. (
  9675. ;
  9676. GaMe[1]
  9677. VieW[]
  9678. SiZe[19]
  9679. Comment[A game between two amateurs both ranked betwen 10 kyu and 15 kyu
  9680.     
  9681.  
  9682. Result:  with no komi, black wins by 4]
  9683. ;
  9684. Black[pd]
  9685. ;
  9686. White[qp]
  9687. ;
  9688. Black[dp]
  9689. ;
  9690. White[dc]
  9691. ;
  9692. Black[op]
  9693. ;
  9694. White[po]
  9695. ;
  9696. Black[lp]
  9697. ;
  9698. White[pl]
  9699. ;
  9700. Black[de]
  9701. ;
  9702. White[cd]
  9703. ;
  9704. Black[ed]
  9705. ;
  9706. White[ce]
  9707. ;
  9708. Black[cf]
  9709. ;
  9710. White[ec]
  9711. ;
  9712. Black[ci]
  9713. ;
  9714. White[fd]
  9715. ;
  9716. Black[fe]
  9717. ;
  9718. White[gd]
  9719. ;
  9720. Black[ph]
  9721. ;
  9722. White[qi]
  9723. ;
  9724. Black[nc]
  9725. ;
  9726. White[cn]
  9727. ;
  9728. Black[dn]
  9729. ;
  9730. White[cp]
  9731. ;
  9732. Black[co]
  9733. ;
  9734. White[bo]
  9735. ;
  9736. Black[do]
  9737. ;
  9738. White[dq]
  9739. ;
  9740. Black[bp]
  9741. ;
  9742. White[bq]
  9743. ;
  9744. Black[ap]
  9745. ;
  9746. White[cq]
  9747. ;
  9748. Black[bn]
  9749. ;
  9750. White[ep]
  9751. ;
  9752. Black[eo]
  9753. ;
  9754. White[fq]
  9755. ;
  9756. Black[fp]
  9757. ;
  9758. White[eq]
  9759. ;
  9760. Black[gp]
  9761. ;
  9762. White[gq]
  9763. ;
  9764. Black[hq]
  9765. ;
  9766. White[hp]
  9767. ;
  9768. Black[ho]
  9769. ;
  9770. White[iq]
  9771. ;
  9772. Black[ip]
  9773. ;
  9774. White[hr]
  9775. ;
  9776. Black[jq]
  9777. ;
  9778. White[ir]
  9779. ;
  9780. Black[jr]
  9781. ;
  9782. White[go]
  9783. ;
  9784. Black[gn]
  9785. ;
  9786. White[io]
  9787. ;
  9788. Black[hn]
  9789. ;
  9790. White[hp]
  9791. ;
  9792. Black[fo]
  9793. ;
  9794. White[jp]
  9795. ;
  9796. Black[kq]
  9797. ;
  9798. White[jn]
  9799. ;
  9800. Black[kd]
  9801. ;
  9802. White[jc]
  9803. ;
  9804. Black[kc]
  9805. ;
  9806. White[jd]
  9807. ;
  9808. Black[lg]
  9809. ;
  9810. White[ke]
  9811. ;
  9812. Black[le]
  9813. ;
  9814. White[kf]
  9815. ;
  9816. Black[lf]
  9817. ;
  9818. White[if]
  9819. ;
  9820. Black[gg]
  9821. ;
  9822. White[ge]
  9823. ;
  9824. Black[ff]
  9825. ;
  9826. White[jh]
  9827. ;
  9828. Black[hj]
  9829. ;
  9830. White[jk]
  9831. ;
  9832. Black[mk]
  9833. ;
  9834. White[pq]
  9835. ;
  9836. Black[oq]
  9837. ;
  9838. White[qh]
  9839. ;
  9840. Black[qg]
  9841. ;
  9842. White[pi]
  9843. ;
  9844. Black[oh]
  9845. ;
  9846. White[oi]
  9847. ;
  9848. Black[ni]
  9849. ;
  9850. White[nh]
  9851. ;
  9852. Black[ng]
  9853. ;
  9854. White[nj]
  9855. ;
  9856. Black[mh]
  9857. ;
  9858. White[mj]
  9859. ;
  9860. Black[lm]
  9861. ;
  9862. White[kp]
  9863. ;
  9864. Black[lo]
  9865. ;
  9866. White[lq]
  9867. ;
  9868. Black[lr]
  9869. ;
  9870. White[js]
  9871. ;
  9872. Black[mq]
  9873. ;
  9874. White[oo]
  9875. ;
  9876. Black[no]
  9877. ;
  9878. White[nn]
  9879. ;
  9880. Black[nm]
  9881. ;
  9882. White[mn]
  9883. ;
  9884. Black[lj]
  9885. ;
  9886. White[mi]
  9887. ;
  9888. Black[li]
  9889. ;
  9890. White[mo]
  9891. ;
  9892. Black[np]
  9893. ;
  9894. White[nk]
  9895. ;
  9896. Black[ml]
  9897. ;
  9898. White[nl]
  9899. ;
  9900. Black[mm]
  9901. ;
  9902. White[om]
  9903. ;
  9904. Black[il]
  9905. ;
  9906. White[hh]
  9907. ;
  9908. Black[gh]
  9909. ;
  9910. White[gf]
  9911. ;
  9912. Black[kg]
  9913. ;
  9914. White[jg]
  9915. ;
  9916. Black[ii]
  9917. ;
  9918. White[bf]
  9919. ;
  9920. Black[df]
  9921. ;
  9922. White[cg]
  9923. ;
  9924. Black[dg]
  9925. ;
  9926. White[bh]
  9927. ;
  9928. Black[ch]
  9929. ;
  9930. White[bg]
  9931. ;
  9932. Black[bi]
  9933. ;
  9934. White[gi]
  9935. ;
  9936. Black[hi]
  9937. ;
  9938. White[dd]
  9939. ;
  9940. Black[ee]
  9941. ;
  9942. White[hg]
  9943. ;
  9944. Black[fg]
  9945. ;
  9946. White[ji]
  9947. ;
  9948. Black[gj]
  9949. ;
  9950. White[nh]
  9951. ;
  9952. Black[pg]
  9953. ;
  9954. White[aq]
  9955. ;
  9956. Black[ao]
  9957. ;
  9958. White[jl]
  9959. ;
  9960. Black[kl]
  9961. ;
  9962. White[im]
  9963. ;
  9964. Black[hl]
  9965. ;
  9966. White[ln]
  9967. ;
  9968. Black[pr]
  9969. ;
  9970. White[qr]
  9971. ;
  9972. Black[ps]
  9973. ;
  9974. White[qs]
  9975. ;
  9976. Black[or]
  9977. ;
  9978. White[km]
  9979. ;
  9980. Black[ko]
  9981. ;
  9982. White[lk]
  9983. ;
  9984. Black[kk]
  9985. ;
  9986. White[ll]
  9987. ;
  9988. Black[kj]
  9989. ;
  9990. White[jj]
  9991. ;
  9992. Black[jo]
  9993. ;
  9994. White[rg]
  9995. ;
  9996. Black[rf]
  9997. ;
  9998. White[rh]
  9999. ;
  10000. Black[ip]
  10001. ;
  10002. White[hq]
  10003. ;
  10004. Black[in]
  10005. ;
  10006. White[kn]
  10007. ;
  10008. Black[hm]
  10009. ;
  10010. White[kb]
  10011. ;
  10012. Black[lb]
  10013. ;
  10014. White[ka]
  10015. ;
  10016. Black[la]
  10017. ;
  10018. White[jb]
  10019. ;
  10020. Black[lc]
  10021. ;
  10022. White[ih]
  10023. ;
  10024. Black[ah]
  10025. ;
  10026. White[ag]
  10027. ;
  10028. Black[ai]
  10029. ;
  10030. White[be]
  10031. ;
  10032. Black[sg]
  10033. ;
  10034. White[sh]
  10035. ;
  10036. Black[ks]
  10037. ;
  10038. White[is]
  10039. ;
  10040. Black[ik]
  10041. ;
  10042. White[kh]
  10043. ;
  10044. Black[lh]
  10045. ;
  10046. White[jm]
  10047. ;
  10048. Black[sf]
  10049. ;
  10050. White[ni]
  10051. ;
  10052. Black[pp]
  10053. ;
  10054. White[qq]
  10055. )
  10056.  
  10057. SHAR_EOF
  10058. fi
  10059. if test -f 'Sample.02'
  10060. then
  10061.     echo shar: "will not over-write existing file 'Sample.02'"
  10062. else
  10063. cat << \SHAR_EOF > 'Sample.02'
  10064. (
  10065. ;
  10066. GaMe[1]
  10067. SiZe[19]
  10068. VieW[]
  10069. Comment[16th Honinbo League Playoff
  10070.     
  10071. White: Sakata Eio 9-dan    
  10072.     
  10073. Black: Kitani Minoru 9-dan
  10074.     
  10075. Komi: 4 1/2    
  10076.  
  10077. Result: White wins by 3 1/2 points]
  10078. Black[qd]
  10079. ;
  10080. White[dc]
  10081. ;
  10082. Black[pq]
  10083. ;
  10084. White[cq]
  10085. ;
  10086. Black[oc]
  10087. ;
  10088. White[po]
  10089. ;
  10090. Black[qo]
  10091. ;
  10092. White[qn]
  10093. ;
  10094. Black[qp]
  10095. ;
  10096. White[pm]
  10097. ;
  10098. Black[nq]
  10099. ;
  10100. White[qi]
  10101. ;
  10102. Black[ce]
  10103. ;
  10104. White[dh]
  10105. ;
  10106. Black[ee]
  10107. ;
  10108. White[cb]
  10109. ;
  10110. Black[cc]
  10111. ;
  10112. White[gc]
  10113. ;
  10114. Black[bc]
  10115. ;
  10116. White[bb]
  10117. ;
  10118. Black[qg]
  10119. ;
  10120. White[dd]
  10121. ;
  10122. Black[de]
  10123. ;
  10124. White[cg]
  10125. ;
  10126. Black[co]
  10127. ;
  10128. White[cm]
  10129. ;
  10130. Black[ep]
  10131. ;
  10132. White[do]
  10133. ;
  10134. Black[dp]
  10135. ;
  10136. White[cp]
  10137. ;
  10138. Black[dn]
  10139. ;
  10140. White[bo]
  10141. ;
  10142. Black[eo]
  10143. ;
  10144. White[cn]
  10145. ;
  10146. Black[el]
  10147. ;
  10148. White[dk]
  10149. ;
  10150. Black[ql]
  10151. ;
  10152. White[rm]
  10153. ;
  10154. Black[rj]
  10155. ;
  10156. White[qe]
  10157. Comment[Complications start. Creating two weak groups. ]
  10158. ;
  10159. Black[qj]
  10160. ;
  10161. White[rd]
  10162. ;
  10163. Black[qc]
  10164. ;
  10165. White[qf]
  10166. ;
  10167. Black[pg]
  10168. ;
  10169. White[rc]
  10170. ;
  10171. Black[rb]
  10172. ;
  10173. White[oe]
  10174. ;
  10175. Black[mc]
  10176. ;
  10177. White[op]
  10178. ;
  10179. Black[on]
  10180. ;
  10181. White[pn]
  10182. ;
  10183. Black[oq]
  10184. ;
  10185. White[mo]
  10186. ;
  10187. Black[mp]
  10188. Comment[Severe attack. ]
  10189. ;
  10190. White[lo]
  10191. Comment[Counters aggressively. ]
  10192. ;
  10193. Black[no]
  10194. ;
  10195. White[np]
  10196. ;
  10197. Black[nm]
  10198. Comment[Black cuts. Brings on crisis.]
  10199. ;
  10200. White[pj]
  10201. ;
  10202. Black[pi]
  10203. ;
  10204. White[pk]
  10205. ;
  10206. Black[rl]
  10207. ;
  10208. White[ml]
  10209. ;
  10210. Black[nl]
  10211. ;
  10212. White[nk]
  10213. ;
  10214. Black[mk]
  10215. ;
  10216. White[om]
  10217. Comment[Exquisite shinogi tesuji. Lets W secure his endangered group]
  10218. ;
  10219. Black[nj]
  10220. ;
  10221. White[ok]
  10222. ;
  10223. Black[ll]
  10224. ;
  10225. White[lp]
  10226. ;
  10227. Black[mq]
  10228. ;
  10229. White[mn]
  10230. ;
  10231. Black[mm]
  10232. ;
  10233. White[nn]
  10234. ;
  10235. Black[rf]
  10236. Comment[Turns toward other weak group. ]
  10237. ;
  10238. White[re]
  10239. ;
  10240. Black[rg]
  10241. ;
  10242. White[nd]
  10243. ;
  10244. Black[nc]
  10245. ;
  10246. White[nf]
  10247. ;
  10248. Black[nh]
  10249. ;
  10250. White[lf]
  10251. ;
  10252. Black[le]
  10253. ;
  10254. White[mh]
  10255. ;
  10256. Black[mi]
  10257. ;
  10258. White[me]
  10259. ;
  10260. Black[mg]
  10261. ;
  10262. White[ld]
  10263. ;
  10264. Black[ke]
  10265. ;
  10266. White[md]
  10267. ;
  10268. Black[kb]
  10269. ;
  10270. White[kc]
  10271. ;
  10272. Black[jb]
  10273. ;
  10274. White[id]
  10275. ;
  10276. Black[kf]
  10277. ;
  10278. White[oi]
  10279. ;
  10280. Black[ph]
  10281. ;
  10282. White[jc]
  10283. Comment[Manages to rescue weak group. ]
  10284. ;
  10285. Black[ib]
  10286. ;
  10287. White[fd]
  10288. ;
  10289. Black[eg]
  10290. ;
  10291. White[lg]
  10292. Comment[Double attack.]
  10293. ;
  10294. Black[lh]
  10295. ;
  10296. White[kg]
  10297. ;
  10298. Black[if]
  10299. ;
  10300. White[hg]
  10301. ;
  10302. Black[hf]
  10303. ;
  10304. White[gf]
  10305. ;
  10306. Black[ge]
  10307. ;
  10308. White[fe]
  10309. ;
  10310. Black[jg]
  10311. ;
  10312. White[he]
  10313. Comment[First time that B is the one under pressure.]
  10314. ;
  10315. Black[gg]
  10316. ;
  10317. White[ff]
  10318. ;
  10319. Black[dg]
  10320. ;
  10321. White[ef]
  10322. ;
  10323. Black[df]
  10324. ;
  10325. White[fg]
  10326. ;
  10327. Black[ch]
  10328. ;
  10329. White[bh]
  10330. ;
  10331. Black[ci]
  10332. ;
  10333. White[bf]
  10334. ;
  10335. Black[ei]
  10336. ;
  10337. White[cj]
  10338. ;
  10339. Black[gh]
  10340. ;
  10341. White[fh]
  10342. ;
  10343. Black[eh]
  10344. ;
  10345. White[dj]
  10346. ;
  10347. Black[di]
  10348. ;
  10349. White[bi]
  10350. ;
  10351. Black[fi]
  10352. ;
  10353. White[gi]
  10354. ;
  10355. Black[gj]
  10356. ;
  10357. White[hh]
  10358. ;
  10359. Black[ii]
  10360. ;
  10361. White[mf]
  10362. ;
  10363. Black[jh]
  10364. Comment[Fight ends. ]
  10365. ;
  10366. White[er]
  10367. Comment[W has taken the lead.]
  10368. ;
  10369. Black[fk]
  10370. ;
  10371. White[ro]
  10372. ;
  10373. Black[rp]
  10374. ;
  10375. White[fq]
  10376. ;
  10377. Black[in]
  10378. ;
  10379. White[go]
  10380. ;
  10381. Black[gn]
  10382. ;
  10383. White[jn]
  10384. ;
  10385. Black[jm]
  10386. ;
  10387. White[fn]
  10388. ;
  10389. Black[hn]
  10390. ;
  10391. White[fo]
  10392. ;
  10393. Black[en]
  10394. ;
  10395. White[fm]
  10396. ;
  10397. Black[dl]
  10398. ;
  10399. White[cl]
  10400. ;
  10401. Black[hl]
  10402. ;
  10403. White[km]
  10404. ;
  10405. Black[jl]
  10406. ;
  10407. White[lq]
  10408. ;
  10409. Black[ip]
  10410. ;
  10411. White[lr]
  10412. ;
  10413. Black[hq]
  10414. ;
  10415. White[os]
  10416. ;
  10417. Black[or]
  10418. ;
  10419. White[gq]
  10420. ;
  10421. Black[dq]
  10422. ;
  10423. White[dr]
  10424. ;
  10425. Black[be]
  10426. ;
  10427. White[hb]
  10428. ;
  10429. Black[ic]
  10430. ;
  10431. White[sb]
  10432. ;
  10433. Black[ra]
  10434. ;
  10435. White[ie]
  10436. ;
  10437. Black[hc]
  10438. ;
  10439. White[gb]
  10440. ;
  10441. Black[gr]
  10442. ;
  10443. White[hi]
  10444. ;
  10445. Black[hj]
  10446. ;
  10447. White[ns]
  10448. ;
  10449. Black[ps]
  10450. ;
  10451. White[mr]
  10452. ;
  10453. Black[pp]
  10454. ;
  10455. White[oo]
  10456. ;
  10457. Black[rr]
  10458. ;
  10459. White[ej]
  10460. ;
  10461. Black[fj]
  10462. ;
  10463. White[ir]
  10464. ;
  10465. Black[hr]
  10466. ;
  10467. White[jr]
  10468. ;
  10469. Black[jo]
  10470. ;
  10471. White[kn]
  10472. ;
  10473. Black[ab]
  10474. ;
  10475. White[qk]
  10476. ;
  10477. Black[rk]
  10478. ;
  10479. White[oj]
  10480. ;
  10481. Black[ia]
  10482. ;
  10483. White[jp]
  10484. ;
  10485. Black[fr]
  10486. ;
  10487. White[iq]
  10488. ;
  10489. Black[hp]
  10490. ;
  10491. White[eq]
  10492. ;
  10493. Black[af]
  10494. ;
  10495. White[kl]
  10496. ;
  10497. Black[kk]
  10498. ;
  10499. White[ko]
  10500. ;
  10501. Black[ag]
  10502. ;
  10503. White[kh]
  10504. ;
  10505. Black[ki]
  10506. ;
  10507. White[bg]
  10508. ;
  10509. Black[gm]
  10510. ;
  10511. White[ng]
  10512. ;
  10513. Black[mh]
  10514. ;
  10515. White[sl]
  10516. ;
  10517. Black[so]
  10518. ;
  10519. White[rn]
  10520. ;
  10521. Black[hd]
  10522. ;
  10523. White[gd]
  10524. ;
  10525. Black[lm]
  10526. ;
  10527. White[ri]
  10528. ;
  10529. Black[si]
  10530. ;
  10531. White[sf]
  10532. ;
  10533. Black[sg]
  10534. ;
  10535. White[io]
  10536. ;
  10537. Black[ho]
  10538. ;
  10539. White[cd]
  10540. ;
  10541. Black[bd]
  10542. ;
  10543. White[pd]
  10544. ;
  10545. Black[pc]
  10546. ;
  10547. White[se]
  10548. ;
  10549. Black[nr]
  10550. ;
  10551. White[ms]
  10552. ;
  10553. Black[ha]
  10554. ;
  10555. White[ga]
  10556. ;
  10557. Black[lc]
  10558. ;
  10559. White[kd]
  10560. ;
  10561. Black[ed]
  10562. ;
  10563. White[ec]
  10564. ;
  10565. Black[fl]
  10566. ;
  10567. White[ah]
  10568. ;
  10569. Black[ae]
  10570. ;
  10571. White[je]
  10572. ;
  10573. Black[jf]
  10574. ;
  10575. White[ni]
  10576. ;
  10577. Black[mj]
  10578. ;
  10579. White[ih]
  10580. ;
  10581. Black[sc]
  10582. ;
  10583. White[sd]
  10584. ;
  10585. Black[od]
  10586. ;
  10587. White[pf]
  10588. ;
  10589. Black[db]
  10590. ;
  10591. White[eb]
  10592. ;
  10593. Black[ba]
  10594. ;
  10595. White[da]
  10596. ;
  10597. Black[do]
  10598. ;
  10599. White[hs]
  10600. ;
  10601. Black[og]
  10602. ;
  10603. White[of]
  10604. ;
  10605. Black[es]
  10606. ;
  10607. White[ds]
  10608. ;
  10609. Black[fs]
  10610. ;
  10611. White[jo]
  10612. ;
  10613. Black[ac]
  10614. ;
  10615. White[pe]
  10616. )
  10617. SHAR_EOF
  10618. fi
  10619. if test -f 'Rules'
  10620. then
  10621.     echo shar: "will not over-write existing file 'Rules'"
  10622. else
  10623. cat << \SHAR_EOF > 'Rules'
  10624. This files contains rules to the game of Go in Smart-Go format.  It should be 
  10625. viewed with the mgt program.
  10626.  
  10627. (
  10628. ;
  10629. GaMe[1]
  10630. VieW[]
  10631. SiZe[19]
  10632. Comment[        THE GAME OF GO
  10633.       A Brief Introduction
  10634.  
  10635.        by Adrian Mariano
  10636.  
  10637.  
  10638.  
  10639.    press . to move forward
  10640.    press , to move backward ]
  10641. ;
  10642. Comment[Go is a two player strategy board game.  Players take turns putting black and white pieces \(called stones\) on the board.  The board is normally a 19x19 grid.  The stones are placed on the intersections.  Once played, a stone cannot be moved, though it may be captured by the other player.  The object of the game is to surround territory.]
  10643. ;
  10644. Comment[There are three major scoring systems for Go:  Japanese, Chinese and Ing.  This tutorial describes the Japanese system, which is the most common in Western countries.  Under Japanese rules, a completed game is scored as follows:  each intersection surrounded and each prisoner captured count as a point. The player with the most points wins.]
  10645. ;
  10646. Comment[When a player has nothing left to do, he passes.  After two consecutive passes, the game is over.]
  10647. ;
  10648. Comment[An empty intersection adjacent to a stone \(orthogonally\) is called a liberty. 
  10649.  
  10650. The white stone in the center of the board has 4 liberties, the marked spots.  The white stone at the bottom has three liberties, and the white stone in corner has two liberties.]
  10651. AddWhite[jj][js][ss]
  10652. Mark[ij][ji][kj][jk][is][jr][ks][rs][sr]
  10653. AddEmpty[aa]
  10654. ;
  10655. AddBlack[dc][dd][ed][fd][fe][ge]
  10656. Comment[Groups of stones that are connected orthogonally can be captured all at once by removing all of their liberties.  The black stones are orthogonally connected and have 11 liberties.  The white stones are not orthogonally connected.]
  10657. AddWhite[in][io][jn][jo][kl][km][ll][lm]
  10658. Mark[ff][gf][he][gd][ee][de][cd][fc][ec][cc][db]
  10659. AddEmpty[aa][ep][fp][gp][jj][jp][jq][js][kj][kk][kp][lk][lp][mp][na][np][ob][pb][pc][qd][qk][qm][rb][re][ri][rj][rk][rm][rn][ro][rp][sd][se][si][sp][ss]
  10660. ;
  10661. AddBlack[ij][ji][jj]
  10662. AddEmpty[aa][dc][dd][ed][ep][fd][fe][fp][ge][gp][hj][in][io][jn][jo][jp][jq][kl][km][kp][ll][lm][lp][mp][na][np][ob][pb][pc][qd][qk][ql][qm][rb][re][ri][rj][rk][rm][rn][ro][rp][sd][se][si][sp]
  10663. Comment[A group is captured if its last liberty is taken away.
  10664.  
  10665.  
  10666. Here is a black group with seven liberties.]
  10667. ;
  10668. AddWhite[hj]
  10669. Comment[A single white stone next to the group reduces it to six liberties.]
  10670. ;
  10671. AddWhite[ik][jh][jk][ki][kj]
  10672. Comment[Six white stones reduces the group to one liberty \(remember that play alternates black and white.  These stones could not be placed like this during a game.\)]
  10673. ;
  10674. White[ii]
  10675. Comment[The final white move captures the black group.]
  10676. ;
  10677. AddWhite[qh][qi][qj][rg][rk][sg][sk]
  10678. AddBlack[rh][ri][rj][sh][sj]
  10679. AddEmpty[aa][hj][ii][ik][jh][jk][ki][kj]
  10680. Comment[The black group has only one liberty.  White can capture the black group by playing inside black at T11.]
  10681. ;
  10682. White[si]
  10683. ;
  10684. AddBlack[rh][ri][rj][sh][sj]
  10685. Comment[It is illegal to comit suicide.  White cannot play at T11 now, because the move does not capture the black group, and the white stone at T11 would have no liberties.]
  10686. AddWhite[qh][qj][rg][rk][sg][sk]
  10687. AddEmpty[aa][qi][si]
  10688. ;
  10689. Comment[Another rule of Go is the Ko rule.  It is illegal to make a move which recreates preceeding board positions \(to prevent loops\).
  10690.  
  10691.  
  10692. Suppose black captures the white stone at J12.]
  10693. AddBlack[hh][ig][ii]
  10694. AddWhite[ih][jg][ji][kh]
  10695. AddEmpty[aa][ab][ac][aq][ar][bb][bc][bq][br][bs][ca][cb][cc][cq][cr][da][db][dc][dq][dr][ds][eq][er][es][qg][qh][qi][qj][qk][ql][rf][rg][rh][ri][rj][rk][rl][sf][sg][sh][sj][sk][sl]
  10696. ;
  10697. Black[jh]
  10698. Comment[If white were allowed to play at J12 now, the board would look exactly as it did before.]
  10699. ;
  10700. AddEmpty[jh]
  10701. AddWhite[ih]
  10702. Comment[This white move is ILLEGAL.  White must wait a turn before making this move, giving black the option of filling in the hole at J12.]
  10703. ;
  10704. AddEmpty[aa][hh][ig][ih][ii][jg][ji][kh][ph][qh][qj][rg][rh][ri][rj][rk][sg][sh][sj][sk]
  10705. Comment[The concept of life is an important, and tricky one.  You must know how to make a living group.  A living group is one that can't be captured.  
  10706.  
  10707.  
  10708. A liberty which is inside a group and completely surrounded is called an eye.  A group with two disconnected eyes cannot be captured.]
  10709. ;
  10710. AddBlack[ic][id][ie][jc][je][jj][jk][jl][kc][kd][ke][kj][kl][lc][le][lj][lk][ll][mc][md][me]
  10711. AddWhite[hc][hd][he][ib][if][ij][ik][il][jb][jf][ji][jm][kb][kf][ki][km][lb][lf][li][lm][mb][mf][mj][mk][ml][nc][nd][ne]
  10712. AddEmpty[aa][hb][hf][ii][im][mi][mm][nb][nf]
  10713. Comment[The black group above cannot be captured, because it has two eyes, the points K16 and M16.  White cannot play in either eye, because his stone would have no liberties.
  10714.  
  10715. White CAN capture the lower group, however, because it has only a single eye, and a white stone played within it reduces black to zero liberties.]
  10716. ;
  10717. White[kk]
  10718. ;
  10719. AddWhite[aq][ar][bq][bs][cq][cr][cs]
  10720. AddBlack[ap][bp][cp][dp][dq][dr][ds]
  10721. AddEmpty[aa][hc][hd][he][ib][ic][id][ie][if][ij][ik][il][jb][jc][je][jf][ji][jm][kb][kc][kd][ke][kf][ki][kk][km][lb][lc][le][lf][li][lm][mb][mc][md][me][mf][mj][mk][ml][nc][nd][ne]
  10722. Comment[Here is another example of a living group.  Black cannot capture the white group, because it has two eyes at A1 and B2.  Black cannot play at either of these points, because the black stone would have no liberties.]
  10723. ;
  10724. Comment[The black group here has only ONE eye.  If black does not make further moves in this area, white can capture black.  \(More on this shape later.\)]
  10725. AddBlack[ap][bp][cp][cq][cr][cs]
  10726. AddWhite[ao][bo][co][do][dp][dq][dr][ds]
  10727. AddEmpty[aa][aq][ar][bq][br][bs]
  10728. ;
  10729. AddBlack[ao][bo][co][do][eo][fo][go][ho][hp][hq][hr][hs]
  10730. AddWhite[ap][bp][cp][cr][dp][dq][dr][ds][ep][fp][gp][gq][gr][gs]
  10731. Comment[The white group here is also alive.  If black plays inside, white can safely ignore his plays completely.  White will be able to capture the black stones no matter what black does.  If black does this, white can gain points by simply passing.  ]
  10732. AddEmpty[aa][cq][cs]
  10733. ;
  10734. AddBlack[af][al][bf][bg][bk][bl][cg][ch][ci][cj][ck][ga][gb][gc][hc][ic][jc][kc][lc][ma][mb][mc]
  10735. AddWhite[ag][ai][ak][bh][bi][bj][ha][hb][ib][ja][jb][kb][la][lb]
  10736. AddEmpty[aa][ao][ap][bo][bp][co][cp][cr][do][dp][dq][dr][ds][eo][ep][fo][fp][go][gp][gq][gr][gs][ho][hp][hq][hr][hs]
  10737. Comment[Compare these two white groups.  The white group at the top is alive, because it has two eyes.  But beware!  The white group on the left side is dead!]
  10738. ;
  10739. Comment[The Ko rules prevents white from recapturing the stone at A12.  White must play somewhere else on the board, allowing black to capture the stones.]
  10740. Black[ah]
  10741. ;
  10742. Black[aj]
  10743. ;
  10744. Comment[Here is another example of a DEAD group.  The white group at the bottom does NOT have two eyes.]
  10745. AddBlack[lp][lq][lr][ls][mp][np][op][oq][or][pp][qp][rp][sp][sq][sr]
  10746. AddWhite[mr][ms][nr][os][pq][pr][ps][qq][rq][rr][rs]
  10747. AddEmpty[aa][af][ah][aj][al][bf][bg][bk][bl][cg][ch][ci][cj][ck][ga][gb][gc][ha][hb][hc][ib][ic][ja][jb][jc][kb][kc][la][lb][lc][ma][mb][mc][mq][nq]
  10748. ;
  10749. AddWhite[ar][br][cr][cs]
  10750. AddBlack[aq][bq][cq][dq][dr][ds]
  10751. AddEmpty[aa][ao][ap][bo][bp][co][cp][do][dp][eo][ep][fo][fp][go][gp][gq][gr][gs][ho][hp][hq][hr][hs][lp][lq][lr][ls][mp][mr][ms][np][nr][op][oq][or][os][pp][pq][pr][ps][qp][qq][rp][rq][rr][rs][sp][sq][sr]
  10752. Comment[In this example, the white group is dead.  There is nothing white can do to prevent black from capturing it.]
  10753. ;
  10754. Black[bs]
  10755. ;
  10756. White[as]
  10757. ;
  10758. Black[bs]
  10759. Comment[Notice that black had to sacrifice a stone to capture the white group, but black succeeds in the end.  Because both players can tell that black will be able to capture white, black does not actually need to play any stones.  This group is dead and will be removed at the end of the game.]
  10760. ;
  10761. AddWhite[ar][br][cr][dr][ds]
  10762. AddBlack[eq][er][es]
  10763. AddEmpty[aa][bs]
  10764. Comment[This case is more complicated.  If white plays first, then the group has two eyes and lives.]
  10765. ;
  10766. White[bs]
  10767. ;
  10768. Comment[On the other hand, if black plays first, the group is killed. ]
  10769. AddEmpty[aa][bs]
  10770. ;
  10771. Black[bs]
  10772. ;
  10773. White[cs]
  10774. ;
  10775. Black[as]
  10776. ;
  10777. Comment[In this case, the white group is alive, even if black plays first.]
  10778. AddWhite[ar][br][cr][dr][er][es]
  10779. AddBlack[aq][fq][fr][fs]
  10780. AddEmpty[aa][as][bs][en]
  10781. ;
  10782. Black[cs]
  10783. ;
  10784. White[bs]
  10785. ;
  10786. Comment[In this case, however, the white stones can be killed if black moves first.  \(If white plays first at B1, then they are alive.\)]
  10787. AddBlack[ap][bp][cp][dp][dq][eq][er][es]
  10788. AddWhite[aq][bq][cq][cr][ds]
  10789. AddEmpty[aa][ar][bn][br][bs][cs]
  10790. ;
  10791. Black[bs]
  10792. ;
  10793. White[br]
  10794. ;
  10795. Black[as]
  10796. ;
  10797. White[cs]
  10798. ;
  10799. Black[ar]
  10800. ;
  10801. AddWhite[ao][bo][co][do][dp][dq][dr][ds]
  10802. AddBlack[ap][bp][cp][cq][cr][cs]
  10803. AddEmpty[aa][aq][ar][as][bq][bs][eq][er][es][fq][fr][fs]
  10804. Comment[As promised, here is the situation we saw earlier.  This situation is similar to the preceeding one.  If black plays first, then black can live.]
  10805. ;
  10806. Black[br]
  10807. ;
  10808. White[ar]
  10809. ;
  10810. Black[aq]
  10811. ;
  10812. White[bs]
  10813. ;
  10814. Black[as]
  10815. ;
  10816. AddEmpty[aa][aq][ar][as][br][es]
  10817. Comment[If, however, white plays first, white can kill the black group.]
  10818. ;
  10819. White[br]
  10820. ;
  10821. Black[bs]
  10822. ;
  10823. White[ar]
  10824. ;
  10825. Black[aq]
  10826. ;
  10827. White[as]
  10828. ;
  10829. Black[bq]
  10830. ;
  10831. White[ar]
  10832. ;
  10833. Black[br]
  10834. ;
  10835. White[as]
  10836. ;
  10837. AddWhite[ab][ai][am][ar][bb][bi][bm][br][ca][cb][ci][cj][ck][cl][cm][cr][dr][ds][rh][ri][rj][rk][sg][si][sk]
  10838. AddBlack[ac][ah][ak][an][aq][bc][bh][bk][bn][bq][bs][cc][ch][cn][cq][da][db][dc][dh][di][dj][dk][dl][dm][dn][dq][eq][er][es][qg][qh][qi][qj][qk][ql][rf][rg][rl][sf][sl]
  10839. AddEmpty[aa][ao][as][bo][co][do][dp][sh]
  10840. Comment[Each of these groups is dead.  In all cases where a group can be considered dead, it can be removed from the board at the end of the game without further play.  It is NOT advantageous to capture groups which are dead, unless they threaten your position, because doing so reduces your own territory, and may allow your opponent to make important moves.]
  10841. ;
  10842. AddBlack[cj][ck][cl][cm][cn][co][db][dc][dd][de][df][dg][dj][do][ea][eb][eg][ej][eo][fa][fg][fj][fo][ga][gg][gj][gn][go][ha][hg][hj][hn][ia][ib][if][ig][ij][ik][il][im][in][jb][jc][jd][je][jf][jg][km][kn][ko][kp][kq][ll][lm][lq][lr][ml][mr][nl][nr][ol][or][pd][pe][pf][pg][ph][pl][pm][pq][pr][qc][qd][qh][qi][qm][qn][qo][qp][qq][rc][ri][sc][si]
  10843. AddWhite[dk][dl][dm][dn][ec][ed][ee][ef][ek][en][fb][fc][ff][fk][fn][gb][gf][gk][gm][hb][hc][he][hf][hk][hl][hm][ic][id][ie][ln][lo][lp][mm][mn][mp][mq][nm][nq][om][on][op][oq][pn][po][pp][qe][qf][qg][rd][re][rg][rh][sd][sh]
  10844. Comment[All of the white groups are dead if black moves first, but live if white moves first.  Can you find the move that kills each group?]
  10845. AddEmpty[aa][ab][ac][ah][ai][ak][al][am][an][aq][ar][bb][bc][bd][be][bh][bi][bk][bl][bm][bn][bq][br][bs][ca][cb][cc][ch][ci][cq][cr][da][dh][di][dq][dr][ds][eh][ei][el][eq][er][es][fh][fl][gh][gl][hh][ih][ii][jh][ji][jj][jk][kh][qj][qk][ql][rf][rj][rk][rl][sf][sg][sk][sl]
  10846. ;
  10847. AddEmpty[aa][cj][ck][cl][cm][cn][co][db][dc][dd][de][df][dg][dj][dk][dl][dm][dn][do][ea][eb][ec][ed][ee][ef][eg][ej][ek][en][eo][fa][fb][fc][ff][fg][fj][fk][fn][fo][ga][gb][gf][gg][gj][gk][gm][gn][go][ha][hb][hc][he][hf][hg][hj][hk][hl][hm][hn][ia][ib][ic][id][ie][if][ig][ij][ik][il][im][in][jb][jc][jd][je][jf][jg][km][kn][ko][kp][kq][ll][lm][ln][lo][lp][lq][lr][ml][mm][mn][mp][mq][mr][nl][nm][nq][nr][ol][om][on][op][oq][or][pd][pe][pf][pg][ph][pl][pm][pn][po][pp][pq][pr][qc][qd][qe][qf][qg][qh][qi][qm][qn][qo][qp][qq][rc][rd][re][rg][rh][ri][sc][sd][sh][si]
  10848. Comment[If there is debate over who owns a territory, or whether a group is alive, simply continue play until the players agree.]
  10849. ;
  10850. AddBlack[an][ap][bn][bo][bp][br][bs][cp][cs][dp][ds][ep][er][es][fp][gp][gq][gr][gs][hr][ir][is]
  10851. AddWhite[aq][ar][as][bq][cq][dq][eq][fq][fr][fs]
  10852. AddEmpty[ai][aj][ak][al][am][bi][bj][bk][bl][bm][cr][dr]
  10853. Comment[This situation is called seki.  Even though the white group and the black group contained inside do not have two eyes, they are considered alive.
  10854.  
  10855. The reason is that neither black nor white can make a move in the region.  ]
  10856. (
  10857. ;
  10858. White[cr]
  10859. Comment[If white attempts to capture black by playing inside...]
  10860. ;
  10861. Black[dr]
  10862. Comment[Then black captures the white stones.]
  10863. )
  10864. (
  10865. ;
  10866. Comment[If black tries to capture white by moving inside...]
  10867. Black[cr]
  10868. ;
  10869. Comment[Then white captures black, and now the white group is alive.  ]
  10870. White[dr]
  10871. ;
  10872. Comment[Notice that the black group around the very outside is clearly alive, with two eyes.  If white were able to surround and capture the black group, then he could break the deadlock and the situation would no longer be seki.]
  10873. ;
  10874. AddEmpty[aa][an][ap][aq][ar][as][bo][bp][bq][cp][cq][dp][dq][dr][ep][eq][fp][fq][fr][fs][gp][gq][gr][gs][hr][ir][is]
  10875. Comment[Examine this situation.  The white and black groups have started surrounding each other.  This is called a "capture race."  If white plays first, who will capture whom?]
  10876. AddWhite[bh][bi][bj][bn][cj][cm][cn][dk][dl]
  10877. AddBlack[bf][bk][bl][bm][cf][cg][ch][ci][ck][di][dj]
  10878. ;
  10879. White[am]
  10880. ;
  10881. Black[bg]
  10882. ;
  10883. White[al]
  10884. ;
  10885. Black[ah]
  10886. ;
  10887. White[ak]
  10888. ;
  10889. Black[ai]
  10890. ;
  10891. White[cl]
  10892. ;
  10893. Black[ag]
  10894. ;
  10895. White[aj]
  10896. ;
  10897. Comment[Connections of stones are very important.  If two groups each have one eye, they can live if they can be connected directly to each other.]
  10898. AddEmpty[aa][ag][ah][ai][aj][ak][al][am][bf][bg][bh][bi][bj][bn][cf][cg][ch][ci][cj][cl][cm][cn][di][dj][dk][dl]
  10899. AddBlack[aq][bq][cq][cr][dq][eq][fq][gq][gr][gs]
  10900. AddWhite[ar][br][bs][dr][ds][er][fr][fs]
  10901. (
  10902. ;
  10903. Black[cs]
  10904. Comment[If black plays here, then the two white groups will die, since each has only one eye.]
  10905. )
  10906. (
  10907. ;
  10908. White[cs]
  10909. Comment[If white plays C1, then his stones are connected into one group which has two eyes.]
  10910. ;
  10911. AddEmpty[aa][aq][ar][bq][br][bs][cq][cr][cs][dq][dr][ds][eq][er][fq][fr][fs][gq][gr][gs]
  10912. Comment[Obviously, this sort of loose connection only works if it happens to be white's turn.  It is not reasonable to play all your stones solidly connected, because you will not be able to get much territory.  You must instead make different types of connections which can be fortified when they are attacked.]
  10913. ;
  10914. Comment[In this situation, the black stones can be considered connected, even though they are not yet orthogonally connected directly.]
  10915. AddWhite[ah][al][bh][bl][ch][ci][ck][cl][di][dk][dl][ei][el][fi][fl][gi][gj][gl][gm][hi][hm][ii][im][ji][jm][ki][kj][kk][kl][km]
  10916. AddBlack[ai][ak][bi][bj][bk][cj][dj][ej][fk][gk][hj][hk][hl][ij][il][jj][jk][jl]
  10917. AddEmpty[aa][cs][ek][fj][lj][lk][ll][mj][mk][ml][nj][nk][nl][oj][ok][ol][pj][pk][pl][qi][qj][qk][ql][qm][ri][rj][rk][rl][rm][si][sj][sl][sm]
  10918. ;
  10919. Comment[If white threatens to disconnect the black stones...]
  10920. White[fj]
  10921. ;
  10922. Comment[...black always has a response which connects his stones.  ]
  10923. Black[ek]
  10924. ;
  10925. AddBlack[lm][lp][mm][mp][nm][np]
  10926. Comment[Here is another strong connection that cannot be cut.]
  10927. AddWhite[io][jo][ko][ln][lo][nn][no][on][pn][qn]
  10928. AddEmpty[aa][ah][ai][ak][al][bh][bi][bj][bk][bl][ch][ci][cj][ck][cl][di][dj][dk][dl][ei][ej][ek][el][fi][fj][fk][fl][gi][gj][gk][gl][gm][hi][hj][hk][hl][hm][ii][ij][il][im][jc][jd][je][ji][jj][jk][jl][jm][kc][ke][ki][kj][kk][kl][km][lc][ld][le][md][nd][ne][pa][pb][pc][pd][pe][qa][qb][qc][qd][ra][rb][rc][rd][sb][sc]
  10929. ;
  10930. Comment[If black tries to disconnect the white stones...]
  10931. Black[mo]
  10932. ;
  10933. Comment[...as with the diagonal connection, white always has a response which directly connects his stones. \(This is called a bamboo connection\)]
  10934. White[mn]
  10935. ;
  10936. Comment[There are several other weaker connections which can be cut.  ]
  10937. AddEmpty[aa][ao][aq][bn][bo][bp][bq][br][cn][cp][cr][dm][dn][do][dp][dq][dr][ep][eq][fo][fp][fq][gp][gq][hp][io][ip][jo][jp][ko][kp][kq][lm][ln][lo][lp][lq][mm][mn][mo][mp][mq][nm][nn][no][np][on][pn][qn]
  10938. ;
  10939. Comment[These are all weaker connections.  Whether the stones can be separated depends on the location on the board and what other stones are in place.  
  10940.     The marked locations are the cutting points -- the moves white would make to disconnect black.]
  10941. Mark[fo][fb][fe][gh][fk]
  10942. AddEmpty[aa][cl][cp][dl][dp][ec][ej][el][ep][fc][fi][fj][fo][fp][gi][gj][gp][hd][hi][hm][id][ii][ij][im][jd][jj][jm][kd][kj][kp][lp][pg][ph][pi][ql][qm][qn]
  10943. AddBlack[cb][ce][ch][ck][co][db][de][dh][dk][do][eb][ee][eh][ek][eo][gb][gl][hb][he][hl][hp][ib][ie][ih][il][ip][je][jh][jp][kh]
  10944. ;
  10945. Comment[In previous diagrams, several times a ko has arisen during an attempt to capture a group.  In these cases, I have ignored the possible reprecussions of the play that must be made elsewhere.  Now consider this one situation on the whole board.  White wishes to kill the black group at the left.]
  10946. AddBlack[bp][cp][dp][dq][dr][ph][pm][pn][po][pp][pq][qi][qq][qr][qs][ri][rj][rk][rs][si][sl]
  10947. AddWhite[bm][bo][co][do][eo][ep][eq][er][gr][oj][ok][ol][pl][ql][qn][rl][rn][ro][rp][rq][sq]
  10948. AddEmpty[aa][cb][ce][ch][ck][co][db][de][dh][dk][do][eb][ee][eh][ek][eo][gb][gl][hb][he][hl][hp][ib][ie][ih][il][ip][je][jh][jp][kh]
  10949. ;
  10950. White[br]
  10951. ;
  10952. Black[ar]
  10953. ;
  10954. White[cr]
  10955. ;
  10956. Black[ds]
  10957. ;
  10958. White[ap]
  10959. ;
  10960. Black[aq]
  10961. ;
  10962. White[ao]
  10963. ;
  10964. Black[bq]
  10965. ;
  10966. White[cs]
  10967. ;
  10968. Black[bs]
  10969. ;
  10970. Comment[We have reached a Ko situation.  Black may not retake the white stone at A1. 
  10971.  
  10972. Black may, however, attack the white formation on the right side of the board.]
  10973. White[as]
  10974. ;
  10975. Comment[This attack by black is called a "ko threat."  Black is forcing white to decide between killing the group in the left corner, and connecting on the right.  Note that if white does not connect on the right, then the white stones on the right will die.]
  10976. Black[qm]
  10977. (
  10978. ;
  10979. Name[On the right]
  10980. Comment[White will now respond on the right, connecting the white groups together.]
  10981. White[rm]
  10982. ;
  10983. Black[bs]
  10984. ;
  10985. Comment[White cannot retake the ko at B1 now.  He would like to find an attack similar to the one black used on him, but since the board is almost empty, no such attack exists.  \(White can play at T7, threatening to capture the single black stone, but black would much rather save his 10 corner stones than a single side stone.\)]
  10986. White[sm]
  10987. ;
  10988. Black[cq]
  10989. Comment[The black group lives.]
  10990. )
  10991. (
  10992. ;
  10993. Comment[White plays in the corner, planning to kill the group on the left.]
  10994. Name[In the corner]
  10995. ;
  10996. White[bs]
  10997. ;
  10998. Black[cq]
  10999. ;
  11000. Comment[The black stones are dead.]
  11001. White[bs]
  11002. ;
  11003. Comment[But black gets to cut off the white stones.]
  11004. Black[rm]
  11005. ;
  11006. Comment[Suppose black wants to capture the white stone.  ]
  11007. AddBlack[dm][em][fn]
  11008. AddWhite[en]
  11009. AddEmpty[aa][ao][ap][aq][ar][as][bm][bo][bp][bq][br][bs][cn][co][cp][cq][cs][dn][do][dp][dq][dr][ds][eo][ep][eq][er][es][gr][oj][ok][ol][ph][pl][pm][pn][po][pp][pq][qi][ql][qm][qn][qq][qr][qs][ri][rj][rk][rl][rm][rn][ro][rp][rq][rs][si][sl][sq]
  11010. (
  11011. ;
  11012. Comment[If black plays here...]
  11013. Black[dn]
  11014. ;
  11015. Comment[...white escapes downward.  
  11016.  
  11017. This is not the correct approach.]
  11018. White[eo]
  11019. )
  11020. (
  11021. ;
  11022. Comment[Instead, black should play here.  This starts a pattern called the "ladder," a very common occurrence in go games.]
  11023. Black[eo]
  11024. ;
  11025. Comment[The only direction white can go is leftwards.  However, observe the sequence that follows. ]
  11026. White[dn]
  11027. ;
  11028. Black[cn]
  11029. ;
  11030. White[do]
  11031. ;
  11032. Black[dp]
  11033. ;
  11034. White[co]
  11035. ;
  11036. Black[bo]
  11037. ;
  11038. White[cp]
  11039. ;
  11040. Black[cq]
  11041. ;
  11042. White[bp]
  11043. ;
  11044. Black[ap]
  11045. ;
  11046. White[bq]
  11047. ;
  11048. Black[br]
  11049. ;
  11050. White[aq]
  11051. ;
  11052. Comment[Each of the moves is forced, and white is unable to save the stones.  
  11053.  
  11054.  
  11055. White must be able to recognize this, so he can avoid playing this sequence and losing such a large group of stones.]
  11056. Black[ar]
  11057. ;
  11058. Comment[The outcome is very different if white has a stone in the path of the ladder.]
  11059. AddBlack[fn]
  11060. AddWhite[bo][en]
  11061. AddEmpty[aa][ap][ar][br][cn][co][cq][dn][dp][eo]
  11062. ;
  11063. Black[eo]
  11064. ;
  11065. White[dn]
  11066. ;
  11067. Black[cn]
  11068. ;
  11069. White[do]
  11070. ;
  11071. Black[dp]
  11072. ;
  11073. White[co]
  11074. ;
  11075. Black[cm]
  11076. ;
  11077. White[ep]
  11078. ;
  11079. Black[fo]
  11080. ;
  11081. Comment[Black fails to capture white in this case.]
  11082. White[dq]
  11083. ;
  11084. Comment[In this case, white wishes to capture the black stone.  ]
  11085. AddWhite[jh][ji][jj][kj][lj]
  11086. AddBlack[ki]
  11087. AddEmpty[aa][bo][cm][cn][co][dm][dn][do][dp][dq][em][en][eo][ep][fn][fo][iq]
  11088. ;
  11089. Comment[To do so, white plays here.]
  11090. White[lh]
  11091. ;
  11092. Black[li]
  11093. ;
  11094. White[mi]
  11095. ;
  11096. Black[kh]
  11097. ;
  11098. White[kg]
  11099. ;
  11100. AddEmpty[aa][jh][ji][jj][kg][kj][lh][lj][mi]
  11101. Comment[It is important to remember that the object of the game is TERRITORY, not captured stones.  Capturing stones, or preventing stones from being captured is important only when it increases your territory.  A frequent beginner error is to place too much emphasis on capturing stones.]
  11102. ;
  11103. AddBlack[ap][bp][cp][da][db][dc][dd][dp][dq][dr][ds][ed][fd][gd][ha][hb][hc][hd][ih][ii][ij][ik][il][jh][jl][kh][kl][lh][ll][mh][mi][mj][mk][ml]
  11104. Comment[It is easiest to make territory in the corner, and hardest in the center.  Each group surrounds nine points of territory.  The corner group is 7 stones, side group is 11 stones, and the center is 16 stones.  Because of this, you should start in the corner, and expand along the sides from the corners, and finally expand into the center from the sides.]
  11105. ;
  11106. AddEmpty[aa][ap][bp][cp][da][db][dc][dd][dp][dq][dr][ds][ed][fd][gd][ha][hb][hc][hd][ih][ii][ij][ik][il][jh][jl][kh][kl][lh][ll][mh][mi][mj][mk][ml]
  11107. Comment[A common opening move is to play at the 4,4 point in one of the corners.  This move has potential to claim corner territory, side territory, and even center territory.]
  11108. Black[pp]
  11109. ;
  11110. White[qq]
  11111. Comment[Note that white can play underneath black and take the corner despite the black stone at the 4,4 point, however.  This move by white is NOT an opening move, but is an attack that would occur later in the game.]
  11112. ;
  11113. AddBlack[qq]
  11114. AddEmpty[aa][pp]
  11115. Comment[Opening at the 3,3 point insures ownership of the corner but has less potential for extension into the center.]
  11116. ;
  11117. AddBlack[de][pq]
  11118. AddEmpty[aa][qq]
  11119. Comment[Other good openings are the 5,4 point and the 3,4 point.]
  11120. ;
  11121. Comment[From either of these openings, black can make a corner enclosure so get corner territory.]
  11122. AddBlack[dc][qo]
  11123. ;
  11124. Comment[And then extend along the side, staking out side territory.]
  11125. AddBlack[ic][kq]
  11126. ;
  11127. AddEmpty[dc][de][ic][kq][pq][qo]
  11128. AddBlack[dd][dj][dp][jj][pd][pj][pp]
  11129. Comment[Go players use a handicap system to balance games between players of 
  11130. different skill.  The weaker player starts by placing from two to nine stones 
  11131. on the board in a special configuration on the handicap points.  
  11132.     
  11133.  
  11134. This is a seven stone handicap.]
  11135. ;
  11136. AddEmpty[aa][dd][dj][dp][jj][pd][pj][pp]
  11137. Comment[Playing strength of amateurs is measured on a scale where one unit 
  11138. corresponds to a handicap stone.  A total beginner is 35 kyu, and will very 
  11139. quickly improve to 20 kyu.  A player will reach 10 kyu after playing about 
  11140. 100 games.  Ranks worse than 10 kyu are unreliable because playing is too 
  11141. uneven and players progress too quickly to get a stable rating.]
  11142. ;
  11143. Comment[Beyond the kyu ranks are the amateur dan ranks which go from 1 dan to 6 dan, the highest amateur rank.
  11144.  
  11145.  
  11146. A 5 kyu player would give a 9 kyu player a four stone handicap.  A 2 dan player would give a two stone handicap to a 1 kyu player.  Each handicap stone is worth about 10 points.]
  11147. ;
  11148. Comment[Professional players have a different ranking system from 1 dan \(lowest\) to 9 dan \(highest\) which has a finer grating:  a 9 dan is about two stones better than a 1 dan. ]
  11149. ;
  11150. Comment[Playing Black, who always moves first, is advantageous because you start with the initiative.  Generally, white is given 5.5 extra points, called a komi, to compensate for his disadvantage.  \(The 1/2 point prevents tie games.\)]
  11151. ;
  11152. Comment[A new player should begin by playing several games on a 9x9 board, followed by several games on a 13x13 board before finally playing on the full sized 19x19 board.]
  11153. ;
  11154. Comment[The strategy of go is very complex and intricate.  If you wish to become a good player, you should buy a book about the game.
  11155.  
  11156. Computer go programs are presently very weak -- they are ranked around 10 kyu]
  11157. )
  11158. )
  11159. )
  11160. )
  11161. )
  11162. SHAR_EOF
  11163. fi
  11164. if test -f 'Prop.lst'
  11165. then
  11166.     echo shar: "will not over-write existing file 'Prop.lst'"
  11167. else
  11168. cat << \SHAR_EOF > 'Prop.lst'
  11169.                              Smart-Go Properties 
  11170.  
  11171. mgt
  11172. supports
  11173.  
  11174. x       "B" : Black move                [move]
  11175. x       "W" : White move                [move]
  11176. x       "C" : Comment                   [Text]
  11177. x       "N" : Node Name                 [Text]
  11178.         "V" : Node value                [number]
  11179.         "CH": Check mark                [triple]
  11180.         "GB": good for black            [triple]
  11181.         "GW": good for white            [triple]
  11182.         "TE": good move (tesuji)        [triple]
  11183.         "BM": bad move                  [triple]
  11184.         "BL": time left for Black       [real]
  11185.         "WL": time left for White       [real]
  11186.         "FG": figure                    [none]
  11187. x       "AB": add black stones          [point list]
  11188. x       "AW": add white stones          [point list]
  11189. x       "AE": add empty stones          [point list]
  11190. x       "PL": player to play first      [color]
  11191. x       "GN": game name                 [text]
  11192. x       "GC": game comment              [text]
  11193. x       "EV": event (tournament)        [text]
  11194. x       "RO": round                     [text]
  11195. x       "DT": date                      [text]
  11196. x       "PC": place                     [text]
  11197. x       "PB": black player name         [text]
  11198. x       "PW": white player name         [text]
  11199. x       "RE": result, outcome           [text]
  11200. x       "US": user (who entered game)   [text]
  11201. x       "TM": time limit per player     [text]
  11202. x       "SO": source (book, journal...) [text]
  11203. x       "GM": game                      [number] (Go=1)
  11204. x       "SZ": board size                [number]
  11205.         "VW": partial view              [point list]
  11206.         "BS": black species             [number] (human=0, modem=-1, computer>0)
  11207.         "WS": white species             [number]
  11208.         "EL": evaluation of computer mv [number]
  11209.         "EX": expected next move        [move, game-specific]
  11210.         "SL": selected points           [point list, game-specific]
  11211. x       "M" : marked points             [point list, game-specific]
  11212. x       "L" : letters on points         [point list, game-specific]
  11213. x       "BR": Black's rank              [text]
  11214. x       "WR": White's rank              [text]
  11215. x       "HA": handicap                  [number]
  11216. x       "KM": komi                      [real]
  11217.         "TB": Black's territory         [point list]
  11218.         "TW": White's territory         [point list]
  11219.         "SC": secure stones             [point list]
  11220.         "RG": region of the board       [point list]
  11221.  
  11222. SHAR_EOF
  11223. fi
  11224. if test -f 'README.IBM'
  11225. then
  11226.     echo shar: "will not over-write existing file 'README.IBM'"
  11227. else
  11228. cat << \SHAR_EOF > 'README.IBM'
  11229.                             The IBM Implementation
  11230.  
  11231. The IBM PC implementation has several features which are absent from the 
  11232. UNIX version.  
  11233.  
  11234.                              Keyboard Extensions
  11235.  
  11236. The cursor keys work in the editor as cursor keys.
  11237.      
  11238. When not in the editor, the operation of the cursor keys is controlled
  11239. by the _ASCARROW environment string:
  11240.  
  11241. _ASCARROW:CURSOR
  11242.     The PC arrow keys move the board cursor.
  11243.  
  11244. _ASCARROW:TREE
  11245.     The PC arrow keys are used for tree traversing,
  11246.     right, left: down tree, up tree (like > and < respectively)
  11247.     up, down:    last, next variation branch
  11248.     pgup, pgdn:  last, next comment
  11249.  
  11250. _ASCARROW:MODE
  11251.     The operation of the PC arrow keys change depending upon the current
  11252.     mgt mode: cursor control in edit mode and tree control in tutor mode  
  11253.  
  11254.  
  11255.                               Display Extensions
  11256.  
  11257. There are three display modes for the IBM mgt:
  11258.     graphics mode, nographics mode, and nocolor mode
  11259.  
  11260. Graphics mode is the default on VGA or EGA systems.  The board is displayed
  11261. using special graphics characters.  The _ASCCHAR
  11262. specification is ignored.  Note that despite its name, "graphics" mode
  11263. does not use graphics mode.  It uses text mode and redefines the font.
  11264.  
  11265. In nographics mode, color is used to obtain good contrast between the board 
  11266. and the stones.  The "black stone" character is used for both white and 
  11267. black stones with different colors.  Similarly, the "black territory" 
  11268. marker is used for both white and black territory.  The "white stone" 
  11269. character and the "white territory" character are ignored.  
  11270.  
  11271. Nocolor mode is the pure text display.  The default uses IBM graphics
  11272. characters for the borders.  
  11273.  
  11274. In both nographics mode and nocolor mode, ascii 3 (a heart symbol) is used 
  11275. the default for the black stone character.
  11276.  
  11277. To force nographics mode, put _ASCNOGRAPH in your MGT environment string.  
  11278. To force nocolor mode, put _ASCNOCOLOR in the environment string.
  11279.  
  11280. In either graphics or nographics modes, the display colors can be set 
  11281. through these environment strings:
  11282.   _ASCBCOL:   black stone color
  11283.   _ASCWCOL:   white stone color
  11284.   _ASCDAME:   dame color
  11285.   _ASCBOARD:  board color
  11286.   _ASCBG:     background
  11287.   _ASCFG:     foreground
  11288.   _ASCMARK:   mark color
  11289.   _ASCLET:    letter color
  11290.   _ASCMENUFG: menu foreground
  11291.   _ASCMENUBG: menu background
  11292.  
  11293. The colors are:
  11294.     0   black         8   dark gray    
  11295.     1   blue          9   light blue   
  11296.     2   green         10  light green  
  11297.     3   cyan          11  light cyan   
  11298.     4   red           12  light red    
  11299.     5   magenta       13  light magenta
  11300.     6   brown         14  yellow       
  11301.     7   light gray    15  white        
  11302.  
  11303. To choose the defaults, you would execute the command:
  11304.  
  11305. set MGT=_ASCBCOL:0 _ASCWCOL:7 _ASCDAME:1 _ASCBOARD:6 _ASCBG:0 _ASCFG:0
  11306.         _ASCMARK:9 _ASCLET:1 _ASCMENUFG:2 _ASCMENUBG:0
  11307.  
  11308. (You don't need to do this if you like the defaults.)
  11309.  
  11310. The _ASCINV environment item will swap the foreground and background, and 
  11311. set the menu background to the background.  This is equivalent to pressing 
  11312. '&' from within mgt.
  11313.  
  11314. If you run mgt in graphics mode with a VGA, color 6 is changed to a brown 
  11315. shade defined by red, green and blue components: 
  11316.         _RED:39 _BLUE:5 _GREEN:33
  11317. This color is meant to be used for the board.  Other colors for color 6 can be 
  11318. selected by specifying different values for red, green and blue in the 
  11319. environment.  The range is 0-63.  
  11320.  
  11321. One person thought _RED:40 _GREEN:30 _BLUE:14 with the background
  11322. inverted looked better than the defaults.
  11323.  
  11324. A CGA user suggests the following combination:
  11325.                  _ASCBOARD:5 _ASCMARK:4 _ASCLET:2   
  11326.  
  11327. Some text, CGA and LCD portable users may want to use the _ASCCHAR
  11328. string to set the Stones and board characters to some of the "special"
  11329. IBM PC characters.  The black and white smilie faces may be better for
  11330. some as the stone characters.  There are single line and double line
  11331. border characters.  A "dot in the middle" character seems to work well
  11332. for the empty points on the board.  These characters may be entered on a
  11333. PC with the following key sequence: 
  11334.  
  11335.               <press and hold Alt>nnn<release Alt>
  11336.  
  11337. The nnn represents a 1 to 3 digit decimal value for the character
  11338. entered on the numeric keypad (the number keys across the top do not
  11339. work.)  The following "special" values seem to work well:
  11340.  
  11341. Black stone:  2
  11342. White stone:  1
  11343. Empty point:  249
  11344. Vert. border: 179 or 186
  11345. Horz. border: 196 or 205
  11346. Upper left:   218 or 201
  11347. Upper right:  191 or 187
  11348. Lower left:   192 or 200
  11349. Lower right:  217 or 188
  11350.  
  11351. The first column is for a single line border and the second column is
  11352. for a double line border.
  11353.  
  11354. The sequence of characters after "_ASCCHAR:" is: black stone (002),
  11355. white stone (001), dame territory ('?'), black territory ('+'), white
  11356. territory ('-'), empty points (249), hosi points ('+'), vertical
  11357. border (186), horizontal border (205), upper left corner (201),
  11358. upper right corner (187), lower left corner (200), lower right corner
  11359. (188).
  11360.  
  11361. In nograph mode the board border characters are ignored, but the stone,
  11362. empty point, hoshi points and territory points may be set. In nocolor
  11363. mode all may be set.
  11364.  
  11365.                                 Mouse Support
  11366.  
  11367. The mouse cursor is an arrow in EGA or VGA modes.  If you don't want the 
  11368. arrow, put _ASCMOUSENORM in the environment variable.  
  11369.  
  11370. The mouse can be used to click on menus, or to click on various parts of 
  11371. the board. 
  11372.  
  11373.  
  11374.  
  11375. The top line contains various mode listings.  
  11376.  
  11377.     help quit stone walk move
  11378.  
  11379. Clicking on help or quit gets help or quits.  
  11380.  
  11381. The third word indicates the mode for placing items on the board.  In stone 
  11382. mode, the left mouse button plays a stone on the board, and the right mouse 
  11383. button sets a stone on the board.  (Equivalent to space, and either z or x 
  11384. respectively.)  The color of the stone set is determined by the player 
  11385. indicator in the lower right corner of the screen.  Clicking on the word 
  11386. "stone" on the top line will change it to "mark".  In this mode, the left 
  11387. mouse button sets or unsets letters on the board and the right mouse button 
  11388. sets and unsets marks.  
  11389.  
  11390. The fourth item on the top line is either "walk" or "branch" to indicate the 
  11391. type of game tree traversal.  In walk mode, clicking with the left button 
  11392. anywhere on the variation window moves down the tree (like the > key).  In 
  11393. branch mode, clicking on a specific variation visits that variation (like 
  11394. pressing capital letters).  In branch mode clicking on blank parts of the 
  11395. variation window does nothing.  In either of these modes, right clicking moves 
  11396. back up the tree.  
  11397.  
  11398. The last mode indicator on the top line identifies the menu choice.  
  11399. There are four different menus you can choose:
  11400.  
  11401. move:  start end var comment
  11402.  
  11403. This is the default menu.  Clicking on start or end moves to the start of the 
  11404. game record or the end of the current variation (like the b and e keys).  
  11405. Left clicking on var or comment goes to the next variation branch or the next 
  11406. comment.  Right clicking on either one goes to the previous variation branch 
  11407. or comment.  
  11408.  
  11409. play: score pass player
  11410.  
  11411. These menu items score the game, pass a move (like p key) or set the player 
  11412. (like the o key), actually changing the Smart-Go record to specify the current 
  11413. player.  
  11414.  
  11415. edit: info cut paste delnode addvar
  11416.  
  11417. These items invoke the info, cut, paste, delete node, and add variation 
  11418. commands.  
  11419.  
  11420. file: save load next prev
  11421.  
  11422. These save the game record, load a file, move to the next, or the previous 
  11423. file.  Some loading commands are available directly from the screen.
  11424. If you loaded mgt with 2 or more files, then left clicking on the filename at 
  11425. the upper right will move to the next file, and right clicking will move to 
  11426. the previous file.  If you specified only one file, then clicking on the 
  11427. filename will load a new file (by name).  
  11428.  
  11429.  
  11430. To scroll the comment window or variation windows with the mouse, click on the 
  11431. '+' or '-' character.  
  11432.  
  11433. To edit a comment, click on the comment window.  To move to a node by number, 
  11434. click on the word "node" above the variation window, and to set the node name, 
  11435. click on the node name above the variation window.
  11436.  
  11437. To select the stone color (like the 't' key) click on the stone that is 
  11438. displayed on the lower right corner of the screen.
  11439.  
  11440. At any (y/n) query, press the left button once to get a 'y' and a second time 
  11441. to get a return.  Pressing the right button twice gets a 'n' and return.  
  11442. Pressing one button and then the other gets either 'y' or 'n', and then a 
  11443. backspace to remove the character that is there.  
  11444.  
  11445. When scoring a game, press right button to score, left button to kill, or
  11446. click on the words at the bottom of the screen to undo, quit, or score.
  11447.  
  11448. Click on the word "tutor" to leave tutor mode, and click on "read" or "edit" 
  11449. to enter tutor mode.  
  11450.  
  11451. Click on the word "short" or "long" to toggle the save format for Smart-Go 
  11452. files between short and long.
  11453.  
  11454. The mode line above the board and the menu line below the board are
  11455. omitted if a mouse is not detect on the PC.  All of the functions
  11456. performed with the mouse have equivalent key commands.
  11457.  
  11458.  
  11459.  
  11460.               Conversion to Short Format
  11461.  
  11462. A batch file called "mgtshort.bat" is included with mgt.  You invoke
  11463. it as
  11464.         mgtshort filespec
  11465. where the filespec is either a single file or single wildcard specification.
  11466. The batch file then invokes mgt on each file, and instructs mgt to save the
  11467. file in short format.  
  11468.  
  11469. This removes any data from the file which mgt did not recognize.  Be careful
  11470. with this program, since it will destroy any files which are not Smart-Go. 
  11471.  
  11472. To install it, you need to edit the file mgtshort.bat to refer to the
  11473. permanent location of the mgtshort.cmd file.  
  11474.  
  11475.  
  11476. SHAR_EOF
  11477. fi
  11478. if test -f 'wrapmgt.6'
  11479. then
  11480.     echo shar: "will not over-write existing file 'wrapmgt.6'"
  11481. else
  11482. cat << \SHAR_EOF > 'wrapmgt.6'
  11483. .TH WRAPMGT 6  "23 November 1992"
  11484. .SH NAME
  11485. wrapmgt - wraps long lines in Smart-Go files to make them safe to post
  11486. or email
  11487. .SH SYNOPSIS
  11488. .B wrapmgt [nn]
  11489. .SH DESCRIPTION
  11490. .B Wrapmgt
  11491. formats Smart-Go files as generated by
  11492. .B mgt
  11493. so that the lines are shorter than nn, the number specified on the
  11494. command line.  The default format width is 79 characters.
  11495. .B Wrapmgt
  11496. reads its input from stdin and writes to stdout.  This means you
  11497. should invoke it using I/O redirection which is done under unix and
  11498. DOS with wrapmgt < infile > outfile.
  11499. .LP
  11500. The files are formatted in such a way that if the files are viewed in
  11501. mgt after being formatted, they will look the same as the original.
  11502. The new line breaks will be visible from
  11503. within the editor, however. 
  11504. .SH AUTHOR
  11505. Adrian Mariano (adrian@u.washington.edu)
  11506.  
  11507. SHAR_EOF
  11508. fi
  11509. if test -f 'wrapmgt.c'
  11510. then
  11511.     echo shar: "will not over-write existing file 'wrapmgt.c'"
  11512. else
  11513. cat << \SHAR_EOF > 'wrapmgt.c'
  11514. #include<stdio.h>
  11515.  
  11516. main(argc, argv)
  11517. int argc;
  11518. char *argv[];
  11519. {
  11520.    char *last, line[100];
  11521.    int cur, limit;
  11522.    int intext, incomment;
  11523.  
  11524.    limit = 79;
  11525.  
  11526.    if (argc > 2) {
  11527.       fprintf(stderr, "Wrong number of arguments.\n\n");
  11528.       exit(1);
  11529.    }
  11530.    if (argc == 2) {
  11531.       limit = atoi(argv[1]);
  11532.       if (!limit) {
  11533.      fprintf(stderr, "Invalid limit\n\n");
  11534.      exit(2);
  11535.       }
  11536.    }
  11537.    last = 0;
  11538.    cur = 0;
  11539.    intext = 0;
  11540.    incomment = 0;
  11541.  
  11542.  
  11543.    do {
  11544.       line[cur] = getchar();
  11545.  
  11546.       /* This next line makes the program aggressively eat up white space  */
  11547.       /* found outside the text sections */
  11548.  
  11549.       if (!intext &&
  11550.       (line[cur] == ' ' || line[cur] == '\n' || line[cur] == '\r'))
  11551.      continue;
  11552.  
  11553.       /* These tests come first because they don't look at the current
  11554.        * character */
  11555.       /* They need to be checked before the flags (next section) are reset */
  11556.  
  11557.       /* line breaks at spaces within comments only */
  11558.       if (incomment && cur && line[cur - 1] == ' ')
  11559.      last = &line[cur];
  11560.  
  11561.       /* line breaks at after ']' if followed by capital letter */
  11562.       if (!intext && cur > 2 && line[cur - 1] >= 'A' && line[cur - 1] <= 'Z' &&
  11563.       line[cur - 2] == ']' && line[cur - 3] != '\\')
  11564.      last = &line[cur - 1];
  11565.  
  11566.       /* These change the various flags */
  11567.  
  11568.       /* Check for start of comment 'C[' */
  11569.       if (cur && line[cur - 1] == 'C' && line[cur] == '[')
  11570.      incomment = intext = 1;
  11571.  
  11572.       /* Check for start of non-comment bracketed section */
  11573.       if (line[cur] == '[' && (cur == 0 || line[cur - 1] != '\\'))
  11574.      intext = 1;
  11575.  
  11576.       /* check for end of bracketed sections ']' */
  11577.       if (intext && line[cur] == ']' && (cur == 0 || line[cur - 1] != '\\'))
  11578.      intext = incomment = 0;
  11579.  
  11580.       /* This test does use current character */
  11581.  
  11582.       /* line breaks at ';' outside of text */
  11583.       if (!intext && line[cur] == ';')
  11584.      last = &line[cur];
  11585.  
  11586.  
  11587.       if (line[cur] == '\n') {
  11588.      line[cur + 1] = 0;
  11589.      fputs(line, stdout);
  11590.      last = line;
  11591.      cur = -1;
  11592.       }
  11593.       cur++;
  11594.       if (cur >= limit && last) {
  11595.      char *loc, *end;
  11596.      for (loc = line; loc < last; loc++)
  11597.         putchar(*loc);
  11598.      putchar('\n');
  11599.      loc = line;
  11600.      line[cur] = 0;
  11601.      strcpy(line, last);
  11602.      last = 0;
  11603.      cur = strlen(line);
  11604.       }
  11605.    } while (!feof(stdin));
  11606.    line[cur] = 0;
  11607.    fputs(line, stdout);
  11608. }
  11609. SHAR_EOF
  11610. fi
  11611. if test -f 'mgt2short'
  11612. then
  11613.     echo shar: "will not over-write existing file 'mgt2short'"
  11614. else
  11615. cat << \SHAR_EOF > 'mgt2short'
  11616. #!/bin/sh
  11617. for f in "$@"
  11618. do
  11619.   mgt -s $f <<EOF >/dev/null
  11620. w*
  11621. qy
  11622.  
  11623. EOF
  11624. done
  11625. SHAR_EOF
  11626. chmod +x 'mgt2short'
  11627. fi
  11628. if test -f 'mgt2short.6'
  11629. then
  11630.     echo shar: "will not over-write existing file 'mgt2short.6'"
  11631. else
  11632. cat << \SHAR_EOF > 'mgt2short.6'
  11633. .TH MGT2SHORT 6  "26 February 1993"
  11634. .SH NAME
  11635. mgt2short - converts Smart-Go files to the short format.
  11636. .SH SYNOPSIS
  11637. .B mgt2short files
  11638. .SH DESCRIPTION
  11639. .B Mgt2short
  11640. converts Smart-Go files to the short format by 
  11641. invoking 
  11642. .B mgt
  11643. on each file and instructing mgt to save the file in the short
  11644. format.  This means that any data in the files which mgt does not
  11645. recognize will be lost.  
  11646. .SH AUTHOR
  11647. Adrian Mariano (adrian@u.washington.edu)
  11648.  
  11649. SHAR_EOF
  11650. fi
  11651. if test -f 'mgtshort.bat'
  11652. then
  11653.     echo shar: "will not over-write existing file 'mgtshort.bat'"
  11654. else
  11655. cat << \SHAR_EOF > 'mgtshort.bat'
  11656. for %%f in (%1) do mgt -s %%f < mgtshort.cmd
  11657. SHAR_EOF
  11658. fi
  11659. if test -f 'mgtshort.cmd'
  11660. then
  11661.     echo shar: "will not over-write existing file 'mgtshort.cmd'"
  11662. else
  11663. cat << \SHAR_EOF > 'mgtshort.cmd'
  11664. w*
  11665. qy
  11666.  
  11667.  
  11668. SHAR_EOF
  11669. fi
  11670. exit 0
  11671. #    End of shell archive
  11672.