home *** CD-ROM | disk | FTP | other *** search
/ Giga Games 1 / Giga Games.iso / net / go / prog / mgt22.sh < prev    next >
Encoding:
Linux/UNIX/POSIX Shell Script  |  1993-06-20  |  246.5 KB  |  10,580 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. # This archive created: Thu May  7 09:55:40 1992
  39. export PATH; PATH=/bin:/usr/bin:$PATH
  40. if test -f 'help.c'
  41. then
  42.     echo shar: "will not over-write existing file 'help.c'"
  43. else
  44. cat << \SHAR_EOF > 'help.c'
  45. /* "mgt" Copyright (c) 1991 Shodan  */
  46.  
  47. /* Short help strings.  Don't make any of these longer than the longest one
  48.  * already present */
  49.  
  50. char *helpStr[] =
  51. {
  52.    "Quit mgt",
  53.    "Move forward",
  54.    "Move backward",
  55.    "Next node",
  56.    "Previous node",
  57.    "End of the current variation",
  58.    "Beginning of file",
  59.    "Next comment",
  60.    "Previous comment",
  61.    "Next variation branch",
  62.    "Last variation branch",
  63.    "Jump to a specific node number",
  64.    "Write Smart-Go file",
  65.    "Set black stone",
  66.    "Set white stone",
  67.    "Make variation",
  68.    "Cut tree into buffer",
  69.    "Add letter",
  70.    "Add mark",
  71.    "Load new file",
  72.    "Paste buffer in",
  73.    "Edit comment",
  74.    "Delete current node",
  75.    "Name the current node",
  76.    "Score the game",
  77.    "Pass move",
  78.    "Other player's turn (permanent)",
  79.    "Toggle stone",
  80.    "Reverse through files",
  81.    "Forward through files",
  82.    "Redraw screen",
  83.    "Toggle save format",
  84.    "Toggle tutor mode",
  85.    "Save screen image",
  86.    "Show game info",
  87.    "Make a move",
  88.    "Cursor down left",
  89.    "Cursor down",
  90.    "Cursor down right",
  91.    "Cursor left",
  92.    "Cursor right",
  93.    "Cursor up left",
  94.    "Cursor up",
  95.    "Cursor up right",
  96.    "___last command marker___"};
  97. SHAR_EOF
  98. fi
  99. if test -f 'asc_ibm.inc'
  100. then
  101.     echo shar: "will not over-write existing file 'asc_ibm.inc'"
  102. else
  103. cat << \SHAR_EOF > 'asc_ibm.inc'
  104. /* "mgt" Copyright (c) 1991 Shodan  */
  105.  
  106.  
  107. char chars[] = "\3O?+-\372.\263\304\332\277\300\331";
  108. char graphchar[] = "\16O?\17.\305\307\335     ";
  109.  
  110. int graphicalCursor = 1;
  111. int graphics = 1;
  112. int usecolor = 1;
  113.  
  114. int boardcolor = 6;
  115. int blackstone = 0;
  116. int damecolor = 1;
  117. int whitestone = 7;
  118. int background = 0;
  119. int foreground = 7;
  120. int markcolor = 9;
  121. int lettercolor = 1;
  122. int menufg = 2;
  123. int menubg = 0;
  124.  
  125. int branchmode = 0;
  126. int stonemode = 1;
  127.  
  128. int bred = /* 0x3f; 63 44  40; */ 39;
  129. int bblue = /* 0x16; 22 15  14; */ 5;
  130. int bgreen = /* 0x2e; 46 32  30;  */ 33;
  131.  
  132. int menu = 0;
  133.  
  134. char *stoneModeName[] =
  135. {"mark", "stone"};
  136. char *branchModeName[] =
  137. {"walk", "branch"};
  138. char *menumode[] =
  139. {"move", "play", "edit", "files"};
  140.  
  141. #define MENUITEMS 4
  142.  
  143.  
  144. /* 6789012345678901234567890123456789012345 */
  145. char *menulines[] =
  146. {"    start  end  var  comment    ",
  147.  "       score  pass  player       ",
  148.  "info  cut  paste  delnode  addvar",
  149.  "     save  load  next  prev      "};
  150.  
  151.  
  152. struct {
  153.    char bottom, top;
  154. }  menubounds[4][5] = {
  155.    {{
  156.      -1, -1
  157.    }, {
  158.       10, 14
  159.    }, {
  160.       17, 19
  161.    }, {
  162.       22, 24
  163.    }, {
  164.       27, 33
  165.    }
  166.    },
  167.    {{
  168.      -1, -1
  169.    }, {
  170.       13, 17
  171.    }, {
  172.       20, 23
  173.    }, {
  174.       26, 31
  175.    }, {
  176.       -1, -1
  177.    }
  178.    },
  179.    {{
  180.      6, 9
  181.    }, {
  182.       12, 14
  183.    }, {
  184.       17, 21
  185.    }, {
  186.       24, 30
  187.    }, {
  188.       33, 38
  189.    }
  190.    },
  191.    {{
  192.      -1, -1
  193.    }, {
  194.       11, 14
  195.    }, {
  196.       17, 20
  197.    }, {
  198.       23, 26
  199.    }, {
  200.       29, 32
  201.    }
  202.    }
  203. };
  204.  
  205.  
  206. #include <conio.h>
  207. #include <dos.h>
  208. #include "mou.h"
  209.  
  210. #define move(Y, X) gotoxy((X)+1, (Y)+1)
  211. #define mvaddstr(Y, X, STRING) gotoxy((X)+1, (Y)+1), cputs(STRING)
  212. #define mvprintw(Y, X, STRING) gotoxy((X)+1, (Y)+1), cputs(STRING)
  213. #define mvaddch(Y, X, CHAR) gotoxy((X)+1, (Y)+1), putch(CHAR)
  214. #define addch(CHAR) putch(CHAR)
  215. #define printw cprintf
  216. #define clrtoeol() clreol()
  217. #define clear() clrscr()
  218. #define refresh()
  219. #define wrefresh(win)
  220. #define wmove(win,y,x) move(y,x)
  221. #define waddch(win,c) addch(c)
  222. #define mvwaddch(win,y,x,c) mvaddch(y,x,c)
  223. #define waddstr(win,c) cputs(c)
  224. #define wclreol(win) clreol()
  225. #define closewin() window(1,1,80,25)
  226. #define xpos(w) (wherex()-1)
  227. #define ypos(w) (wherey()-1)
  228. #define WINDOW char
  229. #define openwin() win=0,window(WINLEFT+1,WINTOP+1,WINRIGHT+1,WINBOT+2),clear()
  230. #define fixcursor() if (ypos(win)>WINHIGH) wmove(win,WINHIGH,WINWIDE);
  231. #define preserveScreen() char screen[160][25];gettext(1,1,80,25,&screen)
  232. #define restoreScreen() puttext(1,1,80,25,&screen)
  233. #define restoreRegion(x1,y1,dx,dy) puttext(x1+1,y1+1,x1+1+dx,y1+dy,savearea)
  234. #define saveRegion(x1,y1,dx,dy)    gettext(x1+1,y1+1,x1+1+dx,y1+dy,savearea)
  235. #define normalize(c) (c)
  236. #define set_inverse()
  237. #define unset_inverse()
  238.  
  239. static unsigned char far *getfont()
  240. {
  241.    struct REGPACK regs;
  242.    regs.r_ax = 0x1130;
  243.    regs.r_bx = 0x0600;
  244.    intr(0x10, ®s);
  245.    return (unsigned char far *) MK_FP(regs.r_es, regs.r_bp);
  246. }
  247.  
  248.  
  249. static void setfont(unsigned char far * newfont)
  250. {
  251.    struct REGPACK regs;
  252.    regs.r_cx = 256;
  253.    regs.r_bx = 0x1000;
  254.    regs.r_dx = 0;
  255.    regs.r_ax = 0x1100;
  256.    regs.r_es = FP_SEG(newfont);
  257.    regs.r_bp = FP_OFF(newfont);
  258.    intr(0x10, ®s);
  259. }
  260.  
  261. static void endwin()
  262. {
  263.    closewin();
  264.    setfont(getfont());
  265.    normvideo();
  266.    MOUdeinit();
  267.    clrscr();
  268. }
  269.  
  270.  
  271. static void setcolor(bg, fg)
  272. int bg, fg;
  273.  
  274. {
  275.    if (usecolor)
  276.       textattr((bg << 4) + fg);
  277. }
  278.  
  279.  
  280. static void drawPrisoners()
  281. {
  282.    extern int prisoners[];
  283.    extern int ispl;
  284.    char a, b, c, d;
  285.    if (curPlayer == t_Black) {
  286.       a = ispl ? '\20' : '>';
  287.       b = ispl ? '\21' : '<';
  288.       c = d = ' ';
  289.    } else {
  290.       a = b = ' ';
  291.       c = ispl ? '\20' : '>';
  292.       d = ispl ? '\21' : '<';
  293.    }
  294.    move(23, 49);
  295.    if (usecolor) {
  296.       setcolor(boardcolor, blackstone);
  297.       printw(" %c %c: %d %c    ", a, chars[CHAR_BLACK], prisoners[0], b);
  298.       setcolor(boardcolor, whitestone);
  299.       printw("%c %c: %d %c ", c, chars[CHAR_BLACK], prisoners[1], d);
  300.       setcolor(background, foreground);
  301.    } else
  302.       printw(" %c %c: %d %c    %c %c: %d %c ", a, chars[(int)
  303.                           CHAR_BLACK], prisoners[0], b, c,
  304.          chars[(int) CHAR_WHITE], prisoners[1], d);
  305.    clrtoeol();
  306. }
  307.  
  308.  
  309.  
  310. static char getKey()
  311. {
  312.    MOUINFOREC m;
  313.    for (;
  314.     ;
  315.       ) {
  316.       if (MOUcheck()) {
  317.      MOUget(&m);
  318.      if (m.buttonstat & (LEFTBPRESS | RIGHTBPRESS))
  319.         return ' ';
  320.       } if (kbhit())
  321.      return getch();
  322.    }
  323. }
  324.  
  325.  
  326. int iskey()
  327. {
  328.    _AH = 1;
  329.    geninterrupt(0x16);
  330.    return (!(_FLAGS & 64));
  331. }
  332.  
  333. char getKeyEdit()
  334. {
  335.    MOUINFOREC m;
  336.    int key;
  337.  
  338.    for (;
  339.     ;
  340.       ) {
  341.       if (MOUcheck())
  342.      MOUget(&m);
  343.       if (iskey()) {
  344.      _AX = 0;
  345.      geninterrupt(0x16);
  346.      if (_AL)
  347.         return _AL;
  348.      switch (_AH) {
  349.         case 77:
  350.            return CRIGHT;
  351.         case 75:
  352.            return CLEFT;
  353.         case 80:
  354.            return DOWN;
  355.         case 72:
  356.            return CUP;
  357.         case 79:
  358.            return CEND;
  359.         case 71:
  360.            return CHOME;
  361.         case 82:
  362.            return 'I' - 64;
  363.         case 83:
  364.            return CTRLD;
  365.         default:
  366.            return 0;
  367.      }
  368.       }
  369.    }
  370. }
  371.  
  372.  
  373.  
  374. char getKeyLine()
  375. {
  376.    static lastmouse = 0;
  377.    MOUINFOREC m;
  378.    for (;
  379.     ;
  380.       ) {
  381.       if (MOUcheck()) {
  382.      MOUget(&m);
  383.      if (m.buttonstat & LEFTBPRESS) {
  384.         if (lastmouse == 1) {
  385.            lastmouse = 0;
  386.            return '\r';
  387.         }
  388.         if (!lastmouse) {
  389.            lastmouse = 1;
  390.            return 'y';
  391.         }
  392.         lastmouse = 0;
  393.         return '\b';
  394.      }
  395.      if (m.buttonstat & RIGHTBPRESS) {
  396.         if (lastmouse == 2) {
  397.            lastmouse = 0;
  398.            return '\r';
  399.         }
  400.         if (!lastmouse) {
  401.            lastmouse = 2;
  402.            return 'n';
  403.         }
  404.         lastmouse = 0;
  405.         return '\b';
  406.      }
  407.       }
  408.       if (kbhit()) {
  409.      lastmouse = 0;
  410.      return getch();
  411.       }
  412.    }
  413. }
  414.  
  415.  
  416. static char scoring = 0;
  417.  
  418.  
  419. void printmodes()
  420. {
  421.    setcolor(menubg, menufg);
  422.    move(0, 4);
  423.    printw("  help   quit %7s%7s%7s", stoneModeName[stonemode], branchModeName[branchmode], menumode[menu]);
  424.    setcolor(background, foreground);
  425.    setCursor(xcur, ycur);
  426. }
  427.  
  428.  
  429. int getmenu(cx)
  430. int cx;
  431. {
  432.    int i;
  433.    for (i = 0;
  434.     i < 5;
  435.     i++)
  436.       if (cx <= menubounds[menu][i].top && cx >= menubounds[menu][i].bottom)
  437.      return (menu << 4) + i;
  438.    return -1;
  439. }
  440.  
  441.  
  442. int checkLeftButton(cx, cy)
  443. int cx, cy;
  444. {
  445.    if (cy == COMMAND_Y && cx >= COMMAND_X) {
  446.       cx -= COMMAND_X;
  447.       if (cx < 10)
  448.      return '?';
  449.       if (cx >= 15 && cx < 20)
  450.      return keys[C_TUTORSWAP];
  451.       if (cx >= 24 && cx < 29)
  452.      return keys[C_SAVESHORT];
  453.       cx += COMMAND_X;
  454.    }
  455.    if (cy >= COMMENT_Y && cy < COMMENT_Y + COMMENT_HIGH && cx >= COMMENT_X)
  456.       return keys[C_EDCOMMENT];
  457.    if ((cy == 22) && usecolor) {
  458.       switch (getmenu(cx)) {
  459.      case 0x01:
  460.         return keys[C_BEGINNING];
  461.      case 0x02:
  462.         return keys[C_END];
  463.      case 0x03:
  464.         return keys[C_DOWNFORK];
  465.      case 0x04:
  466.         return keys[C_SEARCHCOMMENT];
  467.  
  468.      case 0x11:
  469.         return keys[C_SCORE];
  470.  
  471.      case 0x12:
  472.         return keys[C_PASSMOVE];
  473.  
  474.      case 0x13:
  475.         return keys[C_TOPLAY];
  476.  
  477.  
  478.  
  479.      case 0x20:
  480.         return keys[C_INFO];
  481.      case 0x21:
  482.         return keys[C_TREECUT];
  483.      case 0x22:
  484.         return keys[C_PASTE];
  485.      case 0x23:
  486.         return keys[C_DELNODE];
  487.      case 0x24:
  488.         return keys[C_ADDVAR];
  489.  
  490.      case 0x31:
  491.         return keys[C_WRITE];
  492.      case 0x32:
  493.         return keys[C_LOAD];
  494.      case 0x33:
  495.         return keys[C_NEXTFILE];
  496.      case 0x34:
  497.         return keys[C_BACKFILE];
  498.       }
  499.    }
  500.    if (cy == STATUS_Y && cx >= STATUS_X) {
  501.       return keys[filecount ? C_NEXTFILE : C_LOAD];
  502.    }
  503.    if ((cy == 0) && usecolor) {
  504.       MOUhide();
  505.       switch ((cx - 4) / 7) {
  506.      case 0:
  507.         MOUshow();
  508.         return '?';
  509.      case 1:
  510.         MOUshow();
  511.         return keys[C_QUIT];
  512.      case 2:
  513.         stonemode = !stonemode;
  514.         printmodes();
  515.         break;
  516.      case 3:
  517.         branchmode = !branchmode;
  518.         printmodes();
  519.         break;
  520.      case 4:
  521.         menu++;
  522.         menu %= MENUITEMS;
  523.         printmodes();
  524.         setcolor(menubg, menufg);
  525.         mvaddstr(22, 6, menulines[menu]);
  526.         setcolor(background, foreground);
  527.         setCursor(xcur, ycur);
  528.         break;
  529.       }
  530.       MOUshow();
  531.    }
  532.    if (scoring && cy == 23 && cx <= 39) {
  533.       if (cx <= 12)
  534.      return '\r';
  535.       if (cx <= 24)
  536.      return 0;
  537.       else if (cx <= 32)
  538.      return 'u';
  539.       else if (cx <= 39)
  540.      return 'q';
  541.    }
  542.    if (!((cx - LEFT) & 1) && inRange(cy - TOP, (cx - LEFT) / 2)) {
  543.       xcur = (cx - LEFT) / 2;
  544.       ycur = (cy - TOP);
  545.       return stonemode || scoring ? 32 : keys[C_ADDLETTER];
  546.    }
  547.    if ((cy == 23) && ((cx >= 48 && cx <= 54 && curPlayer != t_Black) ||
  548.               (cx >= 59 && cx <= 67 && curPlayer == t_Black)))
  549.       return keys[C_TOGGLESTONE];
  550.    if (cx == COMMENT_X - 1 && cy == COMMENT_Y)
  551.       return keys[C_COMMENTSCROLLUP];
  552.    if (cx == TREE_X - 1 && cy == TREE_Y + 1)
  553.       return keys[C_TREESCROLLUP];
  554.    if (cx == TREE_X - 1 && cy == TREE_Y + TREEHIGH - 1)
  555.       return keys[C_TREESCROLLDOWN];
  556.    if (cx == COMMENT_X - 1 && cy == COMMENT_Y + COMMENT_HIGH - 1)
  557.       return keys[C_COMMENTSCROLLDOWN];
  558.    if (cx >= TREE_X && cy > TREE_Y && cy < TREE_Y + TREEHIGH)
  559.       return branchmode ? 'A' + treeLine + cy - TREE_Y - 1 : keys[C_WALKDOWN];
  560.    if (cy == TREE_Y) {
  561.       if (cx > TREE_X + 10)
  562.      return keys[C_ADDNAME];
  563.       if (cx > TREE_X + 1)
  564.      return keys[C_GOTO];
  565.    }
  566.    return 0;
  567. }
  568.  
  569.  
  570.  
  571.  
  572. int checkRightButton(cx, cy)
  573. int cx, cy;
  574. {
  575.  
  576.    if (scoring)
  577.       return '\r';
  578.    if ((cy == 22) && usecolor) {
  579.       if (getmenu(cx) == 3)
  580.      return keys[C_UPFORK];
  581.       if (getmenu(cx) == 4)
  582.      return keys[C_SEARCHBACKCOMMENT];
  583.    }
  584.    if ((!((cx - LEFT) & 1))
  585.        && inRange(cy - TOP, (cx - LEFT) / 2)) {
  586.       xcur = (cx - LEFT) / 2;
  587.       ycur = (cy - TOP);
  588.       return keys[stonemode ?
  589.           (curPlayer == t_Black ? C_ADDBLACK : C_ADDWHITE)
  590.           :
  591.           C_ADDMARK];
  592.    }
  593.    if (cy == STATUS_Y && cx >= STATUS_X && filecount) {
  594.       return keys[C_BACKFILE];
  595.    }
  596.    if (cx >= TREE_X && cy > TREE_Y && cy < TREE_Y + TREEHIGH)
  597.       return keys[branchmode ? C_UP : C_WALKUP];
  598.    return 0;
  599. }
  600.  
  601.  
  602.  
  603.  
  604. char getKeyIdle()
  605. {
  606.    int key;
  607.    MOUINFOREC m;
  608.  
  609.    MOUshow();
  610.    for (;;) {
  611.       if (MOUcheck()) {
  612.      MOUget(&m);
  613.      if ((m.buttonstat & LEFTBPRESS) && (key = checkLeftButton(m.cx, m.cy))) {
  614.         MOUhide();
  615.         return key;
  616.      }
  617.      if ((m.buttonstat & RIGHTBPRESS) && (key = checkRightButton(m.cx, m.cy))) {
  618.         MOUhide();
  619.         return key;
  620.      }
  621.       }
  622.       if (kbhit()) {
  623.      MOUhide();
  624.      return getch();
  625.       }
  626.    }
  627. }
  628.  
  629.  
  630.  
  631. char getKeyScore()
  632. {
  633.    char temp;
  634.    scoring = 1;
  635.    temp = getKeyIdle();
  636.    scoring = 0;
  637.    return temp;
  638. }
  639.  
  640.  
  641.  
  642.  
  643. static void initAscii()
  644. {
  645.  
  646.    char stone[] =
  647.    {0x00, 0x00, 0x00, 0x7E, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7E, 0x00, 0x00, 0x00};
  648.    char terr[] =
  649.    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x7e, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  650.    char hoshi[] =
  651.    {0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0xFF, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18};
  652.  
  653.    unsigned char *dest, far * font;
  654.    int i, j, k;
  655.    unsigned char myfont[256][16];
  656.    extern vgapresent;
  657.  
  658.    textmode(C80);
  659.  
  660.    if (graphics && isegavga()) {
  661.       _AX = 0x1003;
  662.       _BX = 0;
  663.       geninterrupt(0x10);    /* enable high intensity background */
  664.  
  665.       if (vgapresent) {
  666.      _AX = 0x1010;
  667.      _BX = 0x0014;
  668.      _CH = bgreen;
  669.      _CL = bblue;
  670.      _DH = bred;
  671.  
  672.      geninterrupt(0x10);    /* change color 6 */
  673.       }
  674.       font = getfont();
  675.  
  676.       for (dest = (char *) myfont, k = 0; k < 16 * 256; k++, dest++, font++)
  677.      *dest = *font;
  678.       for (k = 0; k < 16; k++) {
  679.      myfont[14][k] = stone[k];
  680.      myfont[15][k] = terr[k];
  681.      myfont[199][k] = hoshi[k];
  682.       }
  683.       setfont((unsigned char far *) myfont);
  684.       strcpy(chars, graphchar);
  685.       usecolor = 1;
  686.    } else
  687.       graphics = 0;
  688.    if ((!graphics) && usecolor)
  689.       strcpy(chars + CHAR_VERT, graphchar + CHAR_VERT);
  690.  
  691.    MOUinit();
  692.    MOUhide();
  693.    fixkeys();
  694.  
  695. }
  696.  
  697.  
  698.  
  699. static void plotMarkAscii(b, i, j)
  700. pBoard b;
  701. int i, j;
  702. {
  703.    void plotPieceAscii();
  704.    int sc;
  705.  
  706.    if (usecolor) {
  707.       sc = boardcolor;
  708.       boardcolor = markcolor;
  709.    } else
  710.       textattr(inverseFlag ? 0x07 : 0x70);
  711.    plotPieceAscii(b, i, j);
  712.    if (usecolor) {
  713.       boardcolor = sc;
  714.    } else
  715.       textattr(inverseFlag ? 0x70 : 0x07);
  716. }
  717.  
  718.  
  719.  
  720. static command specialKeysIdle(c)
  721. char c;
  722. {
  723.    if (!c) {
  724.       c = getKey();
  725.       switch (c) {
  726.      case 77:
  727.         return C_DOWN;
  728.      case 75:
  729.         return C_UP;
  730.      case 80:
  731.         return C_DOWNFORK;
  732.      case 72:
  733.         return C_UPFORK;
  734.      case 81:
  735.         return C_SEARCHCOMMENT;
  736.      case 73:
  737.         return C_SEARCHBACKCOMMENT;
  738.      default:
  739.         return (command) 0;
  740.       }
  741.    } else
  742.       return (command) 0;
  743. }
  744.  
  745.  
  746.  
  747.  
  748. static void drawPiece(i, j, c)
  749. int i, j;
  750. char c;
  751. {
  752.    move(TOP + j, LEFT + 2 * i);
  753.    setcolor(boardcolor, blackstone);
  754.  
  755.    if (c == chars[(int) CHAR_NOTHING]) {
  756.       if (graphics) {
  757.      if (i == 0) {
  758.         if (j == boardsize - 1)
  759.            c = '\300';
  760.         else if (j == 0)
  761.            c = '\332';
  762.         else
  763.            c = '\303';
  764.      } else if (i == boardsize - 1) {
  765.         if (j == boardsize - 1)
  766.            c = '\331';
  767.         else if (j == 0)
  768.            c = '\277';
  769.         else
  770.            c = '\264';
  771.      } else if (j == 0)
  772.         c = '\302';
  773.      else if (j == boardsize - 1)
  774.         c = '\301';
  775.       }
  776.    }
  777.    if (usecolor) {
  778.       if (c == chars[(int) CHAR_WHITE]) {
  779.      c = chars[(int) CHAR_BLACK];
  780.      setcolor(boardcolor, whitestone);
  781.       }
  782.       if (c == chars[(int) CHAR_WHITETERR]) {
  783.      c = chars[(int) CHAR_BLACKTERR];
  784.      setcolor(boardcolor, whitestone);
  785.       }
  786.       if (c == chars[(int) CHAR_DAME]) {
  787.      setcolor(boardcolor, damecolor);
  788.       }
  789.       if (c >= 'a' && c <= 'z')
  790.      setcolor(boardcolor, lettercolor);
  791.    }
  792.    addch(c);
  793.    setcolor(background, foreground);
  794. }
  795.  
  796.  
  797. static void initBoardAscii()
  798. {
  799.    int i, j;
  800.  
  801.    if (!usecolor) {
  802.       if (inverseFlag)
  803.      textattr(0x70);
  804.       else
  805.      textattr(0x07);
  806.    }
  807.    if (inverseFlag && usecolor) {
  808.       inverseFlag = foreground;
  809.       foreground = background;
  810.       background = inverseFlag;
  811.       menubg = background;
  812.       inverseFlag = 0;
  813.    }
  814.    setcolor(background, foreground);
  815.    clrscr();
  816.    if (mouseinstalled & usecolor) {
  817.       printmodes();
  818.       setcolor(menubg, menufg);
  819.       mvaddstr(22, 6, menulines[menu]);
  820.       setcolor(background, foreground);
  821.    }
  822.    if (usecolor) {
  823.       setcolor(boardcolor, blackstone);
  824.       for (i = LEFT + 1; i < LEFT + boardsize * 2 - 2; i += 2)
  825.      for (j = TOP; j < TOP + boardsize; j++)
  826.         mvaddch(j, i, graphics ? '\304' : ' ');
  827.    }
  828.    for (i = boardsize; i--;) {
  829.  
  830.       /* left */
  831.       set_inverse();
  832.       move(TOP + i, LEFT - 1);
  833.       setcolor(boardcolor, background);
  834.       addch(chars[(int) CHAR_VERT]);
  835.  
  836.       setcolor(background, boardcolor);
  837.       /* top */
  838.       move(TOP - 1, LEFT + i * 2 - 1);
  839.       printw("%c%c", chars[(int) CHAR_HORIZ], chars[(int) CHAR_HORIZ]);
  840.  
  841.       /* bottom */
  842.       move(TOP + boardsize, LEFT + i * 2 - 1);
  843.       printw("%c%c", chars[(int) CHAR_HORIZ], chars[(int) CHAR_HORIZ]);
  844.  
  845.       /* right */
  846.       move(TOP + i, LEFT + boardsize * 2 - 1);
  847.       setcolor(background, boardcolor);
  848.       addch(chars[(int) CHAR_VERT]);
  849.       setcolor(background, foreground);
  850.  
  851.       unset_inverse();
  852.  
  853.       /* right */
  854.       printw("%-2d%c", boardsize - i, '\263');
  855.  
  856.       /* left */
  857.       move(TOP + i, LEFT - 3);
  858.       printw("%2d", boardsize - i);
  859.  
  860.  
  861.       /* top */
  862.       move(TOP - 2 + usecolor, LEFT + i * 2);
  863.       addch(xAxisChars[i]);
  864.  
  865.       /* bottom */
  866.       move(TOP + boardsize + 1 - usecolor, LEFT + i * 2);
  867.       addch(xAxisChars[i]);
  868.  
  869.       for (j = boardsize; j--;)
  870.      drawPiece(i, j, boardPiece(i, j));
  871.    }
  872.    set_inverse();
  873.    move(TOP - 1, LEFT - 1);
  874.    addch(chars[(int) CHAR_UPLEFT]);
  875.    move(TOP + boardsize, LEFT - 1);
  876.    addch(chars[(int) CHAR_DOWNLEFT]);
  877.    move(TOP - 1, LEFT + boardsize * 2 - 1);
  878.    addch(chars[(int) CHAR_UPRIGHT]);
  879.    move(TOP + boardsize, LEFT + boardsize * 2 - 1);
  880.    addch(chars[(int) CHAR_DOWNRIGHT]);
  881.    unset_inverse();
  882.    mvaddstr(COMMAND_Y, COMMAND_X, helpMsg);
  883.    printstatus(name_buf);
  884. }
  885.  
  886. static char *mouseHelp[] =
  887. {
  888.    "                                 Mouse Commands",
  889.    "Click on           (left)=left click         (right)=right click",
  890.    " board        \"stone\" mode: makes a move (left)  sets stone (right)",
  891.    "              \"mark\" mode: places letter (left)  places mark (right)",
  892.    "",
  893.    " \"Node #\"     Goes to node by number",
  894.    " node name    Sets node name",
  895.    " comment      Edits the comment",
  896.    " \"+\" or \"-\"   (next to comment or variations) scroll the comment/variations",
  897.    " filename     Next (left) or previous (right) file, or load file.",
  898.    " variation    Go to that variation (left) back up (right)",
  899.    " long/short   Toggles save file format",
  900.    " read/edit/tutor Toggles tutor mode",
  901.    "",
  902. "When scoring a game, right button scores, left buttons kills, and clicking ",
  903.    "on words at the bottom of the screen executes whatever function.",
  904.    "",
  905.    "Mouse clicks will remove error messages.",
  906.    "At a (y/n) prompt, double click left to respond yes, double click right for no",
  907.    "",
  908.    "Menus above and below the board provide other functions",
  909.    "",
  910.    "                         Hit a key (or click) to continue"};
  911.  
  912. static char *ibmHelp[] =
  913. {"               Cursor Keys",
  914.  "",
  915.  "To move the cursor on the board",
  916.  "you must use the number keys",
  917.  "(have num lock on)",
  918.  "",
  919.  "The cursor keys have the following functions:",
  920.  "",
  921.  "right  down tree like ",
  922.  "left   up tree like ",
  923.  "up     previous variation branch",
  924.  "down   next variation branch",
  925.  "pgup   last comment",
  926.  "pgdn   next comment",
  927.  "",
  928.  "         press a key"
  929. };
  930.  
  931.  
  932.  
  933. static void specialHelp()
  934. {
  935.    int i;
  936.    char ch;
  937.    clrscr();
  938.    for (i = 0; i < sizeof(ibmHelp) / sizeof(char *); i++) {
  939.       move(i + 5, 14);
  940.       cputs(ibmHelp[i]);
  941.       if (i == 8)
  942.      addch(keys[C_DOWN]);
  943.       if (i == 9)
  944.      addch(keys[C_UP]);
  945.    }
  946.    ch = getKey();
  947.    if (ch != '\n' && ch != '\r' && mouseinstalled) {
  948.       clrscr();
  949.       for (i = 0; i < sizeof(mouseHelp) / sizeof(char *); i++) {
  950.      move(i, 0);
  951.      if (i == 4) {
  952.         printw(" ");
  953.         if (usecolor)
  954.            setcolor(boardcolor, blackstone);
  955.         printw(" %c: ?? ", chars[CHAR_BLACK]);
  956.         if (usecolor)
  957.            setcolor(background, foreground);
  958.         printw("      selects black stones, ");
  959.         if (usecolor) {
  960.            setcolor(boardcolor, whitestone);
  961.            printw(" %c: ?? ", chars[CHAR_BLACK]);
  962.            setcolor(background, foreground);
  963.         } else
  964.            printw(" %c: ?? ", chars[CHAR_WHITE]);
  965.         printw(" selects white stones.");
  966.  
  967.  
  968.      }
  969.      cputs(mouseHelp[i]);
  970.       }
  971.       getKey();
  972.       clrscr();
  973.       printmodes();
  974.  
  975.  
  976.       mvaddstr(1, 20, " \263      \263      \300\304 indicates menu chosen.  Click here to");
  977.       mvaddstr(2, 20, " \263      \263         switch to a different menu.");
  978.       mvaddstr(3, 20, " \263      \300\304 type of movement through game tree (see previous");
  979.       move(4, 20);
  980.       printw(" \263         screen).  Branch for movement like %c and %c, ", keys[C_DOWN], keys[C_UP]);
  981.       move(5, 20);
  982.       printw(" \263         walk for movement like %c and %c. ", keys[C_WALKDOWN], keys[C_WALKUP]);
  983.       mvaddstr(6, 20, " \300\304 Mouse button on the board sets stones or sets marks.");
  984.       mvaddstr(7, 20, "    Click here to toggle.");
  985.  
  986.       setcolor(menubg, menufg);
  987.       mvaddstr(9, 0, menulines[0]);
  988.       setcolor(background, foreground);
  989.       mvaddstr(10, 2, "Click on start or end to go to start of file or end of current variation.");
  990.       mvaddstr(11, 2, "Left click on var or comment to go to next variation branch or comment.");
  991.       mvaddstr(12, 2, "Right click to go to last variation branch or comment.");
  992.       setcolor(menubg, menufg);
  993.       mvaddstr(13, 0, menulines[1]);
  994.       setcolor(background, foreground);
  995.  
  996.       mvaddstr(14, 2, "Click on score to score, pass to play a pass move, and player to toggle the");
  997.       mvaddstr(15, 2, "current player with an item in the game tree.");
  998.  
  999.       setcolor(menubg, menufg);
  1000.       mvaddstr(16, 0, menulines[2]);
  1001.       setcolor(background, foreground);
  1002.  
  1003.       mvaddstr(17, 2, "Click on info to get info, cut or paste to cut and paste, delnode to delete a");
  1004.       mvaddstr(18, 2, "node or addvar to add a variation.");
  1005.  
  1006.       setcolor(menubg, menufg);
  1007.       mvaddstr(19, 0, menulines[3]);
  1008.       setcolor(background, foreground);
  1009.  
  1010.       mvaddstr(20, 2, "Click on save to save the game record, load to load a new file, next to go to");
  1011.       mvaddstr(21, 2, "the next file or prev to go to the previous file.");
  1012.  
  1013.       mvaddstr(23, 24, "Hit a key or click to continue.");
  1014.       getKey();
  1015.  
  1016.    }
  1017. }
  1018. SHAR_EOF
  1019. fi
  1020. if test -f 'asc_unix.inc'
  1021. then
  1022.     echo shar: "will not over-write existing file 'asc_unix.inc'"
  1023. else
  1024. cat << \SHAR_EOF > 'asc_unix.inc'
  1025. /* "mgt" Copyright (c) 1991 Shodan  */
  1026.  
  1027.  
  1028. #include <curses.h>
  1029.  
  1030. char chars[] = "@O=+-.+|-++++";
  1031.  
  1032. #define openwin() win=subwin(stdscr,WINHIGH+1,WINWIDE+1,WINTOP,WINLEFT),wclear(win)
  1033. #define fixcursor()
  1034. #define specialKeysEdit(c) (c)
  1035. #define closewin() delwin(win)
  1036. #define getKey getch
  1037. #define getKeyIdle getch
  1038. #define getKeyLine getch
  1039. #define getKeyScore getch
  1040. #define getKeyEdit getch
  1041. #define specialHelp()
  1042. #define preserveScreen() WINDOW *wi;wi=newwin(0,0,0,0);overwrite(stdscr,wi)
  1043. #define restoreScreen() overwrite(wi,stdscr);refresh();delwin(wi)
  1044. #define saveRegion(x1,y1,dx,dy) { WINDOW *ww; ww=subwin(stdscr,dy,dx,y1,x1);wi=newwin(dy,dx,y1,x1);overwrite(ww,wi);delwin(ww);}
  1045. #define restoreRegion(x1,y1,dx,dy) overwrite(wi,stdscr);refresh();delwin(wi)
  1046. #define dopris() printw(" %c %c: %d %c    %c %c: %d %c ", a, chars[(int)\
  1047.           CHAR_BLACK], prisoners[0], b, c, \
  1048.       chars[(int) CHAR_WHITE], prisoners[1], d)
  1049.  
  1050.  
  1051. static void drawPrisoners()
  1052. {
  1053.    extern int prisoners[];
  1054.    extern int ispl;
  1055.    char a, b, c, d;
  1056.    if (curPlayer == t_Black) {
  1057.       a = ispl ? '}' : '>';
  1058.       b = ispl ? '{' : '<';
  1059.       c = d = ' ';
  1060.    } else {
  1061.       a = b = ' ';
  1062.       c = ispl ? '}' : '>';
  1063.       d = ispl ? '{' : '<';
  1064.    }
  1065.    move(23, 50);
  1066.    printw("%c %c: %d %c    %c %c: %d %c ", a, chars[(int)
  1067.                           CHAR_BLACK], prisoners[0], b, c,
  1068.       chars[(int) CHAR_WHITE], prisoners[1], d);
  1069.    clrtoeol();
  1070. }
  1071.  
  1072.  
  1073.  
  1074. static void initAscii()
  1075. {
  1076.    fixkeys();
  1077.    initscr();
  1078.    noecho();
  1079.    crmode();
  1080. }
  1081.  
  1082.  
  1083.  
  1084. static void plotMarkAscii(b, i, j)
  1085. pBoard b;
  1086. int i, j;
  1087. {
  1088.    void drawPiece();
  1089.    piece p;
  1090.    p = boardGet(b, i, j);
  1091.    inverseFlag = !inverseFlag;
  1092.  
  1093.    drawPiece(i, j, (p == P_NOTHING ? boardPiece(i, j) :
  1094.             (p == P_BLACK ? chars[(int) CHAR_BLACK] :
  1095.              chars[(int) CHAR_WHITE])));
  1096.    inverseFlag = !inverseFlag;
  1097. }
  1098.  
  1099. static int xpos(win)
  1100. WINDOW *win;
  1101. {
  1102.    int x, y;
  1103.    getyx(win, y, x);
  1104.    return x;
  1105. }
  1106.  
  1107.  
  1108. static int ypos(win)
  1109. WINDOW *win;
  1110. {
  1111.    int y, x;
  1112.    getyx(win, y, x);
  1113.    return y;
  1114. }
  1115.  
  1116.  
  1117. static command specialKeysIdle(c)
  1118. char c;
  1119. {
  1120.    return (command) 0;
  1121. }
  1122.  
  1123. static void set_inverse()
  1124. {
  1125.  
  1126.    if (inverseFlag)
  1127.       standout();
  1128. }
  1129.  
  1130. static void unset_inverse()
  1131. {
  1132.    standend();
  1133. }
  1134.  
  1135.  
  1136.  
  1137. static void drawPiece(i, j, c)
  1138. int i, j;
  1139. char c;
  1140. {
  1141.    move(TOP + j, LEFT + 2 * i);
  1142.    set_inverse();
  1143.    addch(c);
  1144.    unset_inverse();
  1145. }
  1146.  
  1147.  
  1148. static void initBoardAscii()
  1149. {
  1150.    int i, j;
  1151.  
  1152.    clear();
  1153.    if (inverseFlag) {
  1154.       set_inverse();
  1155.       for (i = LEFT + 1; i < LEFT + boardsize * 2 - 2; i += 2)
  1156.      for (j = TOP; j < TOP + boardsize; j++)
  1157.         mvaddch(j, i, ' ');
  1158.       unset_inverse();
  1159.    }
  1160.    for (i = boardsize; i--;) {
  1161.       /* left */
  1162.       move(TOP + i, LEFT - 3);
  1163.       printw("%2d", boardsize - i);
  1164.       set_inverse();
  1165.       addch(chars[(int) CHAR_VERT]);
  1166.  
  1167.       /* right */
  1168.       move(TOP + i, LEFT + boardsize * 2 - 1);
  1169.       addch(chars[(int) CHAR_VERT]);
  1170.       unset_inverse();
  1171.       printw("%2d%c", boardsize - i, chars[(int) CHAR_VERT]);
  1172.  
  1173.       /* top */
  1174.       move(TOP - 2, LEFT + i * 2);
  1175.       addch(xAxisChars[i]);
  1176.       move(TOP - 1, LEFT + i * 2 - 1);
  1177.       set_inverse();
  1178.       printw("%c%c", chars[(int) CHAR_HORIZ], chars[(int) CHAR_HORIZ]);
  1179.  
  1180.       /* bottom */
  1181.       move(TOP + boardsize, LEFT + i * 2 - 1);
  1182.       printw("%c%c", chars[(int) CHAR_HORIZ], chars[(int) CHAR_HORIZ]);
  1183.       unset_inverse();
  1184.       move(TOP + boardsize + 1, LEFT + i * 2);
  1185.       addch(xAxisChars[i]);
  1186.       for (j = boardsize; j--;)
  1187.      drawPiece(i, j, boardPiece(i, j));
  1188.    }
  1189.    set_inverse();
  1190.    move(TOP - 1, LEFT - 1);
  1191.    addch(chars[(int) CHAR_UPLEFT]);
  1192.    move(TOP - 1, LEFT + boardsize * 2 - 1);
  1193.    addch(chars[(int) CHAR_UPRIGHT]);
  1194.    move(TOP + boardsize, LEFT - 1);
  1195.    addch(chars[(int) CHAR_DOWNLEFT]);
  1196.    move(TOP + boardsize, LEFT + boardsize * 2 - 1);
  1197.    addch(chars[(int) CHAR_DOWNRIGHT]);
  1198.    unset_inverse();
  1199.    mvaddstr(COMMAND_Y, COMMAND_X, helpMsg);
  1200.    printstatus(name_buf);
  1201. }
  1202. SHAR_EOF
  1203. fi
  1204. if test -f 'mou.c'
  1205. then
  1206.     echo shar: "will not over-write existing file 'mou.c'"
  1207. else
  1208. cat << \SHAR_EOF > 'mou.c'
  1209. /*****************************************************************************
  1210.  * PROJECT:  Mouse routines with 'real' graphic cursor in text mode.
  1211.  *****************************************************************************
  1212.  * MODULE:  MOU.C
  1213.  *****************************************************************************
  1214.  * DESCRIPTION:
  1215.  *   Main file for the mouse routines.
  1216.  *
  1217.  *****************************************************************************
  1218.  * MODIFICATION NOTES:
  1219.  *    Date     Version Author Comment
  1220.  * 15-Mar-1991     1.04     dk   Added function to set mouse position.  From a
  1221.  *                  suggestion by Gary Tepel.
  1222.  * 17-Jan-1991     1.02     ta   Diffs sent to me from Tony Acero for middle
  1223.  *                  mouse button support.
  1224.  * 10-Jan-1991     1.01     dk   Made points variable global throughout module.
  1225.  * 07-Jan-1991     1.00     dk   Fixed bugs and set up for release to Usenet.
  1226.  * 26-Oct-1990     0.00     dk   Initial file.
  1227.  *****************************************************************************
  1228.  *
  1229.  * DISCLAIMER:
  1230.  *
  1231.  * Programmers may incorporate any or all code into their programs,
  1232.  * giving proper credit within the source. Publication of the
  1233.  * source routines is permitted so long as proper credit is given
  1234.  * to Dave Kirsch.
  1235.  *
  1236.  * Copyright (C) 1990, 1991 by Dave Kirsch.  You may use this program, or
  1237.  * code or tables extracted from it, as desired without restriction.
  1238.  * I can not and will not be held responsible for any damage caused from
  1239.  * the use of this software.
  1240.  *
  1241.  * Author: a563@mindlink.UUCP  -or-  Zoid@cc.sfu.ca
  1242.  *
  1243.  *****************************************************************************
  1244.  * This source works with Turbo C 2.0 and MSC 6.0 and above.
  1245.  *****************************************************************************/
  1246.  
  1247. #ifdef __TURBOC__
  1248. #pragma inline
  1249. #endif
  1250.  
  1251. #include <stdio.h>
  1252. #include <dos.h>
  1253. #include <stdlib.h>
  1254. #include <string.h>
  1255.  
  1256. #include "mou.h"
  1257.  
  1258. #define HEIGHT 16
  1259.  
  1260. int vgapresent=0;
  1261. word mousehidden = 0;           /* Is the mouse on? Additive flag */
  1262. mouseboolean mouseinstalled = FALSE; /* Is the mouse installed? */
  1263.  
  1264. volatile word mousex=0, mousey=0; /* Character position of mouse */
  1265.  
  1266. #ifndef __TURBOC__
  1267. STATIC word _based(_segname("_CODE")) DGroupSeg;
  1268. #endif
  1269.  
  1270. STATIC volatile word mbufin = 0, mbufout = 0; /* Mouse buffer pointers */
  1271.  
  1272. STATIC word mousefreeze = 0;           /* Is mouse frozen in place? */
  1273.  
  1274. STATIC MOUINFOREC mbuf[MOUSEBUFFERSIZE]; /* Mouse buffer */
  1275.  
  1276. /* Save information for non EGA/VGA */
  1277. STATIC word oldword;
  1278. STATIC word newword;
  1279. STATIC mouseboolean saved = FALSE;
  1280. STATIC word oldmx, oldmy;
  1281.  
  1282. /* Save information for EGA/VGA displays */
  1283.   mouseboolean egavga = FALSE; /* Do we have an EGA/VGA adapter? */
  1284. STATIC byte savechars[3][3]; /* The saved characters we overwrote */
  1285. STATIC dword mousecursormask[HEIGHT] =  {
  1286.   0x00000000L,  /*0000000000000000*/
  1287.   0x40000000L,  /*0100000000000000*/
  1288.   0x60000000L,  /*0110000000000000*/
  1289.   0x70000000L,  /*0111000000000000*/
  1290.   0x78000000L,  /*0111100000000000*/
  1291.   0x7c000000L,  /*0111110000000000*/
  1292.   0x7e000000L,  /*0111111000000000*/
  1293.   0x7f000000L,  /*0111111100000000*/
  1294.   0x7f800000L,  /*0111111110000000*/
  1295.   0x7f000000L,  /*0111111100000000*/
  1296.   0x7c000000L,  /*0111110000000000*/
  1297.   0x46000000L,  /*0100011000000000*/
  1298.   0x06000000L,  /*0000011000000000*/
  1299.   0x03000000L,  /*0000001100000000*/
  1300.   0x03000000L,  /*0000001100000000*/
  1301.   0x00000000L   /*0000000000000000*/
  1302. };
  1303.  
  1304. STATIC dword mousescreenmask[HEIGHT] =  {
  1305.   0x3fffffffL,  /*0011111111111111*/
  1306.   0x1fffffffL,  /*0001111111111111*/
  1307.   0x0fffffffL,  /*0000111111111111*/
  1308.   0x07ffffffL,  /*0000011111111111*/
  1309.   0x03ffffffL,  /*0000001111111111*/
  1310.   0x01ffffffL,  /*0000000111111111*/
  1311.   0x00ffffffL,  /*0000000011111111*/
  1312.   0x007fffffL,  /*0000000001111111*/
  1313.   0x003fffffL,  /*0000000000111111*/
  1314.   0x007fffffL,  /*0000000001111111*/
  1315.   0x01ffffffL,  /*0000000111111111*/
  1316.   0x10ffffffL,  /*0001000011111111*/
  1317.   0xb0ffffffL,  /*1011000011111111*/
  1318.   0xf87fffffL,  /*1111100001111111*/
  1319.   0xf87fffffL,  /*1111100001111111*/
  1320.   0xfcffffffL   /*1111110011111111*/
  1321. };
  1322.  
  1323. STATIC byte chardefs[32 * 9]; /* 9 character definitons. */
  1324. STATIC word mousepx, mousepy; /* Mouse pixel coordinates */
  1325.  
  1326. STATIC mouseboolean conditionalhidemouse = FALSE;
  1327. STATIC word conx1, cony1, conx2, cony2;
  1328.  
  1329. STATIC word vseg; /* Segment of video ram. */
  1330. STATIC word mcols, mrows;
  1331. STATIC byte savevmode;
  1332. STATIC word points;
  1333.  
  1334. STATIC word maxx, maxy;
  1335.  
  1336. STATIC mouseboolean desqview = FALSE;
  1337.  
  1338. #define POKEATTRIB(x, y, a) pokeb(vseg, (y) * (mcols * 2) + ((x) << 1) + 1, a)
  1339. #define PEEKATTRIB(x, y)    peekb(vseg, (y) * (mcols * 2) + ((x) << 1) + 1)
  1340.  
  1341. #define POINTS *((byte far *) 0x00000485)
  1342. #define COLS *((byte far *) 0x0040004AL)
  1343. #define ROWS *((byte far *) 0x00400084L)
  1344.  
  1345. #define DEFCHAR 0xd0
  1346.  
  1347. /*********************************************************************/
  1348. /* Mon 07-Jan-1991 - dk                                              */
  1349. /*                                                                   */
  1350. /*  Plot the cursor on the screen, save background, draw grid, etc.  */
  1351. /*                                                                   */
  1352. /*********************************************************************/
  1353. PRIVATE void LOCAL FAST plotegavgacursor(word func)
  1354. {
  1355. word off;
  1356. word width, height, i, j;
  1357. word disp;
  1358. word x = 0, y = 0;
  1359. static word lsavex = 0, lsavey = 0;
  1360.  
  1361.   switch (func) {
  1362.     case 0 : /* erase grid, put back save info */
  1363.       x = lsavex;
  1364.       y = lsavey;
  1365.       break;
  1366.     case 1 : /* draw grid */
  1367.       x = mousex;
  1368.       y = mousey;
  1369.       break;
  1370.     case 2 : /* save grid */
  1371.       lsavex = x = mousex;
  1372.       lsavey = y = mousey;
  1373.       break;
  1374.   }
  1375.  
  1376.   width = mcols - x;
  1377.   if (width > 3)
  1378.     width = 3;
  1379.   height = mrows - y;
  1380.   if (height > 3)
  1381.     height = 3;
  1382.  
  1383.   off = y * (mcols * 2) + x * 2;
  1384.   disp = (mcols * 2) - width * 2;
  1385.  
  1386.   switch (func) {
  1387.     case 0 : /* erase grid, put back save info */
  1388.       for (i = 0; i < height; i++, off += disp)
  1389.         for (j = 0; j < width; j++, off += 2)
  1390.           pokeb(vseg, off, savechars[i][j]);
  1391.       break;
  1392.     case 1 : /* draw grid. */
  1393.       for (i = 0; i < height; i++, off += disp)
  1394.         for (j = 0; j < width; j++, off += 2)
  1395.           pokeb(vseg, off, DEFCHAR + i * 3 + j);
  1396.       break;
  1397.     case 2 : /* save grid. */
  1398.       for (i = 0; i < height; i++, off += disp)
  1399.         for (j = 0; j < width; j++, off += 2)
  1400.           savechars[i][j] = peekb(vseg, off);
  1401.       break;
  1402.   }
  1403. }
  1404.  
  1405. PRIVATE void LOCAL FAST drawegavgacursor(void)
  1406. {
  1407. word off;
  1408. word i, j;
  1409. word s1, s2, s3;
  1410. dword *defs;
  1411. dword *masks;
  1412. word shift;
  1413. dword addmask;
  1414.  
  1415.   plotegavgacursor(2); /* Save current grid that is there. */
  1416.  
  1417.   /* Time for some assembler.  Program the EGA/VGA Sequencer and Graphics
  1418.      Controller for direct access to the character definition tables.
  1419.      Then read in the definitions for the characters we are changing, AND
  1420.      the screen mask, then OR the cursor mask to them.  Then copy those
  1421.      defintions into the location of the mouse cursor defintions
  1422.      and set the Sequencer and Graphics Controller back to normal <whew!>.
  1423.   */
  1424.  
  1425.   /* Program the Sequencer */
  1426.  
  1427.   asm pushf; /* Disable interrupts */
  1428.   asm cli;
  1429.   asm mov dx, 3c4h; /* Sequencer port address */
  1430.   asm mov ax, 0704h; /* Sequential addressing */
  1431.   asm out dx, ax;
  1432.  
  1433.   /* Program the Graphics Controller */
  1434.   asm mov dx, 3ceh; /* Graphics Controller port address */
  1435.   asm mov ax, 0204h; /* Select map 2 for CPU reads */
  1436.   asm out dx, ax;
  1437.   asm mov ax, 0005h; /* Disable odd-even addressing */
  1438.   asm out dx, ax;
  1439.   asm mov ax, 0406h; /* Map starts at A000:0000 (64K mode) */
  1440.   asm out dx, ax;
  1441.   asm popf;
  1442.  
  1443.   /* Ok, now we have direct access to the character defintion tables, copy
  1444.      over the defintions for the characters we are changing */
  1445.  
  1446.   off = 0;
  1447.   for (i = 0; i < 9; i += 3) { /* Grid is three characters high. */
  1448.     s1 = ((byte *)savechars)[i    ] * 32;
  1449.     s2 = ((byte *)savechars)[i + 1] * 32;
  1450.     s3 = ((byte *)savechars)[i + 2] * 32;
  1451.     for (j = 0; j < points; j++) {
  1452.       off++; /* 4th byte, that we don't need. */
  1453.       chardefs[off++] = peekb(0xa000, s3++);
  1454.       chardefs[off++] = peekb(0xa000, s2++);
  1455.       chardefs[off++] = peekb(0xa000, s1++);
  1456.     }
  1457.   }
  1458.  
  1459.   /* Ok, we've got the defintions for the characters that we are drawing the
  1460.      cursor on.  AND the screen mask and OR the cursor mask to them, thereby
  1461.      'drawing' the cursor.  Since the cursor is 16 pixels wide and 16 pixels
  1462.      high, we have to save a 3 by 3 character grid where the mouse cursor is
  1463.      going.  We use dwords (32 bits) to do the bit AND and OR.  This could
  1464.      be made alot faster on a 386 by using 32 bit registers. */
  1465.  
  1466.   shift = mousepx % 8;
  1467.   addmask = 0xff000000L << (8 - shift);
  1468.  
  1469.   masks = mousescreenmask;
  1470.   defs = ((dword *)chardefs) + mousepy % points;
  1471.   for (i = 0; i < HEIGHT; i++)
  1472.     *defs++ &= (*masks++ >> shift) | addmask;
  1473.  
  1474.   masks = mousecursormask;
  1475.   defs = ((dword *)chardefs) + mousepy % points;
  1476.   for (i = 0; i < HEIGHT; i++)
  1477.     *defs++ |= *masks++ >> shift;
  1478.  
  1479.   /* Ok, Everything is setup, now copy the modifed character definitions
  1480.      to their new location. */
  1481.  
  1482.   asm mov dx, 3c4h; /* Sequencer port address */
  1483.   asm mov ax, 0402h; /* CPU writes only to map 2 */
  1484.   asm out dx, ax;
  1485.  
  1486.   off = 0;
  1487.   for (i = 0; i < 9; i += 3) { /* Grid is three characters high. */
  1488.     s1 = (DEFCHAR + i    ) * 32;
  1489.     s2 = (DEFCHAR + i + 1) * 32;
  1490.     s3 = (DEFCHAR + i + 2) * 32;
  1491.     for (j = 0; j < points; j++) {
  1492.       off++; /* 4th byte, that we don't need. */
  1493.       pokeb(0xa000, s3++, chardefs[off++]);
  1494.       pokeb(0xa000, s2++, chardefs[off++]);
  1495.       pokeb(0xa000, s1++, chardefs[off++]);
  1496.     }
  1497.   }
  1498.  
  1499.   /* Ok, put the Sequencer and Graphics Controller back to normal */
  1500.  
  1501.   /* Program the Sequencer */
  1502.   asm pushf; /* Disable interrupts */
  1503.   asm cli;
  1504.   asm mov dx, 3c4h; /* Sequencer port address */
  1505.   asm mov ax, 0302h; /* CPU writes to maps 0 and 1 */
  1506.   asm out dx, ax;
  1507.   asm mov ax, 0304h; /* Odd-even addressing */
  1508.   asm out dx, ax;
  1509.  
  1510.   /* Program the Graphics Controller */
  1511.   asm mov dx, 3ceh; /* Graphics Controller port address */
  1512.   asm mov ax, 0004h; /* Select map 0 for CPU reads */
  1513.   asm out dx, ax;
  1514.   asm mov ax, 1005h; /* Enable odd-even addressing */
  1515.   asm out dx, ax;
  1516.   asm sub ax, ax;
  1517.   asm mov es, ax; /* Segment 0 */
  1518.   asm mov ax, 0e06h; /* Map starts at B800:0000 */
  1519.   asm mov bl, 7;
  1520.   asm cmp es:[49h], bl; /* Get current video mode */
  1521.   asm jne notmono;
  1522.   asm mov ax, 0806h; /* Map starts at B000:0000 */
  1523. notmono:
  1524.   asm out dx, ax;
  1525.   asm popf;
  1526.  
  1527.   /* Ok, now put the bytes on the screen */
  1528.  
  1529.   plotegavgacursor(1); /* Plot the new grid on the screen. */
  1530. }
  1531.  
  1532. /*******************************************************/
  1533. /* 27-Oct-1990 - dk                                    */
  1534. /*                                                     */
  1535. /*  This function checks for the presense of EGA/VGA.  */
  1536. /*                                                     */
  1537. /*******************************************************/
  1538.  mouseboolean isegavga(void)
  1539. {
  1540.   asm mov ax, 1a00h; /* ROM BIOS video function 1ah -- Read Display Code */
  1541.   asm int 10h;
  1542.   asm cmp ah, 1ah; /* Is this call supported? */
  1543.   asm je checkega; /* Not supported */
  1544.   asm cmp bl, 7; /* VGA w/monochrome display? */
  1545.   asm je isvga; /* Yup. */
  1546.   asm cmp bl, 8; /* VGA w/color display? */
  1547.   asm jne checkega; /* Nope */
  1548. isvga:
  1549.   vgapresent=1;
  1550. isega:
  1551.   return TRUE; /* EGA/VGA is installed */
  1552. checkega:
  1553.   asm mov ah, 12h; /* EGA BIOS function */
  1554.   asm mov bl, 10h;
  1555.   asm int 10h;
  1556.   asm cmp bl, 10h; /* Is EGA BIOS present? */
  1557.   asm jne isega; /* There is an EGA in the system. */
  1558.   return FALSE; /* Not EGA or VGA in system. */
  1559. }
  1560.  
  1561. /************************************************/
  1562. /* 26-Oct-1990 - dk                             */
  1563. /*                                              */
  1564. /*  Mouse handler -- called from mouse driver.  */
  1565. /*                                              */
  1566. /************************************************/
  1567. PRIVATE void far mousehandler(void)
  1568. /* This function is called whenever a button is pressed.  Do not call this
  1569.    function directly!!
  1570. */
  1571. {
  1572. register word conditionmask;
  1573.  
  1574.   /* Get our data segment */
  1575.   asm push ds
  1576. #ifdef __TURBOC__
  1577.   asm push ax
  1578.   asm mov ax, DGROUP
  1579.   asm mov ds, ax
  1580.   asm pop ax
  1581. #else
  1582.   asm mov ds, cs:DGroupSeg
  1583. #endif
  1584.  
  1585.   asm mov conditionmask,ax
  1586.  
  1587.   if (!mousefreeze) {
  1588.     /* save mouse info passed to us from driver */
  1589.     asm mov mousex, cx
  1590.     asm mov mousey, dx
  1591.     asm mov mousepx, cx
  1592.     asm mov mousepy, dx
  1593.  
  1594.     mousex /= 8; /* Characters are 8 pixels wide */
  1595.     mousey /= points; /* Scale mousey down */
  1596.  
  1597.     /* See if the mouse has moved. */
  1598.     if (conditionmask & MOUSEMOVE) {
  1599.       if (saved) {
  1600.         if (egavga)
  1601.           plotegavgacursor(0);
  1602.         else
  1603.           POKEATTRIB(oldmx, oldmy, oldword);
  1604.         saved = FALSE;
  1605.       }
  1606.  
  1607.       if (!mousehidden && conditionalhidemouse) /* Check to see if we need to hide */
  1608.         if (mousex >= conx1 && mousex <= conx2 &&
  1609.             mousey >= cony1 && mousey <= cony2) {
  1610.           mousehidden++;
  1611.           conditionalhidemouse = FALSE;
  1612.         }
  1613.  
  1614.       if (!mousehidden) {
  1615.         if (egavga)
  1616.           drawegavgacursor();
  1617.         else {
  1618.           oldword = PEEKATTRIB(mousex, mousey);
  1619.       asm mov ax, oldword;    /* Prepare to rotate attrib byte */
  1620.           asm and al, 0f7h; /* Clear high bit */
  1621.           asm mov cl, 4   /* We want to rotate 4 bits */
  1622.           asm rol al, cl  /* Rotate it */
  1623.       asm mov newword, ax;
  1624.  
  1625.           POKEATTRIB(mousex, mousey, newword); /* Write out new mouse cursor */
  1626.         }
  1627.  
  1628.         oldmx = mousex;
  1629.         oldmy = mousey;
  1630.         saved = TRUE;
  1631.  
  1632.       }
  1633.     }
  1634.   }
  1635.  
  1636.   /* Now, see if a mouse button was whacked */
  1637.   if (conditionmask & ~MOUSEMOVE)
  1638.     if (((mbufin + 1) % MOUSEBUFFERSIZE) == mbufout) { /* Buffer full? */
  1639. #ifdef __TURBOC__
  1640.       sound(1760); /* Make some noise. */
  1641.       delay(10);
  1642.       nosound();
  1643. #endif
  1644.     } else {
  1645.       mbuf[mbufin].buttonstat = conditionmask & ~MOUSEMOVE;
  1646.       mbuf[mbufin].cx = mousex;
  1647.       mbuf[mbufin].cy = mousey;
  1648.       mbuf[mbufin].shiftstate = peekb(0, 0x417); /* Get shift byte */
  1649.       mbufin = (mbufin + 1) % MOUSEBUFFERSIZE;
  1650.     }
  1651.  
  1652.   asm pop ds;
  1653. }
  1654.  
  1655. /************************************/
  1656. /* 26-Oct-1990 - dk                 */
  1657. /*                                  */
  1658. /*  Initialize the mouse routines.  */
  1659. /*                                  */
  1660. /************************************/
  1661. void FAST MOUinit(void)
  1662. {
  1663. extern int graphicalCursor;
  1664. byte v;
  1665.  
  1666. #ifndef __TURBOC__
  1667.   asm mov cs:DGroupSeg,ds   /* save for interrupt handler to use */
  1668. #endif
  1669.  
  1670.   asm sub ax,ax;    /* Mouse driver function 0 -- reset and detect */
  1671.   asm int 33h
  1672.   asm mov mouseinstalled, AX;
  1673.  
  1674.   if (mouseinstalled) { /* If a mouse is installed then activate driver */
  1675.  
  1676.     mousefreeze++; /* Make sure handler doesn't do things, yet */
  1677.  
  1678.     asm mov ax,0F00h;
  1679.     asm int 10h;
  1680.     asm mov v,al;
  1681.  
  1682.     if (v == 7) {
  1683.       vseg = 0xb000u;
  1684.     } else {
  1685.       vseg = 0xb800u;
  1686.       v = 3;
  1687.     }
  1688.  
  1689.     if (ROWS == 0) { /* No value, assume 80x25. */
  1690.       mrows = 25;
  1691.       mcols = 80;
  1692.       points = 8;
  1693.     } else {
  1694.       mrows = ROWS + 1;
  1695.       mcols = COLS;
  1696.       points = POINTS;
  1697.     }
  1698.  
  1699.     /* Check to see if we are running in DESQview.  If so, don't try to
  1700.        use the 'true' EGA/VGA cursor (DV doesn't like it at ALL). */
  1701.  
  1702.     asm mov ax, 2b01h;
  1703.     asm mov cx, 4445h;
  1704.     asm mov dx, 5351h;
  1705.     asm int 21h;
  1706.  
  1707.     asm cmp al, 0ffh;
  1708.     asm je notdv;
  1709.  
  1710.     desqview = TRUE;
  1711.  
  1712. notdv:
  1713.  
  1714.     /* Do we have an EGA or VGA?  If so, and we are not in monochrome mode
  1715.        and we are not in DESQview then setup to draw a 'true' mouse cursor
  1716.        on an EGA/VGA */
  1717.     egavga = isegavga() && vseg != 0xb000u && !desqview && graphicalCursor;
  1718.  
  1719.     if (egavga) {
  1720.       /* We are going to use our 'true' mouse cursor and we need pixel
  1721.          resolution, not character resolution from the mouse driver
  1722.          (In text mode, the mouse driver only returns coordinates in multiples
  1723.          of 8, which we don't want.  We want multiples of 1, i.e. pixel
  1724.          resolution).  To get the mouse driver to return coordinates in pixel
  1725.          resolution, we 'trick' it into thinking it's in graphics mode by
  1726.          setting the low memory byte indicating mode to mode 6 (CGA 640x200x2).
  1727.          Then we reset the mouse driver.  The mouse driver will get the video
  1728.          mode then act as if it was in graphics mode, not text mode. */
  1729.       savevmode = peekb(0x40, 0x49);
  1730.       pokeb(0x40, 0x49, 6); /* Does this work ?!?!?!?!? */
  1731.  
  1732.       /* Reset driver for change in video mode to take effect. */
  1733.       asm sub ax,ax
  1734.       asm int 33h
  1735.  
  1736.       /* Now that we've tricked the mouse driver into a grapics mode thereby
  1737.          causing it to give us pixel resolutions, put the old mode back. */
  1738.       pokeb(0x40, 0x49, savevmode);
  1739.     }
  1740.  
  1741.     /* Set up max x and y ranges. */
  1742.  
  1743.     maxx = mcols * 8 - 1; /* Pixels horizontally */
  1744.     maxy = mrows * points - 1; /* Pixels vertically */
  1745.  
  1746.     asm mov dx,maxx     /* Pixels horizontally */
  1747.     asm mov ax,7        /* mouse driver function 7 -- set max x range */
  1748.     asm sub cx,cx       /* Minimum range */
  1749.     asm int 33h
  1750.  
  1751.     asm mov dx,maxy     /* Pixels veritcally */
  1752.     asm mov ax,8        /* mouse driver function 8 -- set max y range */
  1753.     asm sub cx,cx       /* Minimum range */
  1754.     asm int 33h
  1755.  
  1756.     /* Now install user routine */
  1757.  
  1758.     asm mov ax,cs
  1759.     asm mov es,ax
  1760.     asm mov dx, offset mousehandler
  1761.     /* Setup up bits for calling routine */
  1762. #ifdef __TURBOC__
  1763.     _CX = LEFTBPRESS | LEFTBRELEASE | RIGHTBPRESS | RIGHTBRELEASE | MIDBPRESS |
  1764.       MIDBRELEASE | MOUSEMOVE;
  1765. #else
  1766.     asm mov cx, LEFTBPRESS | LEFTBRELEASE | RIGHTBPRESS | RIGHTBRELEASE | MIDBPRESS | MIDBRELEASE | MOUSEMOVE;
  1767. #endif
  1768.     asm mov ax,12       /* Function 12 -- set user routine */
  1769.     asm int 33h
  1770.  
  1771.     mousex = mousey = mousepx = mousepy = 0;
  1772.     asm mov cx,mousepx     /* xcoord */
  1773.     asm mov dx,mousepy     /* ycoord */
  1774.     asm mov ax,4    /* mouse driver function 4 -- set mouse position */
  1775.     asm int 33h
  1776.  
  1777.     MOUshow(); /* Call it twice just to make sure */
  1778.  
  1779.     mousefreeze--; /* Handler can get into business, now */
  1780.   }
  1781. }
  1782.  
  1783. /****************************/
  1784. /* 26-Oct-1990 - dk         */
  1785. /*                          */
  1786. /*  Hide the mouse cursor.  */
  1787. /*                          */
  1788. /****************************/
  1789. void FAST MOUhide(void)
  1790. /* This function turns off the mouse cursor, the mouse still responds
  1791.    to button presses */
  1792. {
  1793.   if (!mouseinstalled)
  1794.     return;
  1795.  
  1796.   mousefreeze++; /* don't have the handler doing weird things */
  1797.  
  1798.   mousehidden++; /* indicate it's hidden now */
  1799.  
  1800.   if (saved) {
  1801.     if (egavga)
  1802.       plotegavgacursor(0);
  1803.     else
  1804.       POKEATTRIB(oldmx, oldmy, oldword);
  1805.     saved = FALSE;
  1806.   }
  1807.  
  1808.   mousefreeze--; /* reactivate handler */
  1809. }
  1810.  
  1811. /****************************/
  1812. /* 26-Oct-1990 - dk         */
  1813. /*                          */
  1814. /*  Show the mouse cursor.  */
  1815. /*                          */
  1816. /****************************/
  1817. void FAST MOUshow(void)
  1818. {
  1819.   if (!mouseinstalled)
  1820.     return;
  1821.  
  1822.   mousefreeze++; /* don't have the handler doing weird things */
  1823.  
  1824.   /* Just in case we were in a conditionalhide */
  1825.   if (conditionalhidemouse) {
  1826.     /* We were about to conditional hide, but we didn't, don't reactive
  1827.        mouse cursor. */
  1828.     conditionalhidemouse = FALSE;
  1829.     mousefreeze--; /* Reactivate handler */
  1830.     return;
  1831.   }
  1832.  
  1833.   if (mousehidden)
  1834.     mousehidden--;
  1835.   else {
  1836.     mousefreeze--; /* Reactivate handler */
  1837.     return;  /* It isn't hidden! */
  1838.   }
  1839.  
  1840.   if (mousehidden) {
  1841.     mousefreeze--; /* reactivate handler */
  1842.     return; /* still hidden! */
  1843.   }
  1844.  
  1845.   /* Draw mouse cursor */
  1846.  
  1847.   if (egavga)
  1848.     drawegavgacursor();
  1849.   else {
  1850.     oldword = PEEKATTRIB(mousex, mousey);
  1851.     asm mov ax, oldword;  /* Prepare to rotate attrib byte */
  1852.     asm and al, 0f7h; /* Clear high bit */
  1853.     asm mov cl, 4   /* We want to rotate 4 bits */
  1854.     asm rol al, cl  /* Rotate it */
  1855.     asm mov newword, ax;
  1856.  
  1857.     POKEATTRIB(mousex, mousey, newword); /* Write out new mouse cursor */
  1858.   }
  1859.  
  1860.   oldmx = mousex;
  1861.   oldmy = mousey;
  1862.   saved = TRUE;
  1863.  
  1864.   mousefreeze--; /* Reactivate handler */
  1865. }
  1866.  
  1867. /*************************************************************/
  1868. /* 27-Oct-1990 - dk                                          */
  1869. /*                                                           */
  1870. /*  Returns true if there is something in the mouse buffer.  */
  1871. /*                                                           */
  1872. /*************************************************************/
  1873. mouseboolean FAST MOUcheck(void)
  1874. {
  1875.   return mbufin != mbufout;
  1876. }
  1877.  
  1878. /**************************************************************/
  1879. /* 26-Oct-1990 - dk                                           */
  1880. /*                                                            */
  1881. /*  Take a copy of the mouse event at the head of the queue.  */
  1882. /*                                                            */
  1883. /**************************************************************/
  1884. void FAST MOUpreview(MOUINFOREC *mouinforec)
  1885. {
  1886.   if (!mouseinstalled)
  1887.     return;
  1888.  
  1889.   if (mbufin != mbufout) /* if something is in buffer */
  1890.     *mouinforec = mbuf[mbufout];
  1891.   else {
  1892.     /* Nothing to pull, just report mouse position */
  1893.     mouinforec -> cx = mousex;
  1894.     mouinforec -> cy = mousey;
  1895.     mouinforec -> buttonstat = 0;
  1896.     mouinforec -> shiftstate = peekb(0, 0x417);
  1897.   }
  1898. }
  1899.  
  1900. /****************************************************************/
  1901. /* 26-Oct-1990 - dk                                             */
  1902. /*                                                              */
  1903. /*  Get (and remove) the mouse event at the head of the queue.  */
  1904. /*                                                              */
  1905. /****************************************************************/
  1906. void FAST MOUget(MOUINFOREC *mouinforec)
  1907. {
  1908.   if (!mouseinstalled)
  1909.     return;
  1910.  
  1911.   if (mbufin != mbufout) { /* if something is in buffer */
  1912.     if (mouinforec != NULL)
  1913.       *mouinforec = mbuf[mbufout];
  1914.     mbufout = (mbufout + 1) % MOUSEBUFFERSIZE;
  1915.   } else {
  1916.     /* Nothing to pull, just report mouse position */
  1917.     mouinforec -> cx = mousex;
  1918.     mouinforec -> cy = mousey;
  1919.     mouinforec -> buttonstat = 0;
  1920.     mouinforec -> shiftstate = peekb(0, 0x417);
  1921.   }
  1922. }
  1923.  
  1924. /**************************************/
  1925. /* 26-Oct-1990 - dk                   */
  1926. /*                                    */
  1927. /*  Deinitialize the mouse routines.  */
  1928. /*                                    */
  1929. /**************************************/
  1930. void FAST MOUdeinit(void)
  1931. {
  1932.   if (!mouseinstalled)
  1933.     return;
  1934.  
  1935.   MOUhide();
  1936.  
  1937.   asm sub ax,ax
  1938.   asm int 33h
  1939. }
  1940.  
  1941. /**************************************************/
  1942. /* 26-Oct-1990 - dk                               */
  1943. /*                                                */
  1944. /*  Returns the bits for the button status info.  */
  1945. /*                                                */
  1946. /**************************************************/
  1947. word FAST MOUbuttonstatus(void)
  1948. {
  1949. word buts;
  1950.  
  1951.   if (!mouseinstalled)
  1952.     return 0;
  1953.  
  1954.   asm mov ax,3
  1955.   asm int 33h
  1956.   asm mov buts,bx
  1957.   return buts;
  1958. }
  1959.  
  1960. /************************************************************************/
  1961. /* 26-Oct-1990 - dk                                                     */
  1962. /*                                                                      */
  1963. /*  Hide the mouse *if* it enters a certain screen area, automatically. */
  1964. /*                                                                      */
  1965. /************************************************************************/
  1966. void FAST MOUconditionalhide(int x1, int y1, int x2, int y2)
  1967. {
  1968.   if (!mouseinstalled)
  1969.     return;
  1970.  
  1971.   mousefreeze++; /* hold the handler */
  1972.  
  1973.   if (mousehidden) {
  1974.     mousefreeze--; /* reactivate handler */
  1975.     return; /* already hidden! */
  1976.   }
  1977.  
  1978.   conditionalhidemouse = TRUE;
  1979.  
  1980.   x1 -= 2;
  1981.   if (x1 < 0)
  1982.     x1 = 0;
  1983.   y1 -= 2;
  1984.   if (y1 < 0)
  1985.     y1 = 0;
  1986.   x2 += 2;
  1987.   y2 += 2;
  1988.  
  1989.   conx1 = x1;
  1990.   cony1 = y1;
  1991.   conx2 = x2;
  1992.   cony2 = y2;
  1993.  
  1994.   if (mousex >= conx1 && mousex <= conx2 &&
  1995.       mousey >= cony1 && mousey <= cony2) {
  1996.     conditionalhidemouse = FALSE; /* We've already hidden it */
  1997.     MOUhide(); /* turn it off now if it's there. */
  1998.   }
  1999.  
  2000.   mousefreeze--;
  2001. }
  2002.  
  2003. /*********************************************************/
  2004. /* Fri 15-Mar-1991 - dk                  */
  2005. /*                             */
  2006. /*  Set the mouse cursor to a specific screen position.  */
  2007. /*                             */
  2008. /*********************************************************/
  2009. void FAST MOUsetpos(word x, word y)
  2010. {
  2011.   if (!mouseinstalled)
  2012.     return;
  2013.  
  2014.   mousefreeze++;
  2015.  
  2016.   MOUhide();
  2017.  
  2018.   mousex = x;
  2019.   mousey = y;
  2020.   mousepx = mousex * 8;
  2021.   mousepy = mousey * points;
  2022.   asm mov cx, mousepx    /* xcoord */
  2023.   asm mov dx, mousepy    /* ycoord */
  2024.   asm mov ax, 4     /* mouse driver function 4 -- set mouse position */
  2025.   asm int 33h
  2026.  
  2027.   MOUshow();
  2028.  
  2029.   mousefreeze--;
  2030. }
  2031. SHAR_EOF
  2032. fi
  2033. if test -f 'ascii.c'
  2034. then
  2035.     echo shar: "will not over-write existing file 'ascii.c'"
  2036. else
  2037. cat << \SHAR_EOF > 'ascii.c'
  2038. /* "mgt" Copyright (c) 1991 Shodan  */
  2039.  
  2040. #include <ctype.h>
  2041. #include "mgt.h"
  2042.  
  2043. #define TOP 2
  2044. #define LEFT 4
  2045. #define RIGHT 79
  2046. #define STATUS_X 45
  2047. #define STATUS_Y 0
  2048. #define STATUS_WIDE (RIGHT-STATUS_X)
  2049. #define COMMENT_X 46
  2050. #define COMMENT_Y 2
  2051. #define COMMENT_WIDE (RIGHT-COMMENT_X)
  2052. #define COMMENT_HIGH (14-COMMENT_Y)
  2053. #define TREE_X COMMENT_X
  2054. #define TREE_Y 15
  2055. #define TREEWIDE (RIGHT-TREE_X)
  2056. #define TREEHIGH 6
  2057. #define COMMAND_X TREE_X
  2058. #define COMMAND_Y (TREE_Y+TREEHIGH)
  2059. #define WINLEFT   COMMENT_X
  2060. #define WINRIGHT  (RIGHT-1)
  2061. #define WINTOP    2
  2062. #define WINBOT    13
  2063. #define WINHIGH   (WINBOT-WINTOP)
  2064. #define WINWIDE   (WINRIGHT-WINLEFT)
  2065. #define CUP    ('P'-64)
  2066. #define DOWN  ('N'-64)
  2067. #define CRIGHT ('F'-64)
  2068. #define CEND  ('E'-64)
  2069. #define CHOME ('A'-64)
  2070. #define CLEFT ('B'-64)
  2071. #define CTRLX ('X'-64)
  2072. #define CTRLC ('C'-64)
  2073. #define CTRLD ('D'-64)
  2074. #define CTRLO ('O'-64)
  2075. #define CTRLW ('W'-64)
  2076. #define ESC   27
  2077. #define EDHELP "^W - write %s   ^O - keep old %s"
  2078.  
  2079.  
  2080. #define C_COMMENTSCROLLDOWN C_LASTCOMMAND
  2081. #define C_COMMENTSCROLLUP   ((command) ((int)C_LASTCOMMAND+1))
  2082. #define C_TREESCROLLDOWN    ((command) ((int)C_LASTCOMMAND+2))
  2083. #define C_TREESCROLLUP      ((command) ((int)C_LASTCOMMAND+3))
  2084. #define C_VIDEO             ((command) ((int)C_LASTCOMMAND+4))
  2085. #define C_LASTOFS 5
  2086.  
  2087. enum {
  2088.    CHAR_BLACK, CHAR_WHITE,
  2089.    CHAR_DAME,
  2090.    CHAR_BLACKTERR, CHAR_WHITETERR,
  2091.    CHAR_NOTHING,
  2092.    CHAR_HANDICAP,
  2093.    CHAR_VERT, CHAR_HORIZ,
  2094.    CHAR_UPLEFT, CHAR_UPRIGHT,
  2095.    CHAR_DOWNLEFT, CHAR_DOWNRIGHT,
  2096.    ASC_NUMCHARS
  2097. };
  2098.  
  2099.  
  2100. static boolean commentExists;
  2101. static int commentLine;
  2102. static int treeLine;
  2103. static int inverseFlag = 0;
  2104. static char boardPiece();
  2105. static int getLine();
  2106. static void drawPiece();
  2107. static void printstatus();
  2108. static void setCursor();
  2109.  
  2110. char keys[] = "q><.,eb}{][gwzxv!lm#^cdnspotrfLWTFI012346789kiju&";
  2111. char xAxisChars[] = "ABCDEFGHJKLMNOPQRSTUVWXYZ";
  2112. char helpMsg[] = "? for help";
  2113.  
  2114. static void fixkeys()
  2115. {
  2116.    char *keyptr;
  2117.    for (keyptr = keys; *keyptr; keyptr++)
  2118.       if (*keyptr >= 'A' && *keyptr <= 'Z')
  2119.      *keyptr -= 64;
  2120. }
  2121.  
  2122.  
  2123. #ifdef MGT_IBM
  2124. #include "asc_ibm.inc"
  2125. #endif
  2126.  
  2127. #if (MGT_UNIX || vms)
  2128. #include "asc_unix.inc"
  2129. #endif
  2130.  
  2131.  
  2132. static void notifyClearAscii()
  2133. {
  2134.    move(23, 1);
  2135.    clrtoeol();
  2136. }
  2137.  
  2138. static void notifyMessageAscii(s)
  2139. char *s;
  2140. {
  2141.    mvaddstr(23, 1, s);
  2142.    refresh();
  2143. }
  2144.  
  2145. static void notifyErrorAscii(s)
  2146. char *s;
  2147. {
  2148.    mvaddstr(23, 1, s);
  2149.    printw("  Hit a key.");
  2150.    refresh();
  2151.    getKey();
  2152.    notifyClearAscii();
  2153. }
  2154.  
  2155. static void clearScreenAscii()
  2156. {
  2157.    clear();
  2158. }
  2159.  
  2160.  
  2161. static void printstatus(mesg)
  2162. char *mesg;
  2163. {
  2164.    int i;
  2165.    move(STATUS_Y, STATUS_X);
  2166.    for (i = 0; i < STATUS_WIDE && mesg[i]; i++)
  2167.       addch(mesg[i]);
  2168. }
  2169.  
  2170.  
  2171. static int getLine(query, dst, maxLen)    /* char *, char *, int */
  2172. char *query, *dst;
  2173. int maxLen;
  2174. {
  2175.    int qLen, dLen;
  2176.    char c;
  2177.    mvaddstr(23, 1, query);
  2178.    clrtoeol();
  2179.    dLen = 0;
  2180.    qLen = strlen(query);
  2181.    do {
  2182.       move(23, qLen + 1 + dLen);
  2183.       refresh();
  2184.       c = getKeyLine();
  2185.       if (isprint(c) && dLen < maxLen) {
  2186.      move(23, qLen + dLen + 1);
  2187.      refresh();
  2188.      addch(c);
  2189.      dst[dLen++] = c;
  2190.       } else if (dLen && (c == '\b' || c == '\177')) {
  2191.      dLen--;
  2192.      move(23, qLen + dLen + 1);
  2193.      addch(' ');
  2194.       }
  2195.    }
  2196.    while (c != '\n' && c != '\r');
  2197.    dst[dLen] = 0;
  2198.    move(23, 1);
  2199.    clrtoeol();
  2200.    return dLen;
  2201. }
  2202.  
  2203.  
  2204. static int askYNAscii(query, def)
  2205. char *query;
  2206. int def;
  2207. {
  2208.    static char *yn[] =
  2209.    {" (y/N)? ", " (Y/n)? "};
  2210.    char line[80];
  2211.    char buf[3];
  2212.  
  2213.    strcpy(line, query);
  2214.    strcat(line, yn[def]);
  2215.    if (getLine(line, buf, 2)) {
  2216.       if (*buf == 'Y' || *buf == 'y')
  2217.      return 1;
  2218.       if (*buf == 'N' || *buf == 'n')
  2219.      return 0;
  2220.    }
  2221.    return def;;
  2222. }
  2223.  
  2224.  
  2225. static void setCursor(x, y)
  2226. int x, y;
  2227. {
  2228.    move(TOP + y, LEFT + 2 * x);
  2229. }
  2230.  
  2231.  
  2232. static void printNStr(s, n)
  2233. char *s;
  2234. int n;
  2235. {
  2236.    int i;
  2237.    for (i = 0; i < n && s[i]; i++)
  2238.       addch(s[i]);
  2239. }
  2240.  
  2241.  
  2242. static void drawTreeAscii0(n)
  2243. nodep n;
  2244. {
  2245.    property *p;
  2246.  
  2247.    move(TREE_Y, TREE_X + 1);
  2248.    printw(" Node #%d: ", n->nodeNum);
  2249.    if (p = getprop(n, t_Name)) {
  2250.       int num, width;
  2251.  
  2252.       width = TREEWIDE - 10;
  2253.       num = n->nodeNum;
  2254.       do {
  2255.      num /= 10;
  2256.      width--;
  2257.       } while (num);
  2258.       printNStr(p->data.comment, width);
  2259.    }
  2260.    clrtoeol();
  2261.    {
  2262.       int temp;
  2263.       if (treeLine < 0)
  2264.      treeLine = 0;
  2265.       else {
  2266.      temp = treeCountSiblings(n) - TREEHIGH + 1;
  2267.      temp = MAX(temp, 0);
  2268.      treeLine = treeLine > temp ? temp : treeLine;
  2269.       }
  2270.    }
  2271.    {
  2272.       nodep ch;
  2273.       int index;
  2274.       index = 0;
  2275.       ch = nthChild(n, treeLine);
  2276.       while (ch && index < TREEHIGH - 1) {
  2277.      move(index + TREE_Y + 1, TREE_X);
  2278.      printw("%c:", 'A' + index + treeLine);
  2279.      clrtoeol();
  2280.      if (p = getprop(ch, t_Name))
  2281.         printNStr(p->data.comment, 80 - (TREE_X + 3));
  2282.      ch = ch->nextSibling;
  2283.      index++;
  2284.       }
  2285.       while (index < TREEHIGH - 1) {
  2286.      move(index++ + TREE_Y + 1, TREE_X);
  2287.      clrtoeol();
  2288.       }
  2289.       move(TREE_Y + TREEHIGH - 1, TREE_X - 1);
  2290.       addch(ch ? '+' : ' ');
  2291.       move(TREE_Y + 1, TREE_X - 1);
  2292.       addch(treeLine ? '-' : ' ');
  2293.    }
  2294.    refresh();
  2295. }
  2296.  
  2297.  
  2298. /* draw the tree children when node currently is at n */
  2299. static void drawTreeAscii(n)
  2300. nodep n;
  2301. {
  2302.    treeLine = 0;
  2303.    drawTreeAscii0(n);
  2304. }
  2305.  
  2306.  
  2307. static void closeAscii()
  2308. {
  2309.    endwin();
  2310. }
  2311.  
  2312.  
  2313. static void refreshAscii()
  2314. {
  2315.    refresh();
  2316. }
  2317.  
  2318. static char boardPiece(x, y)
  2319. int x, y;
  2320. {
  2321.    return
  2322.  
  2323.       (((boardsize == 19 && x == 9) || (boardsize >= 10 && (x == 3 || x == boardsize - 4))
  2324.     || (boardsize > 6 && boardsize < 10 && (x == 2 || x == boardsize - 3)))
  2325.        &&
  2326.        ((boardsize == 19 && y == 9) || (boardsize >= 10 && (y == 3 || y == boardsize - 4))
  2327.     || (boardsize > 6 && boardsize < 10 && (y == 2 || y == boardsize - 3)))
  2328.       )
  2329.       ? chars[(int) CHAR_HANDICAP] : chars[(int) CHAR_NOTHING];
  2330. }
  2331.  
  2332.  
  2333.  
  2334.  
  2335. static void plotPieceAscii(b, i, j)
  2336. pBoard b;
  2337. int i, j;
  2338. {
  2339.    piece p;
  2340.    char c;
  2341.    p = boardGet(b, i, j);
  2342.    switch (p) {
  2343.       case P_NOTHING:
  2344.      c = boardPiece(i, j);
  2345.      break;
  2346.       case P_BLACK:
  2347.      c = chars[(int) CHAR_BLACK];
  2348.      break;
  2349.       case P_WHITE:
  2350.      c = chars[(int) CHAR_WHITE];
  2351.      break;
  2352.       case P_DAME:
  2353.      c = chars[(int) CHAR_DAME];
  2354.      break;
  2355.       case P_BLACKTERR:
  2356.      c = chars[(int) CHAR_BLACKTERR];
  2357.      break;
  2358.       case P_WHITETERR:
  2359.      c = chars[(int) CHAR_WHITETERR];
  2360.      break;
  2361.    }
  2362.    drawPiece(i, j, c);
  2363. }
  2364.  
  2365.  
  2366. static char *savetype[] =
  2367. {"long ", "short"};
  2368.  
  2369. static void highlightAscii(x, y, movenum, turn)
  2370. int x, y, movenum, turn;
  2371. {
  2372.    extern int madechanges;
  2373.    if (movenum > 0 && x >= 0) {
  2374.       move(23, 1);
  2375.       printw("%s #%d ",
  2376.          turn ? "White" : "Black",
  2377.          movenum);
  2378.       if (x == PASSVAL && y == PASSVAL)
  2379.      printw("Pass      ");
  2380.       else
  2381.      printw("at %c%d  ", xAxisChars[x], boardsize - y);
  2382.    } else {
  2383.       move(23, 1);
  2384.       clrtoeol();
  2385.    }
  2386.    drawPrisoners();
  2387.    move(COMMAND_Y, COMMAND_X + 15);
  2388.    if (tutor)
  2389.       printw("tutor");
  2390.    else if (madechanges)
  2391.       printw("edit ");
  2392.    else
  2393.       printw("read ");
  2394.    printw("    %s", savetype[saveShort ? 1 : 0]);
  2395.    refresh();
  2396. }
  2397.  
  2398. static void showCommentAscii(i)    /* display from line i onward */
  2399. int i;
  2400. {
  2401.    short line;
  2402.  
  2403.    /* line = MIN(commentLines() - i, COMMENT_HIGH); / */
  2404.    line = COMMENT_HIGH;
  2405.  
  2406.    move(COMMENT_Y, COMMENT_X - 1);
  2407.    addch(i ? '-' : ' ');
  2408.    move(COMMENT_Y + COMMENT_HIGH - 1, COMMENT_X - 1);
  2409.    addch(commentLines() - i > COMMENT_HIGH ? '+' : ' ');
  2410.  
  2411.    while (line--) {
  2412.       mvaddstr(line + COMMENT_Y, COMMENT_X, commentGet(line + i));
  2413.       clrtoeol();
  2414.    }
  2415.    refresh();
  2416. }
  2417.  
  2418. static void clearCommentAscii()
  2419. {
  2420.    int line;
  2421.  
  2422.    commentExists = false;
  2423.    for (line = COMMENT_Y; line < COMMENT_Y + COMMENT_HIGH; line++)
  2424.       move(line, COMMENT_X), clrtoeol();
  2425.    move(COMMENT_Y, COMMENT_X - 1);
  2426.    addch(' ');
  2427.    move(COMMENT_Y + COMMENT_HIGH - 1, COMMENT_X - 1);
  2428.    addch(' ');
  2429.    refresh();
  2430. }
  2431.  
  2432. static void displayCommentAscii(s)
  2433. char *s;
  2434. {
  2435.    commentExists = true;
  2436.    commentLine = 0;
  2437.    formatComment(s, COMMENT_WIDE);
  2438.    showCommentAscii(0);
  2439.    refresh();
  2440. }
  2441.  
  2442.  
  2443. static command charToCommand(c)
  2444. char c;
  2445. {
  2446.    int i;
  2447.    if ((c == ESC) || (c == CTRLC))
  2448.       return C_QUIT;
  2449.    for (i = (int) C_LASTCOMMAND + C_LASTOFS; i--;) {
  2450.       if (c == keys[i])
  2451.      break;
  2452.    }
  2453.    return (command) i;        /* -1 = not found */
  2454. }
  2455.  
  2456.  
  2457. static int getPointAscii()
  2458. {
  2459.    char c;
  2460.  
  2461.    setCursor(xcur, ycur);
  2462.    refresh();
  2463.    while (1) {
  2464.       c = getKeyScore();
  2465.       if (c == 'u')
  2466.      return (int) C_UNDO;
  2467.       if ((c == ESC) || (c == keys[(int) C_QUIT]))
  2468.      return (int) C_QUIT;
  2469.       if (c == 014)
  2470.      return (int) C_REDRAW;
  2471.       if ((c == '\r') || (c == '\n'))
  2472.      return (int) C_SCORE;
  2473.       if ((c == ' ') || (c == keys[(int) C_MOVE]))
  2474.      return (int) C_MOVE;
  2475.       switch (charToCommand(c)) {
  2476.      case C_CURLEFT:
  2477.         xcur = (xcur - 1 + boardsize) % boardsize;
  2478.         setCursor(xcur, ycur);
  2479.         refresh();
  2480.         break;
  2481.      case C_CURRIGHT:
  2482.         xcur = (xcur + 1) % boardsize;
  2483.         setCursor(xcur, ycur);
  2484.         refresh();
  2485.         break;
  2486.      case C_CURUP:
  2487.         ycur = (ycur - 1 + boardsize) % boardsize;
  2488.         setCursor(xcur, ycur);
  2489.         refresh();
  2490.         break;
  2491.      case C_CURDOWN:
  2492.         ycur = (ycur + 1) % boardsize;
  2493.         setCursor(xcur, ycur);
  2494.         refresh();
  2495.         break;
  2496.      case C_UPLEFT:
  2497.         ycur = (ycur - 1 + boardsize) % boardsize;
  2498.         xcur = (xcur - 1 + boardsize) % boardsize;
  2499.         setCursor(xcur, ycur);
  2500.         refresh();
  2501.         break;
  2502.      case C_UPRIGHT:
  2503.         xcur = (xcur + 1) % boardsize;
  2504.         ycur = (ycur - 1 + boardsize) % boardsize;
  2505.         setCursor(xcur, ycur);
  2506.         refresh();
  2507.         break;
  2508.      case C_DOWNLEFT:
  2509.         xcur = (xcur - 1 + boardsize) % boardsize;
  2510.         ycur = (ycur + 1) % boardsize;
  2511.         setCursor(xcur, ycur);
  2512.         refresh();
  2513.         break;
  2514.      case C_DOWNRIGHT:
  2515.         xcur = (xcur + 1) % boardsize;
  2516.         ycur = (ycur + 1) % boardsize;
  2517.         setCursor(xcur, ycur);
  2518.         refresh();
  2519.         break;
  2520.       }
  2521.    }
  2522. }
  2523.  
  2524.  
  2525.  
  2526.  
  2527. static char *edhelp[] =
  2528. {
  2529.    "                Comment Editor Help",
  2530.    "",
  2531.    " Cursor control as in emacs:",
  2532.    "    ^P: Previous line         ^N: Next line",
  2533.    "    ^B: Back one character    ^F: Forward one character",
  2534.    "    ^A: Beginning of line     ^E: End of line",
  2535.    "    ^D: Delete one character  ^K: Delete to end of line",
  2536.    "",
  2537.    " Press ^I to toggle insert mode",
  2538.    " Press ^W or ESC to exit and write your comment",
  2539.    " Press ^O to exit and keep the old comment",
  2540.    "",
  2541.    "  (Warning:  comments longer than the comment window",
  2542.    "             will be truncated if edited)",
  2543.    "",
  2544.    "",
  2545.    "                    Other Notes",
  2546.    "",
  2547.    "  When saving a file, * stands for the current file",
  2548.    "       (printed in the upper right corner)",
  2549.    "",
  2550.    "               Hit any key to return"
  2551. };
  2552.  
  2553.  
  2554.  
  2555.  
  2556. #define HALFWAY (((int)C_DOWNLEFT)/2)
  2557.  
  2558.  
  2559. char *fixkey(key, keystr)
  2560. char key;
  2561. char *keystr;
  2562. {
  2563.    if (key == keys[(int) C_QUIT])
  2564.       printw("ESC or ");
  2565.    if (key == keys[(int) C_MOVE])
  2566.       printw("Space or ");
  2567.    if (key < ' ') {
  2568.       keystr[0] = '^';
  2569.       keystr[1] = key + 64;
  2570.       keystr[2] = 0;
  2571.    } else {
  2572.       keystr[0] = key;
  2573.       keystr[1] = 0;
  2574.    }
  2575.    return keystr;
  2576. }
  2577.  
  2578.  
  2579. static void helpAscii()
  2580. {
  2581.    int i;
  2582.    extern char *helpStr[];
  2583.    char keystr[3];
  2584.    char ch;
  2585.  
  2586.    /* don't put anything here */
  2587.    preserveScreen();
  2588.    clear();
  2589.    move(0, 33);
  2590.    printw("MGT Version %s", VERSION);
  2591.    move(1, 12);
  2592.    printw("Written by Greg Hale        Enhancements by Adrian Mariano");
  2593.    move(2, 11);
  2594.    printw("(hale@scam.Berkely.edu)        (adrian@u.washington.edu)");
  2595.    for (i = 0; i < HALFWAY; i++) {
  2596.       move(i + 3, 8);
  2597.       printw("%s: %s", fixkey(keys[i], keystr), helpStr[i]);
  2598.       move(i + 3, 46);
  2599.       printw("%s: %s", fixkey(keys[i + HALFWAY], keystr), helpStr[i + HALFWAY]);
  2600.    }
  2601.    move(21, 8);
  2602.    printw("%c, %c: Scroll tree window", keys[C_TREESCROLLUP], keys[C_TREESCROLLDOWN]);
  2603.    move(21, 46);
  2604.    printw("%c, %c: Scroll comment window", keys[C_COMMENTSCROLLUP], keys[C_COMMENTSCROLLDOWN]);
  2605.    move(22, 8);
  2606.    printw("Uppercase letters visit variations");
  2607.    move(22, 46);
  2608.    for (i = (int) C_DOWNLEFT; i <= (int) C_UPRIGHT; i++)
  2609.       addch(keys[i]);
  2610.    printw(": Cursor movement");
  2611.    move(23, 21);
  2612.    printw("Hit return to return, any key to continue");
  2613.    refresh();
  2614.    ch = getKey();
  2615.    if (ch != '\r' && ch != '\n') {
  2616.       clear();
  2617.       for (i = 0; i < sizeof(edhelp) / sizeof(char *); i++)
  2618.      mvaddstr(i + 1, 10, edhelp[i]);
  2619.       refresh();
  2620.       ch = getKey();
  2621.       if (ch != '\r' && ch != '\n')
  2622.      specialHelp();
  2623.    }
  2624.    restoreScreen();
  2625. }
  2626.  
  2627.  
  2628.  
  2629. static int idleAscii(curnode)
  2630. nodep curnode;
  2631. {
  2632.    char c;
  2633.    command r;
  2634.    command com;
  2635.  
  2636.    highlightLast();
  2637.    setCursor(xcur, ycur);
  2638.    refresh();
  2639.  
  2640.    c = getKeyIdle();
  2641.    if (r = specialKeysIdle(c))
  2642.       return (int) r;
  2643.    r = C_NOTHING;
  2644.    if (c >= 'A' && c <= 'Z') {
  2645.       r = (command) ((char) C_CHOSECHILD + (c - 'A'));
  2646.    } else
  2647.       switch (c) {
  2648.      case ' ':
  2649.         return (int) C_MOVE;
  2650.      case '?':
  2651.         helpAscii();
  2652.         return (int) C_NOTHING;
  2653.      default:
  2654.         com = charToCommand(c);
  2655.         switch (com) {
  2656.            case C_QUIT:
  2657.           {
  2658.              char buf[5];
  2659.              if (c != ESC) {
  2660.             getLine("Quit (y/N)?", buf, 1);
  2661.             if (buf[0] == 'y')
  2662.                r = C_QUIT;
  2663.              } else
  2664.             r = C_QUIT;
  2665.           }
  2666.           break;
  2667.            case C_VIDEO:
  2668.           inverseFlag = !inverseFlag;
  2669.           return (int) C_REDRAW;
  2670.            case C_COMMENTSCROLLDOWN:
  2671.           {
  2672.              if (commentLine < commentLines() - COMMENT_HIGH)
  2673.             commentLine += COMMENT_HIGH - 1;
  2674.              showCommentAscii(commentLine);
  2675.           }
  2676.           break;
  2677.            case C_COMMENTSCROLLUP:
  2678.           if (commentLine) {
  2679.              commentLine -= COMMENT_HIGH - 1;
  2680.              showCommentAscii(commentLine);
  2681.           }
  2682.           break;
  2683.            case C_TREESCROLLDOWN:
  2684.           treeLine++;
  2685.           drawTreeAscii0(curnode);
  2686.           break;
  2687.            case C_TREESCROLLUP:
  2688.           treeLine--;
  2689.           drawTreeAscii0(curnode);
  2690.           break;
  2691.            default:
  2692.           r = (command) com;
  2693.         }
  2694.       }
  2695.    return (int) r;
  2696. }
  2697.  
  2698.  
  2699. #define MATCH(string,action) if (!strncmp((*env), (string), strlen(string))){ \
  2700.                                (*env) += strlen(string);\
  2701.                                action;\
  2702.                              } else
  2703.  
  2704. static void readEnvAscii(env)
  2705. char **env;
  2706. {
  2707.    MATCH("ASCCOM:", strncpy(keys, (*env), (int) C_REDRAW + 1))
  2708.       MATCH("ASCCHAR:", strncpy(chars, (*env), (int) ASC_NUMCHARS))
  2709.       MATCH("ASCINV", inverseFlag = 1)
  2710. #ifdef MGT_IBM
  2711.       MATCH("ASCNOGRAPH", graphics = 0)
  2712.       MATCH("ASCMOUSENORM", graphicalCursor = 0)
  2713.       MATCH("ASCNOCOLOR", usecolor = 0;
  2714.    graphics = 0)
  2715.       MATCH("ASCBCOL:", blackstone = atoi(*env))
  2716.       MATCH("ASCWCOL:", whitestone = atoi(*env))
  2717.       MATCH("ASCDAME:", damecolor = atoi(*env))
  2718.       MATCH("ASCBOARD:", boardcolor = atoi(*env))
  2719.       MATCH("ASCBG:", background = atoi(*env))
  2720.       MATCH("ASCFG:", foreground = atoi(*env))
  2721.       MATCH("ASCMARK:", markcolor = atoi(*env))
  2722.       MATCH("ASCLET:", lettercolor = atoi(*env))
  2723.       MATCH("ASCMENUBG:", menubg = atoi(*env))
  2724.       MATCH("ASCMENUFG:", menufg = atoi(*env))
  2725.       MATCH("RED:", bred = atoi(*env))
  2726.       MATCH("GREEN:", bgreen = atoi(*env))
  2727.       MATCH("BLUE:", bblue = atoi(*env))
  2728. #endif
  2729.       ;
  2730. }
  2731.  
  2732.  
  2733.  
  2734. char screen[WINHIGH + 1][WINWIDE + 1];
  2735.  
  2736.  
  2737. static void fixnewline(win, X, Y)
  2738. WINDOW *win;
  2739. int X, Y;
  2740. {
  2741.    if (X < WINWIDE && screen[Y][X] == '\n' &&
  2742.        screen[Y][X + 1]) {
  2743.       int myx, myy;
  2744.       for (myy = WINHIGH - 1; myy > Y; myy--)
  2745.      for (myx = 0; myx <= WINWIDE; myx++) {
  2746.         screen[myy + 1][myx] = screen[myy][myx];
  2747.         wmove(win, myy + 1, myx);
  2748.         waddch(win, screen[myy][myx] >= ' ' ?
  2749.            screen[myy][myx] : ' ');
  2750.      }
  2751.       for (myx = X + 1; myx <= WINWIDE; myx++) {
  2752.      screen[myy + 1][myx - X - 1] = screen[myy][myx];
  2753.      wmove(win, myy, myx);
  2754.      waddch(win, ' ');
  2755.      wmove(win, myy + 1, myx - X - 1);
  2756.      waddch(win, screen[myy][myx] >= ' ' ?
  2757.         screen[myy][myx] : ' ');
  2758.      screen[myy][myx] = 0;
  2759.       }
  2760.       for (myx = myx - X - 1; myx <= WINWIDE; myx++) {
  2761.      screen[myy + 1][myx] = 0;
  2762.      wmove(win, myy + 1, myx);
  2763.      waddch(win, ' ');
  2764.       }
  2765.       wrefresh(win);
  2766.    }
  2767. }
  2768.  
  2769.  
  2770. static void deletechar(win, x, y, x1, y1)
  2771. WINDOW *win;
  2772. int x, y, x1, y1;
  2773. {
  2774.    char c, k;
  2775.    c = screen[y][x];
  2776.    while (c && !(c == '\n' && x == WINWIDE) && x1 <= WINWIDE && y1 <= WINHIGH) {
  2777.       c = screen[y1][x1];
  2778.       screen[y][x] = c;
  2779.       wmove(win, y, x);
  2780.       if (c >= ' ')
  2781.      waddch(win, c);
  2782.       else if (!c || c == '\n')
  2783.      waddch(win, ' ');
  2784.       screen[y1][x1] = 0;
  2785.       wmove(win, y1, x1);
  2786.       waddch(win, ' ');
  2787.       if (x < WINWIDE)
  2788.      x++;
  2789.       else {
  2790.      x = 0;
  2791.      y++;
  2792.       }
  2793.       if (x1 < WINWIDE)
  2794.      x1++;
  2795.       else {
  2796.      x1 = 0;
  2797.      y1++;
  2798.       }
  2799.    }
  2800.    k = 0;
  2801.    for (x1 = 0; x1 <= WINWIDE; x1++)
  2802.       k |= screen[y1][x1];
  2803.    if (!k) {
  2804.       if (screen[y][x] == '\n')
  2805.      screen[y][x] = 0;
  2806.       for (y = y1 + 1; y <= WINHIGH; y++)
  2807.      for (x = 0; x <= WINWIDE; x++) {
  2808.         screen[y - 1][x] = screen[y][x];
  2809.         wmove(win, y - 1, x);
  2810.         waddch(win, screen[y][x] >= ' ' ? screen[y][x] : ' ');
  2811.      }
  2812.       for (x = 0; x <= WINWIDE; x++) {
  2813.      screen[WINHIGH][x] = 0;
  2814.      wmove(win, WINHIGH, x);
  2815.      waddch(win, ' ');
  2816.       }
  2817.    }
  2818. }
  2819.  
  2820.  
  2821. static void insertchar(win, c, x, y, mflag)
  2822. WINDOW *win;
  2823. char c;
  2824. int x, y;
  2825. char mflag;
  2826. {
  2827.  
  2828.    int xend = -1, yend;
  2829.    char k;
  2830.    while (c && x <= WINWIDE && y <= WINHIGH) {
  2831.       k = screen[y][x];
  2832.       screen[y][x] = c;
  2833.       wmove(win, y, x);
  2834.       waddch(win, c >= ' ' ? c : ' ');
  2835.       if (x < WINWIDE)
  2836.      x++;
  2837.       else {
  2838.      x = 0;
  2839.      y++;
  2840.       }
  2841.       c = k;
  2842.       if (xend == -1) {
  2843.      xend = x;
  2844.      yend = y;
  2845.       }
  2846.    }
  2847.    for (y = 0; y <= WINHIGH; y++)
  2848.       for (x = 0; x <= WINWIDE; x++)
  2849.      if (screen[y][x] == '\n')
  2850.         fixnewline(win, x, y);
  2851.    if (mflag)
  2852.       wmove(win, yend + 1, 0);
  2853.    else
  2854.       wmove(win, yend, xend);
  2855. }
  2856.  
  2857.  
  2858. /* static void showall(win) WINDOW *win; { int xsave, ysave, x, y; char k;
  2859.  * xsave = xpos(win); ysave = ypos(win); for (x = 0; x <= WINWIDE; x++) for (y
  2860.  * = 0; y <= WINHIGH; y++) { wmove(win, y, x); k = screen[y][x]; if (!k)
  2861.  * waddch(win, 255); else if (k == ' ') waddch(win, 254); else if (k == '\n')
  2862.  * waddch(win, 1); else if (k == '\r') waddch(win, 2); else if (k < ' ')
  2863.  * waddch(win, 19); else waddch(win, k); } wmove(win, ysave, xsave);
  2864.  * wrefresh(win); } */
  2865.  
  2866.  
  2867.  
  2868. static void edit(inp, out, mesg)
  2869. char *inp, **out, *mesg;
  2870. {
  2871.    int x, y, x1, y1, insert;
  2872.    char c;
  2873.    char str[2000];
  2874.    char *s;
  2875.    WINDOW *win;
  2876.    char edithelp[80];
  2877.  
  2878.    sprintf(edithelp, EDHELP, mesg, mesg);
  2879.    notifyMessageAscii(edithelp);
  2880.  
  2881.  
  2882.    /* clearCommentAscii(); */
  2883.    openwin();
  2884.    insert = 1;
  2885.    for (y = 0; y < WINHIGH + 1; y++)
  2886.       for (x = 0; x < WINWIDE + 1; x++) {
  2887.      screen[y][x] = 0;    /* wmove(win,y,x); waddch(win,' '); */
  2888.       }
  2889.    /* wmove(win,0,0); */
  2890.    if (inp)
  2891.       for (s = inp, x = y = 0; *s && (x <= WINWIDE) && (y <= WINHIGH); s++) {
  2892.      screen[y][x] = *s;
  2893.      wmove(win, y, x);
  2894.      waddch(win, *s);
  2895.      if (*s == '\n') {
  2896.         x = 0;
  2897.         y++;
  2898.      } else if (x < WINWIDE)
  2899.         x++;
  2900.      else {
  2901.         x = 0;
  2902.         y++;
  2903.      }
  2904.       }
  2905.    wrefresh(win);
  2906.    if (!screen[0][0])
  2907.       screen[0][0] = '\n';
  2908.    do {
  2909.       fixcursor();
  2910.       c = getKeyEdit();
  2911.       x = xpos(win);
  2912.       y = ypos(win);
  2913.       if ((c >= ' ') && (c < 127)) {
  2914.      if (insert)
  2915.         insertchar(win, c, x, y, 0);
  2916.      else {
  2917.         if (screen[y][x] == '\n')
  2918.            insertchar(win, c, x, y, 0);
  2919.         else {
  2920.            screen[y][x] = c;
  2921.            waddch(win, c);
  2922.         }
  2923.      }
  2924.      wrefresh(win);
  2925.       }
  2926.       if (c == 'I' - 64)
  2927.      insert = !insert;
  2928.       if (c == 'K' - 64) {
  2929.      x1 = x;
  2930.      y1 = y;
  2931.      for (; x < WINWIDE; x++) {
  2932.         screen[y][x] = 0;
  2933.         wmove(win, y, x);
  2934.         waddch(win, ' ');
  2935.      }
  2936.      screen[y1][x1] = '\n';
  2937.      wmove(win, y1, x1);
  2938.      wrefresh(win);
  2939.       }
  2940.       if ((c == '\n') || (c == '\r')) {
  2941.      if (y < WINHIGH)
  2942.         insertchar(win, '\n', x, y, 1);
  2943.      else {
  2944.         int xsave;
  2945.         xsave = x;
  2946.         screen[y][x] = '\n';
  2947.         waddch(win, ' ');
  2948.         for (x++; x <= WINWIDE; x++) {
  2949.            screen[y][x] = 0;
  2950.            waddch(win, ' ');
  2951.         }
  2952.         wmove(win, y, xsave);
  2953.      }
  2954.      wrefresh(win);
  2955.       }
  2956.       if (c == CTRLD) {
  2957.      y1 = y;
  2958.      x1 = x;
  2959.      if (x1 < WINWIDE) {
  2960.         x1++;
  2961.         if (!screen[y1][x1]) {
  2962.            x1 = 0;
  2963.            y1++;
  2964.         }
  2965.      } else {
  2966.         x1 = 0;
  2967.         y1++;
  2968.      }
  2969.      deletechar(win, x, y, x1, y1);
  2970.      wmove(win, y, x);
  2971.      wrefresh(win);
  2972.       }
  2973.       if ((c == '\b' || c == '\177') && (y || x)) {
  2974.      y1 = y;
  2975.      x1 = x;
  2976.      if (x)
  2977.         x--;
  2978.      else {
  2979.         y--;
  2980.         for (x = WINWIDE; !screen[y][x]; x--);
  2981.      }
  2982.      deletechar(win, x, y, x1, y1);
  2983.      wmove(win, y, x);
  2984.      wrefresh(win);
  2985.       }
  2986.       if ((c == CUP) && (y)) {
  2987.      y--;
  2988.      for (; x > 0 && !screen[y][x]; x--);
  2989.      wmove(win, y, x);
  2990.      wrefresh(win);
  2991.       }
  2992.       if ((c == DOWN) && (y < WINHIGH)) {
  2993.      y++;
  2994.      for (; x > 0 && !screen[y][x]; x--);
  2995.      if (!screen[y][x])
  2996.         screen[y][x] = '\n';
  2997.      wmove(win, y, x);
  2998.      wrefresh(win);
  2999.       }
  3000.       if ((c == CLEFT) && (y || x)) {
  3001.      if (x)
  3002.         x--;
  3003.      else {
  3004.         y--;
  3005.         x = WINWIDE;
  3006.         for (; x > 0 && !screen[y][x]; x--);
  3007.      }
  3008.      wmove(win, y, x);
  3009.      wrefresh(win);
  3010.       }
  3011.       if ((c == CRIGHT) && !((x == WINWIDE) && (y == WINHIGH))) {
  3012.      if (x < WINWIDE) {
  3013.         x++;
  3014.         if (!screen[y][x]) {
  3015.            y++;
  3016.            x = 0;
  3017.         }
  3018.      } else {
  3019.         y++;
  3020.         x = 0;
  3021.      }
  3022.      for (; x > 0 && !screen[y][x]; x--);
  3023.      if (!screen[y][x])
  3024.         screen[y][x] = '\n';
  3025.      wmove(win, y, x);
  3026.      wrefresh(win);
  3027.       }
  3028.       if (c == CEND) {
  3029.      for (x = WINWIDE; x > 0 && !screen[y][x]; x--);
  3030.      if (x < WINWIDE && screen[y][x] && screen[y][x] != '\n')
  3031.         x++;
  3032.      wmove(win, y, x);
  3033.      wrefresh(win);
  3034.       }
  3035.       if (c == CHOME) {
  3036.      wmove(win, y, 0);
  3037.      wrefresh(win);
  3038.       }
  3039.       if (c == CTRLW)
  3040.      c = ESC;
  3041.    }
  3042.    while (c != ESC && c != CTRLO);
  3043.    closewin();
  3044.    notifyClearAscii();
  3045.    if (c == CTRLO)
  3046.       *out = inp;
  3047.    else {
  3048.       for (y = WINHIGH; y >= 0; y--)
  3049.      for (x = WINWIDE; x >= 0; x--)
  3050.         if ((screen[y][x] == 0) || (screen[y][x] == '\n'))
  3051.            screen[y][x] = 0;
  3052.         else
  3053.            y = x = 0;
  3054.       strcpy(str, "");
  3055.       s = str;
  3056.       for (y = 0; y <= WINHIGH; y++)
  3057.      for (x = 0; x <= WINWIDE && screen[y][x]; x++, s++)
  3058.         *s = screen[y][x];
  3059.       *s = 0;
  3060.       if (inp)
  3061.      free(inp);
  3062.       *out = dupStr(str);
  3063.    }
  3064.  
  3065. }
  3066.  
  3067.  
  3068.  
  3069. static char *names[] =
  3070. {
  3071.    " Size        ",
  3072.    " Handicap    ",
  3073.    " Komi        ",
  3074.    " playerBlack ",
  3075.    " bLackrank   ",
  3076.    " playerWhite ",
  3077.    " whIterank   ",
  3078.    " Gamename    ",
  3079.    " Event       ",
  3080.    " rouNd       ",
  3081.    " Date        ",
  3082.    " Place       ",
  3083.    " Time        ",
  3084.    " Result      ",
  3085.    " gameComment ",
  3086.    " sOurce      ",
  3087.    " User        "
  3088. };
  3089.  
  3090.  
  3091.  
  3092.  
  3093. getInfoToChange()
  3094. {
  3095.    static char convert[] = "SHBLWIGENDPTRCOUK";
  3096.    static flag = 0;
  3097.    static char savearea[28][17];
  3098.    static WINDOW *wi;
  3099.    static char didhelp = 0;
  3100.  
  3101.    char ch;
  3102.    int con;
  3103.    if (flag == 1) {
  3104.       flag = 0;
  3105.       return t_BlackRank;
  3106.    }
  3107.    if (flag == 2) {
  3108.       flag = 0;
  3109.       return t_WhiteRank;
  3110.    }
  3111.    notifyClearAscii();
  3112.    notifyMessageAscii("Press capital letter to edit info field (? for list) or return to exit");
  3113.    while (1) {
  3114.       ch = getKey();
  3115.       if (ch == 'W')
  3116.      flag = 2;
  3117.       if (ch == 'B')
  3118.      flag = 1;
  3119.       if (ch == '?') {
  3120.      saveRegion(16, 3, 13, 17);
  3121.      for (ch = 0; ch < 17; ch++)
  3122.         mvaddstr(ch + 3, 16, names[ch]);
  3123.      refresh();
  3124.      didhelp = 1;
  3125.       }
  3126.       if (ch == keys[C_COMMENTSCROLLDOWN]) {
  3127.      if (commentLine < commentLines() - COMMENT_HIGH)
  3128.         commentLine += COMMENT_HIGH - 1;
  3129.      showCommentAscii(commentLine);
  3130.       } else if (ch == keys[C_COMMENTSCROLLUP])
  3131.      if (commentLine) {
  3132.         commentLine -= COMMENT_HIGH - 1;
  3133.         showCommentAscii(commentLine);
  3134.      }
  3135.       for (con = strlen(convert); con--;)
  3136.      if (ch == convert[con]) {
  3137.         notifyClearAscii();
  3138.         return (int) t_Size + con;
  3139.      }
  3140.       if (ch == '\n' || ch == '\r' || ch == ESC) {
  3141.      notifyClearAscii();
  3142.      if (didhelp) {
  3143.         restoreRegion(16, 3, 13, 17);
  3144.         didhelp = 0;
  3145.      }
  3146.      return (int) t_EOF;
  3147.       }
  3148.    }
  3149. }
  3150.  
  3151.  
  3152. static char *editName[] =
  3153. {"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: "};
  3154.  
  3155.  
  3156. static void editInfo(in, out, prop)
  3157. char *in, **out;
  3158. Token prop;
  3159. {
  3160.    if (prop == t_Size || prop == t_Handicap || prop == t_BlackRank
  3161.        || prop == t_WhiteRank || prop == t_Komi) {
  3162.       if (in)
  3163.      free(in);
  3164.       *out = (char *) malloc(21);
  3165.       getLine(editName[prop - FIRSTINFO + 2], *out, 20);
  3166.    } else
  3167.       edit(in, out, editName[prop - FIRSTINFO + 2]);
  3168. }
  3169.  
  3170.  
  3171. static void commentEdit(in, out)
  3172. char *in, **out;
  3173. {
  3174.    edit(in, out, "comment");
  3175. }
  3176.  
  3177.  
  3178.  
  3179. interface asciiInterface =
  3180. {
  3181.    (char *) 0,
  3182.    (char *) 0,
  3183.    (char *) 0,
  3184.    (pfi) initAscii,
  3185.    (pfi) closeAscii,
  3186.    (pfi) refreshAscii,
  3187.    (pfi) plotPieceAscii,
  3188.    (pfi) displayCommentAscii,
  3189.    (pfi) clearCommentAscii,
  3190.    (pfi) initBoardAscii,
  3191.    (pfi) clearScreenAscii,
  3192.    idleAscii,
  3193.    (pfi) drawTreeAscii,
  3194.    (pfi) highlightAscii,
  3195.    (pfi) readEnvAscii,
  3196.    (pfi) notifyMessageAscii,
  3197.    (pfi) notifyClearAscii,
  3198.    getLine,
  3199.    (pfi) setCursor,
  3200.    (pfi) plotMarkAscii,
  3201.    (pfi) drawPiece,
  3202.    getPointAscii,
  3203.    (pfi) commentEdit,
  3204.    askYNAscii,
  3205.    (pfi) notifyErrorAscii,
  3206.    (pfi) displayCommentAscii,
  3207.    getInfoToChange,
  3208.    (pfi) editInfo
  3209. };
  3210. SHAR_EOF
  3211. fi
  3212. if test -f 'build.c'
  3213. then
  3214.     echo shar: "will not over-write existing file 'build.c'"
  3215. else
  3216. cat << \SHAR_EOF > 'build.c'
  3217. /* "mgt" Copyright (c) 1991 Shodan  */
  3218.  
  3219. #include "mgt.h"
  3220.  
  3221. int lastMoveX, lastMoveY, moveNum, lastTurn;
  3222. coordList *lastletters = 0, *lastmarks;
  3223. coordList *marks = 0;
  3224. coordList *letters = 0;
  3225.  
  3226.  
  3227. FUNCTION void clearLast()
  3228. {
  3229.    lastMoveX = lastMoveY = -1;
  3230.    moveNum = 0;
  3231. }
  3232.  
  3233. FUNCTION void highlightLast()
  3234. {
  3235.    extern Token curPlayer;
  3236.    if (lastMoveX >= 0 && moveNum > 0 && lastTurn != (int) t_EOF)
  3237.       curPlayer = lastTurn ? t_Black : t_White;
  3238.    (*io->highlightLast) (lastMoveX, lastMoveY, moveNum, lastTurn);
  3239.  
  3240. }
  3241.  
  3242.  
  3243. FUNCTION void doPlace(p, b, t)
  3244. property *p;
  3245. pBoard b;
  3246. piece t;
  3247. {
  3248.    coordList *list;
  3249.  
  3250.    list = p->data.stones;
  3251.    while (list) {
  3252.       placeStone(b, list->x, list->y, t);
  3253.       list = list->next;
  3254.    }
  3255.    if (p->t == t_Black || p->t == t_White)
  3256.       moveNum++;
  3257.  
  3258. }
  3259.  
  3260.  
  3261.  
  3262.  
  3263. FUNCTION void doProps(p, b)
  3264. property *p;
  3265. pBoard b;
  3266. {
  3267.    letters = NULL;
  3268.    marks = NULL;
  3269.    while (p) {
  3270.       switch (p->t) {
  3271.      case t_White:
  3272.         BUG("t_White ");
  3273.         doPlace(p, b, P_WHITE);
  3274.         break;
  3275.      case t_Black:
  3276.         BUG("t_Black ");
  3277.         doPlace(p, b, P_BLACK);
  3278.         break;
  3279.      case t_AddWhite:
  3280.         BUG("t_AddWhite ");
  3281.         doPlace(p, b, P_WHITE);
  3282.         break;
  3283.      case t_AddBlack:
  3284.         BUG("t_AddBlack ");
  3285.         doPlace(p, b, P_BLACK);
  3286.         break;
  3287.      case t_AddEmpty:
  3288.         BUG("t_AddEmpty ");
  3289.         doPlace(p, b, P_NOTHING);
  3290.         break;
  3291.      case t_Comment:
  3292.         break;
  3293.      case t_Pass:
  3294.         moveNum++;
  3295.         break;
  3296.      case t_Mark:
  3297.         marks = p->data.stones;
  3298.         break;
  3299.      case t_Letter:
  3300.         letters = p->data.stones;
  3301.         BUG("t_Letter ");
  3302.         break;
  3303.      default:
  3304.         BUG("default ");
  3305.       }
  3306.       p = p->next;
  3307.    }
  3308. }
  3309.  
  3310. static void setLastMovePos(p)
  3311. property *p;
  3312. {
  3313.    lastTurn = p->t == t_White ? 1 : 0;
  3314.    if (p->data.stones) {
  3315.       lastMoveX = p->data.stones->x;
  3316.       lastMoveY = p->data.stones->y;
  3317.    } else
  3318.       lastMoveX = lastMoveY = -1;
  3319.  
  3320. }
  3321.  
  3322.  
  3323. FUNCTION void doPropComment(n)
  3324. nodep n;
  3325. {
  3326.    property *p;
  3327.  
  3328.    if (p = getprop(n, t_Comment))
  3329.       (*io->displayComment) (p->data.comment);
  3330.  
  3331.    if (p = getprop(n, t_Black))
  3332.       setLastMovePos(p);
  3333.    else if (p = getprop(n, t_White))
  3334.       setLastMovePos(p);
  3335.  
  3336.    if (p = getprop(n, t_Pass)) {
  3337.       lastTurn = p->data.player == t_White ? 1 : 0;
  3338.       lastMoveX = lastMoveY = PASSVAL;
  3339.    }
  3340. }
  3341.  
  3342. FUNCTION void buildTree0(n, b)
  3343. nodep n;
  3344. pBoard b;
  3345. {
  3346.    BUG("parent >");
  3347.    if (n) {
  3348.       buildTree0(n->parent, b);
  3349.       BUG("\nprops:");
  3350.       doProps(n->p, b);
  3351.    }
  3352. }
  3353.  
  3354.  
  3355.  
  3356. FUNCTION void buildTree(n, b)
  3357. nodep n;
  3358. pBoard b;
  3359. {
  3360.    extern int prisoners[];
  3361.    prisoners[0] = 0;
  3362.    prisoners[1] = 0;
  3363.    boardClear(b);
  3364.    (*io->clearComment) ();
  3365.    BUG("buildTree:\n");
  3366.    clearLast();
  3367.    buildTree0(n, b);
  3368.    doPropComment(n);
  3369. }
  3370.  
  3371.  
  3372. FUNCTION void setPiece(b, i, j, p)
  3373. pBoard b;
  3374. int i, j;
  3375. piece p;
  3376. {
  3377.    boardSet(b, i, j, p);
  3378.    (*io->plotPiece) (b, i, j);
  3379. }
  3380.  
  3381. FUNCTION void updateBoard(dst, new)
  3382. pBoard dst, new;        /* update dst to look like new */
  3383. {
  3384.    extern int prisoners[];
  3385.    int i, j;
  3386.    coordList *cl;
  3387.  
  3388.    for (cl = lastmarks; cl; cl = cl->next)
  3389.       (*io->plotPiece) (new, cl->x, cl->y);
  3390.  
  3391.    for (cl = lastletters; cl; cl = cl->next)
  3392.       (*io->plotPiece) (new, cl->x, cl->y);
  3393.    lastmarks = marks;
  3394.    lastletters = letters;
  3395.    for (i = boardsize; i--;)
  3396.       for (j = boardsize; j--;) {
  3397.      if (boardGet(new, i, j) != boardGet(dst, i, j)) {
  3398.         setPiece(dst, i, j, boardGet(new, i, j));
  3399.      }
  3400.       }
  3401.    if (marks) {
  3402.       for (cl = marks; cl; cl = cl->next)
  3403.      (*io->plotMark) (new, cl->x, cl->y);
  3404.       marks = NULL;
  3405.    }
  3406.    if (letters) {
  3407.       for (i = 0, cl = letters; cl; cl = cl->next, i++)
  3408.      (*io->plotLetter) (cl->x, cl->y, (i % 26) + 'a');
  3409.       letters = NULL;
  3410.    }
  3411. }
  3412. SHAR_EOF
  3413. fi
  3414. if test -f 'comment.c'
  3415. then
  3416.     echo shar: "will not over-write existing file 'comment.c'"
  3417. else
  3418. cat << \SHAR_EOF > 'comment.c'
  3419. /* "mgt" Copyright (c) 1991 Shodan  */
  3420.  
  3421. #include "mgt.h"
  3422. #include <string.h>
  3423. #include <ctype.h>
  3424.  
  3425.  
  3426. short clines;
  3427. char cbuf[MAXCOMMENTLINES][MAXCOMMENTWIDTH];
  3428. char *empty = "";
  3429.  
  3430. FUNCTION char *commentGet(line)    /* int */
  3431. int line;
  3432. {
  3433.    if (line < clines)
  3434.       return cbuf[line];
  3435.    else
  3436.       return empty;
  3437. }
  3438.  
  3439. FUNCTION int commentLines()
  3440. {
  3441.    return clines;
  3442. }
  3443.  
  3444.  
  3445.  
  3446.  
  3447. FUNCTION void formatComment(comment, width)
  3448. char *comment;
  3449. int width;
  3450. {
  3451.    char *partstart, *dest, c;
  3452.    int len, partlen, wordlen;
  3453.  
  3454.    clines = 0;
  3455.    width = MIN(width, MAXCOMMENTWIDTH - 1);
  3456.    wordlen = partlen = len = 0;
  3457.    dest = cbuf[0];
  3458.    if (*comment == '\n')
  3459.       comment++;
  3460.    partstart = comment;
  3461.    do {
  3462.       c = *(comment++);
  3463.       len++;
  3464.       partlen++;
  3465.       wordlen++;
  3466.       if (c == ' ')
  3467.      wordlen = 0;
  3468.       else if (c == '\n' && *(comment - 2) == ' ' &&
  3469.            *comment != '\n') {
  3470.      partlen--;
  3471.      len--;
  3472.      strncpy(dest, partstart, partlen);
  3473.      dest += partlen;
  3474.      partstart = comment;
  3475.      wordlen = partlen = 0;
  3476.       } else if (c == '\n' || !c) {
  3477.      strncpy(dest, partstart, partlen - 1);
  3478.      *(dest + partlen - 1) = 0;
  3479.      len = partlen = wordlen = 0;
  3480.      dest = cbuf[++clines];
  3481.      partstart = comment;
  3482.       }
  3483.       if (len == width) {
  3484.  
  3485.      if (len == wordlen)
  3486.         wordlen = 0;
  3487.  
  3488.      else
  3489.         len = partlen - wordlen;
  3490.  
  3491.      strncpy(dest, partstart, len);
  3492.      partstart += len;
  3493.      *(dest + len) = 0;
  3494.      len = partlen = wordlen;
  3495.  
  3496.      dest = cbuf[++clines];
  3497.       }
  3498.    } while (c && clines < MAXCOMMENTLINES);
  3499.  
  3500. }
  3501. SHAR_EOF
  3502. fi
  3503. if test -f 'doit.c'
  3504. then
  3505.     echo shar: "will not over-write existing file 'doit.c'"
  3506. else
  3507. cat << \SHAR_EOF > 'doit.c'
  3508. /* "mgt" Copyright (c) 1991 Shodan  */
  3509.  
  3510. #include "mgt.h"
  3511.  
  3512. int xcur, ycur;
  3513. Token curPlayer;
  3514. int change;
  3515. int madechanges;
  3516. int searchNodeNum;
  3517. int ispl = 0;
  3518.  
  3519. FUNCTION int okChange()
  3520. {
  3521.    if (tutor) {
  3522.       (*io->notifyError) ("Can't edit in tutor mode.");
  3523.       return 0;
  3524.    }
  3525.    if ((!change) && ((*io->askYN) ("Modify tree", 0)))
  3526.       change = 1;
  3527.    if (change)
  3528.       madechanges = 1;
  3529.    return change;
  3530. }
  3531.  
  3532.  
  3533.  
  3534. FUNCTION int okExit(root)
  3535. nodep root;
  3536. {
  3537.    if (mailFlag) {
  3538.       if (madechanges) {
  3539.      if (!(*io->askYN) ("Save", 1)) {
  3540.         retVal = 1;
  3541.         return 1;
  3542.      }
  3543.      if (writeTree(saveName, root))
  3544.         return 0;
  3545.      return 1;
  3546.       }
  3547.       retVal = 1;
  3548.       return 1;
  3549.    }
  3550.    if (madechanges) {
  3551.       if ((*io->askYN) ("Unsaved changes.  Exit without saving", 0))
  3552.      return 1;
  3553.       return 0;
  3554.    }
  3555.    return 1;
  3556. }
  3557.  
  3558.  
  3559.  
  3560. FUNCTION nodep search(n)    /* return 0 on failure */
  3561. nodep n;
  3562. {
  3563.    nodep s;
  3564.    if (!n || n->nodeNum == searchNodeNum)
  3565.       return n;
  3566.    s = search(child(n));
  3567.    if (s && s->nodeNum == searchNodeNum)
  3568.       return s;
  3569.    s = search(nextSibling(n));
  3570.    if (s && s->nodeNum == searchNodeNum)
  3571.       return s;
  3572.    return (nodep) 0;
  3573. }
  3574.  
  3575. FUNCTION void step(n, b)
  3576. nodep n;
  3577. pBoard b;
  3578. {
  3579.    board temp;
  3580.    buildTree(n, &temp);
  3581.    updateBoard(b, &temp);
  3582.    (*io->drawTree) (n);
  3583.    (*io->refreshIO) ();
  3584.    highlightLast();
  3585. }
  3586.  
  3587. FUNCTION void stepDown(n, b)
  3588. nodep n;
  3589. pBoard b;
  3590. {
  3591.    board temp;
  3592.    (*io->clearComment) ();
  3593.    copyBoard(b, &temp);
  3594.    doProps(n->p, &temp);
  3595.    doPropComment(n);
  3596.    updateBoard(b, &temp);
  3597.    (*io->drawTree) (n);
  3598.    (*io->refreshIO) ();
  3599.    highlightLast();
  3600. };
  3601.  
  3602.  
  3603. static char *color[] =
  3604. {
  3605.    "Black", "White"
  3606. };
  3607.  
  3608.  
  3609. int adjust(val, halfk, ksign)
  3610. int val, halfk, ksign;
  3611. {
  3612.    if (!halfk)
  3613.       return val;
  3614.    if (val * ksign >= 0)
  3615.       return val;
  3616.    return val + ksign;
  3617. }
  3618.  
  3619.  
  3620. FUNCTION void doScore(b, curNode)
  3621. pBoard b;
  3622. nodep curNode;
  3623. {
  3624.    extern int prisoners[];
  3625.    int savepris[2], lastpris[2];
  3626.    char out[200];
  3627.    command c;
  3628.    property *p;
  3629.    board new, old, last;
  3630.    int score[2], scored;
  3631.    char komicopy[10];
  3632.    int intkomi, halfkomi, kptr, komisign, winner, diff;
  3633.  
  3634.    winner = -1;
  3635.    scored = 0;
  3636.    lastpris[1] = savepris[1] = prisoners[1];
  3637.    lastpris[0] = savepris[0] = prisoners[0];
  3638.    copyBoard(b, &old);
  3639.    copyBoard(b, &last);
  3640.    copyBoard(b, &new);
  3641.    (*io->notifyClear) ();
  3642.    (*io->notifyMessage) ("return score, space kill, u undo, q quit");
  3643.    do {
  3644.       c = (command) (*io->getPoint) ();
  3645.       if (c == C_MOVE && (new.b[xcur][ycur] == P_WHITE ||
  3646.               new.b[xcur][ycur] == P_BLACK)
  3647.      ) {
  3648.      if (scored) {
  3649.         scored = 0;
  3650.         copyBoard(&last, &new);
  3651.         prisoners[1] = lastpris[1];
  3652.         prisoners[0] = lastpris[0];
  3653.      }
  3654.      copyBoard(&new, &last);
  3655.      lastpris[1] = prisoners[1];
  3656.      lastpris[0] = prisoners[0];
  3657.      removeStones(&new, xcur, ycur);
  3658.      updateBoard(b, &new);
  3659.       }
  3660.       if (c == C_UNDO) {
  3661.      copyBoard(&last, &new);
  3662.      prisoners[1] = lastpris[1];
  3663.      prisoners[0] = lastpris[0];
  3664.      updateBoard(b, &new);
  3665.       }
  3666.       if (c == C_SCORE && !scored) {
  3667.      copyBoard(&new, &last);
  3668.      lastpris[1] = prisoners[1];
  3669.      lastpris[0] = prisoners[0];
  3670.      scoreBoard(&new, score);
  3671.      updateBoard(b, &new);
  3672.      if (info[t_Komi - FIRSTINFO]) {
  3673.         halfkomi = 0;
  3674.         for (kptr = 0; info[t_Komi - FIRSTINFO][kptr]; kptr++) {
  3675.            if (info[t_Komi - FIRSTINFO][kptr] == '.') {
  3676.           kptr++;
  3677.           if (info[t_Komi - FIRSTINFO][kptr] >= '1' && info[t_Komi - FIRSTINFO][kptr] <= '9')
  3678.              halfkomi = 1;
  3679.           break;
  3680.            }
  3681.            komicopy[kptr] = info[t_Komi - FIRSTINFO][kptr];
  3682.         }
  3683.         komicopy[kptr] = 0;
  3684.         intkomi = atoi(komicopy);
  3685.         komisign = 0;
  3686.         if (komicopy[0] == '-' || intkomi < 0)
  3687.            komisign = -1;
  3688.         else if (intkomi > 0 || halfkomi)
  3689.            komisign = 1;
  3690.         sprintf(komicopy, "+ %s ", info[t_Komi - FIRSTINFO]);
  3691.      } else {
  3692.         komisign = intkomi = halfkomi = 0;
  3693.         strcpy(komicopy, "");
  3694.      }
  3695.  
  3696.      diff = score[1] + prisoners[0] - score[0] - prisoners[1] + intkomi;
  3697.  
  3698.      if (!diff) {
  3699.         if (halfkomi) {
  3700.            if (komisign > 0)
  3701.           winner = 1;
  3702.            else if (komisign < 0)
  3703.           winner = 0;
  3704.         } else
  3705.            winner = 2;
  3706.      } else
  3707.         winner = diff > 0 ? 1 : 0;
  3708.  
  3709.  
  3710.      diff = adjust(diff, halfkomi, komisign);
  3711.      sprintf(out,
  3712.          "Black: %d + %d = %d\n\nWhite: %d + %d %s= %s%d%s\n\n",
  3713.          score[0], prisoners[1], score[0] + prisoners[1],
  3714.          score[1], prisoners[0], komicopy, (!diff) && halfkomi && (komisign == -1) ? "-" : "",
  3715.          adjust(score[1] + prisoners[0] + intkomi, halfkomi, komisign),
  3716.          halfkomi ? ".5" : "");
  3717.      if (winner == 2)
  3718.         sprintf(out + strlen(out), "Tie game.");
  3719.      else
  3720.         sprintf(out + strlen(out), "%s wins by %d%s",
  3721.             color[winner], abs(diff), halfkomi ? ".5" : "");
  3722.  
  3723.  
  3724.      (*io->clearComment) ();
  3725.      (*io->displayComment) (out);
  3726.      scored = 1;
  3727.       }
  3728.    }
  3729.    while (c != C_QUIT);
  3730.  
  3731.    if (scored && (*io->askYN) ("Keep comment", 1) && okChange())
  3732.       replaceComment(curNode, out);
  3733.    else {
  3734.       (*io->clearComment) ();
  3735.       if (p = getprop(curNode, t_Comment))
  3736.      (*io->displayComment) (p->data.comment);
  3737.    }
  3738.  
  3739.    prisoners[0] = savepris[0];
  3740.    prisoners[1] = savepris[1];
  3741.  
  3742.    (*io->notifyClear) ();
  3743.    updateBoard(b, &old);
  3744. }
  3745.  
  3746.  
  3747.  
  3748. static void initBoard(b)
  3749. pBoard b;
  3750. {
  3751.    extern coordList *lastmarks, *lastletters;
  3752.  
  3753.    boardClear(b);
  3754.    (*io->initializeBoard) ();
  3755.    lastletters = lastmarks = 0;
  3756. }
  3757.  
  3758.  
  3759.  
  3760. FUNCTION nodep loadFile(filename, root, b)
  3761. char *filename;
  3762. nodep root;
  3763. board *b;
  3764. {
  3765.    openfile(filename);
  3766.    if (input) {
  3767.       madechanges = change = 0;
  3768.       freeNode(root);
  3769.       initNodes();
  3770.       readInit();
  3771.       root = parse(0);
  3772.       fclose(input);
  3773.       if (!root)
  3774.      root = newNode();
  3775.       initBoard(b);
  3776.       (*io->setCursor) (xcur, ycur);
  3777.       (*io->refreshIO) ();
  3778.       xcur = ycur = 0;
  3779.    } else
  3780.       (*io->notifyError) ("Unable to load file.");
  3781.    return root;
  3782. }
  3783.  
  3784.  
  3785. FUNCTION nodep makeTutor(nod, tok, x, y)
  3786. nodep nod;
  3787. Token tok;
  3788. int x, y;
  3789. {
  3790.    property *prop;
  3791.    if (!nod->child)
  3792.       return 0;
  3793.    nod = nod->child;
  3794.    while (!((prop = getprop(nod, tok)) && getCoord(x, y, prop->data.stones))) {
  3795.       if (!nod->nextSibling)
  3796.      return 0;
  3797.       nod = nod->nextSibling;
  3798.    }
  3799.    return nod;
  3800. }
  3801.  
  3802.  
  3803.  
  3804.  
  3805.  
  3806. static char *infotitle[] =
  3807. {
  3808.    "Game name: ",
  3809.    "Event: ",
  3810.    "rouNd: ",
  3811.    "Date: ",
  3812.    "Place: ",
  3813.    "Time limit: ",
  3814.    "Result: ",
  3815.    "Comment: ",
  3816.    "sOurce: ",
  3817.    "User: ",
  3818.    "Komi: "
  3819. };
  3820.  
  3821.  
  3822.  
  3823.  
  3824. static void showinfo()
  3825. {
  3826.    char infoarray[4000];
  3827.    char *infostr;
  3828.    int p;
  3829.  
  3830.    infostr = infoarray;
  3831.  
  3832.    sprintf(infostr, "Size: %d", boardsize);
  3833.    while (*infostr)
  3834.       infostr++;
  3835.    if (info[(int) t_Komi - FIRSTINFO]) {
  3836.       sprintf(infostr, "  Komi: %s", info[(int) t_Komi - FIRSTINFO]);
  3837.       while (*infostr)
  3838.      infostr++;
  3839.    }
  3840.    if (handicap) {
  3841.       sprintf(infostr, "  Handicap: %d", handicap);
  3842.       while (*infostr)
  3843.      infostr++;
  3844.    }
  3845.    *infostr = '\n';
  3846.    infostr++;
  3847.  
  3848.    if (info[0] || info[1]) {
  3849.       sprintf(infostr, "Black: %s%s%s\n", info[0] ? info[0] : "",
  3850.           info[0] && info[1] ? ", " : "",
  3851.           info[1] ? info[1] : "");
  3852.       while (*infostr)
  3853.      infostr++;
  3854.    }
  3855.    if (info[2] || info[3]) {
  3856.       sprintf(infostr, "White: %s%s%s\n", info[2] ? info[2] : "",
  3857.           info[2] && info[3] ? ", " : "",
  3858.           info[3] ? info[3] : "");
  3859.       while (*infostr)
  3860.      infostr++;
  3861.    }
  3862.    for (p = 0; p <= LASTINFO - FIRSTINFO - 4; p++) {
  3863.       if (info[p + 4]) {
  3864.      sprintf(infostr, "%s%s\n", infotitle[p], info[p + 4]);
  3865.      while (*infostr)
  3866.         infostr++;
  3867.       }
  3868.    }
  3869.    *infostr = 0;
  3870.    (*io->displayInfo) (infoarray);
  3871.  
  3872. }
  3873.  
  3874.  
  3875. #define BUFFERSIZE 50
  3876.  
  3877.  
  3878. static int doinfo()
  3879. {
  3880.    Token change;
  3881.    int sizechanged, value;
  3882.    char buffer[BUFFERSIZE + 1];
  3883.    char *current;
  3884.  
  3885.    sizechanged = 0;
  3886.    do {
  3887.       showinfo();
  3888.       change = (Token) (*io->getInfoToChange) ();
  3889.       if (change == t_EOF)
  3890.      break;
  3891.       if (!okChange())
  3892.      continue;
  3893.       if (change == t_Size) {
  3894.      sprintf(buffer, "%d", boardsize);
  3895.      current = dupStr(buffer);
  3896.      (*io->editInfo) (current, ¤t, t_Size);
  3897.      if (current) {
  3898.         value = atoi(current);
  3899.         if (value > 1 && value < 20) {
  3900.            if (value != boardsize)
  3901.           sizechanged = 1;
  3902.            boardsize = value;
  3903.         } free(current);
  3904.      }
  3905.       } else if (change == t_Handicap) {
  3906.      sprintf(buffer, "%d", handicap);
  3907.      current = dupStr(buffer);
  3908.      (*io->editInfo) (current, ¤t, t_Handicap);
  3909.      if (current) {
  3910.         handicap = atoi(current);
  3911.         free(current);
  3912.      }
  3913.       } else {
  3914.  
  3915.      (*io->editInfo) (info[(int) change - FIRSTINFO], &info[(int) change - FIRSTINFO],
  3916.               change);
  3917.      if (!strlen(info[(int) change - FIRSTINFO])) {
  3918.         free(info[(int) change - FIRSTINFO]);
  3919.         info[(int) change - FIRSTINFO] = 0;
  3920.      }
  3921.       }
  3922.  
  3923.  
  3924.    } while (1);
  3925.    return sizechanged;
  3926.  
  3927. }
  3928.  
  3929.  
  3930.  
  3931.  
  3932. static void savescreen(bord)
  3933. board *bord;
  3934. {
  3935.    char fname[75];
  3936.    int i, j;
  3937.    FILE *out;
  3938.    extern coordList *lastletters;
  3939.    extern int prisoners[];
  3940.    coordList *let;
  3941.    char local[19][19];
  3942.    if ((*io->queryStr) ("Save screen: ", fname, 74)) {
  3943.       if (out = fopen(fname, "a+t")) {
  3944.      fprintf(out, "%s to play.\n\n", curPlayer == t_Black ? "Black" : "White");
  3945.      fputs("  ", out);
  3946.      for (i = 0; i < boardsize; i++) {
  3947.         fputc(' ', out);
  3948.         fputc(i + 'A' + ((i + 'A' >= 'I') ? 1 : 0), out);
  3949.      }
  3950.      fputc('\n', out);
  3951.  
  3952.  
  3953.      for (j = 0; j < boardsize; j++)
  3954.         for (i = 0; i < boardsize; i++) {
  3955.            local[i][j] = ' ';
  3956.            switch (bord->b[i][j]) {
  3957.  
  3958.           case P_WHITE:
  3959.              local[i][j] = 'O';
  3960.              break;
  3961.           case P_BLACK:
  3962.              local[i][j] = '#';
  3963.              break;
  3964.  
  3965.           case P_NOTHING:
  3966.           default:
  3967.              local[i][j] = '.';
  3968.              break;
  3969.            }
  3970.         }
  3971.      let = lastletters;
  3972.      i = 0;
  3973.      while (let) {
  3974.         local[let->x][let->y] = i + 'a';
  3975.         i++;
  3976.         i %= 26;
  3977.         let = let->next;
  3978.  
  3979.  
  3980.      }
  3981.  
  3982.      for (j = 0; j < boardsize; j++) {
  3983.         fprintf(out, "%2d ", boardsize - j);
  3984.         for (i = 0; i < boardsize; i++) {
  3985.            fputc(local[i][j], out);
  3986.            fputc(' ', out);
  3987.         }
  3988.  
  3989.         fprintf(out, "%2d", boardsize - j);
  3990.         if (
  3991.           (j == boardsize / 2) && (prisoners[0] || prisoners[1]))
  3992.            fprintf(out, "  Captured #: %d   Captured O: %d", prisoners[0], prisoners[1]);
  3993.         fputc('\n', out);
  3994.      }
  3995.      fputs("  ", out);
  3996.      for (i = 0; i < boardsize; i++) {
  3997.         fputc(' ', out);
  3998.         fputc(i + 'A' + ((i + 'A' >= 'I') ? 1 : 0), out);
  3999.      }
  4000.  
  4001.      fputs("\n\n", out);
  4002.      for (i = 0; i < commentLines(); i++) {
  4003.         fputs(commentGet(i), out);
  4004.         putc('\n', out);
  4005.      }
  4006.  
  4007.      fclose(out);
  4008.       } else
  4009.      (*io->notifyError) ("Unable to open file.");
  4010.    }
  4011. }
  4012.  
  4013.  
  4014.  
  4015.  
  4016.  
  4017. FUNCTION void doit()
  4018. {
  4019.    int quitflg, i;
  4020.    nodep root, curNode;
  4021.    board theBoard;
  4022.    extern coordList *lastletters, *lastmarks;
  4023.  
  4024.    curPlayer = t_Black;
  4025.    xcur = ycur = quitflg = 0;
  4026.    root = 0;
  4027.    madechanges = 0;
  4028.    change = 1;
  4029.    if (input != stdin) {
  4030.       root = parse(0);
  4031.       fclose(input);
  4032.       change = 0;
  4033.    }
  4034.    if (!root)
  4035.       root = newNode();
  4036.    curNode = root;
  4037.    initBoard(&theBoard);
  4038.    (*io->setCursor) (xcur, ycur);
  4039.    (*io->refreshIO) ();
  4040.    if (mailFlag) {
  4041.       while (curNode->child)
  4042.      curNode = treeDown(curNode);
  4043.       change = 1;
  4044.    }
  4045.    step(curNode, &theBoard);
  4046.    while (!quitflg) {
  4047.       nodep tNode;
  4048.       command c;
  4049.       property *prop;
  4050.  
  4051.       if (prop = getprop(curNode, t_Player)) {
  4052.      extern Token lastTurn;
  4053.      curPlayer = prop->data.player;
  4054.      lastTurn = t_EOF;
  4055.      ispl = 1;
  4056.       } else
  4057.      ispl = 0;
  4058.  
  4059.       c = (command) (*io->idle) (curNode);
  4060.  
  4061.       if ((int) c >= (int) C_CHOSECHILD && (int) c < (int) C_NEXTCMD) {
  4062.      nodep new;
  4063.      new = nthChild(curNode, (int) c - (int) C_CHOSECHILD);
  4064.      if (new) {
  4065.         curNode = nthChild(curNode, (int) c - (int) C_CHOSECHILD);
  4066.         step(curNode, &theBoard);
  4067.      }
  4068.       } else
  4069.      switch (c) {
  4070.         case C_LOAD:
  4071.            if (okExit(root)) {
  4072.           char filename[50];
  4073.           if ((*io->queryStr) ("Load file? ", filename, 48)) {
  4074.              root = curNode = loadFile(filename, root, &theBoard);
  4075.              step(curNode, &theBoard);
  4076.           }
  4077.            }
  4078.            break;
  4079.         case C_BACKFILE:
  4080.  
  4081.            if (currentfile > 0 && okExit(root)) {
  4082.           currentfile--;
  4083.           root = curNode = loadFile(files[currentfile], root, &theBoard);
  4084.           step(curNode, &theBoard);
  4085.            } else
  4086.           (*io->notifyError) ("No previous file.");
  4087.            break;
  4088.  
  4089.  
  4090.         case C_NEXTFILE:
  4091.            if (currentfile + 1 < filecount && okExit(root)) {
  4092.           currentfile++;
  4093.           root = curNode = loadFile(files[currentfile], root, &theBoard);
  4094.           step(curNode, &theBoard);
  4095.            } else
  4096.           (*io->notifyError) ("No next file.");
  4097.            break;
  4098.  
  4099.         case C_INFO:
  4100.            if (doinfo())
  4101.           initBoard(&theBoard);
  4102.            step(curNode, &theBoard);
  4103.            if (xcur >= boardsize)
  4104.           xcur = boardsize - 1;
  4105.            if (ycur >= boardsize)
  4106.           ycur = boardsize - 1;
  4107.            break;
  4108.         case C_SAVESCREEN:
  4109.            savescreen(&theBoard);
  4110.            break;
  4111.         case C_REDRAW:
  4112.            {
  4113.           int savex, savey;
  4114.           savex = xcur;
  4115.           savey = ycur;
  4116.           initBoard(&theBoard);
  4117.           (*io->refreshIO) ();
  4118.           step(curNode, &theBoard);
  4119.           xcur = savex;
  4120.           ycur = savey;
  4121.           break;
  4122.            }
  4123.         case C_NOTHING:
  4124.            break;
  4125.         case C_TOPLAY:
  4126.            if (okChange())
  4127.           addPlayer(curNode, (curPlayer == t_Black) ? t_White : t_Black);
  4128.            break;
  4129.         case C_PASSMOVE:{
  4130.           int mod_cur_node;
  4131.           mod_cur_node = passMove(curNode, curPlayer);
  4132.           if (mod_cur_node)
  4133.              step(curNode, &theBoard);
  4134.           else {
  4135.              curNode = treeDown(curNode);
  4136.              stepDown(curNode, &theBoard);
  4137.           }
  4138.            }
  4139.            break;
  4140.  
  4141.  
  4142.         case C_TOGGLESTONE:{
  4143.           extern Token lastTurn;
  4144.           curPlayer = (curPlayer == t_Black) ? t_White : t_Black;
  4145.           lastTurn = t_EOF;
  4146.            }
  4147.  
  4148.            break;
  4149.         case C_TUTORSWAP:
  4150.            tutor = !tutor;
  4151.            break;
  4152.         case C_MOVE:
  4153.            if (tutor) {
  4154.           nodep save;
  4155.           save = curNode;
  4156.           if (curNode = makeTutor(curNode, curPlayer, xcur, ycur)) {
  4157.              step(curNode, &theBoard);
  4158.           } else {
  4159.              (*io->notifyError) ("Wrong move.");
  4160.              curNode = save;;
  4161.           }
  4162.            } else {
  4163.           if (okChange() && legal(&theBoard, curNode, curPlayer, xcur, ycur)) {
  4164.              int mod_cur_node;
  4165.              mod_cur_node = makeMove(curNode, curPlayer, xcur, ycur);
  4166.              curPlayer = (curPlayer == t_Black) ? t_White : t_Black;
  4167.              if (mod_cur_node)
  4168.             step(curNode, &theBoard);
  4169.              else {
  4170.             curNode = treeDown(curNode);
  4171.             stepDown(curNode, &theBoard);
  4172.              }
  4173.           }
  4174.            }
  4175.  
  4176.            break;
  4177.         case C_ADDVAR:
  4178.            if (okChange()) {
  4179.           makeVariation(curNode);
  4180.           step(curNode, &theBoard);
  4181.            }
  4182.            break;
  4183.         case C_DELNODE:
  4184.            if (okChange()) {
  4185.           deleteNode(&curNode);
  4186.           step(curNode, &theBoard);
  4187.            }
  4188.            break;
  4189.         case C_PASTE:
  4190.            if (okChange())
  4191.           if (pasteTree(curNode))
  4192.              step(curNode, &theBoard);
  4193.           else
  4194.              (*io->notifyError) ("Nothing to paste.");
  4195.            break;
  4196.  
  4197.         case C_TREECUT:
  4198.            if (okChange()) {
  4199.           nodep prevNode;
  4200.           int savex, savey;
  4201.           savex = xcur;
  4202.           savey = ycur;
  4203.           prevNode = curNode->parent;
  4204.           cutTree(curNode);
  4205.           curNode = prevNode;
  4206.           if (!curNode) {
  4207.              initNodes();
  4208.              root = curNode = newNode();
  4209.           }
  4210.           step(curNode, &theBoard);
  4211.           xcur = savex;
  4212.           ycur = savey;
  4213.           break;
  4214.            }
  4215.         case C_ADDBLACK:
  4216.            if (okChange()) {
  4217.           coordList *cl;
  4218.           property *prop;
  4219.           if (boardGet(&theBoard, xcur, ycur) == P_BLACK) {
  4220.              addStone(curNode, t_AddEmpty, xcur, ycur);
  4221.              setPiece(&theBoard, xcur, ycur, P_NOTHING);
  4222.           } else {
  4223.              addStone(curNode, t_AddBlack, xcur, ycur);
  4224.              setPiece(&theBoard, xcur, ycur, P_BLACK);
  4225.           }
  4226.           if (prop = getprop(curNode, t_Letter))
  4227.              lastletters = prop->data.stones;
  4228.           for (i = 0, cl = lastletters; cl; i++, cl = cl->next)
  4229.              (*io->plotLetter) (cl->x, cl->y, i % 26 + 'a');
  4230.            }
  4231.            break;
  4232.         case C_ADDWHITE:
  4233.            if (okChange()) {
  4234.           coordList *cl;
  4235.           property *prop;
  4236.           if (boardGet(&theBoard, xcur, ycur) == P_WHITE) {
  4237.              addStone(curNode, t_AddEmpty, xcur, ycur);
  4238.              setPiece(&theBoard, xcur, ycur, P_NOTHING);
  4239.           } else {
  4240.              addStone(curNode, t_AddWhite, xcur, ycur);
  4241.              setPiece(&theBoard, xcur, ycur, P_WHITE);
  4242.           }
  4243.           if (prop = getprop(curNode, t_Letter))
  4244.              lastletters = prop->data.stones;
  4245.  
  4246.           for (i = 0, cl = lastletters; cl; i++, cl = cl->next)
  4247.              (*io->plotLetter) (cl->x, cl->y, i % 26 + 'a');
  4248.  
  4249.            }
  4250.            break;
  4251.         case C_ADDLETTER:
  4252.            if (okChange()) {
  4253.  
  4254.  
  4255.  
  4256.           int sx, sy;
  4257.  
  4258.           for (; lastletters; lastletters = lastletters->next)
  4259.              (*io->plotPiece) (&theBoard, lastletters->x, lastletters->y);
  4260.           lastletters = 0;
  4261.  
  4262.           sx = xcur;
  4263.           sy = ycur;
  4264.  
  4265.  
  4266.           if (addMark(curNode, t_Letter, xcur, ycur))
  4267.              (*io->plotPiece) (&theBoard, xcur, ycur);
  4268.           stepDown(curNode, &theBoard);
  4269.           xcur = sx;
  4270.           ycur = sy;
  4271.            }
  4272.            break;
  4273.         case C_ADDMARK:
  4274.            if (okChange()) {
  4275.           int sx, sy;
  4276.  
  4277.           for (; lastmarks; lastmarks = lastmarks->next)
  4278.              (*io->plotPiece) (&theBoard, lastmarks->x, lastmarks->y);
  4279.           lastmarks = 0;
  4280.  
  4281.           sx = xcur;
  4282.           sy = ycur;
  4283.           if (addMark(curNode, t_Mark, xcur, ycur))
  4284.              (*io->plotPiece) (&theBoard, xcur, ycur);
  4285.  
  4286.           stepDown(curNode, &theBoard);
  4287.           xcur = sx;
  4288.           ycur = sy;
  4289.            }
  4290.            break;
  4291.         case C_EDCOMMENT:
  4292.            if (okChange()) {
  4293.           edComment(curNode);
  4294.           step(curNode, &theBoard);
  4295.            }
  4296.            break;
  4297.         case C_ADDNAME:
  4298.            if (okChange()) {
  4299.           makeName(curNode);
  4300.           step(curNode, &theBoard);
  4301.            }
  4302.            break;
  4303.         case C_DOWN:
  4304.            tNode = treeDown(curNode);
  4305.            if (tNode != curNode) {
  4306.           curNode = tNode;
  4307.           stepDown(curNode, &theBoard);
  4308.            }
  4309.            break;
  4310.         case C_UP:
  4311.            curNode = treeUp(curNode);
  4312.            step(curNode, &theBoard);
  4313.            break;
  4314.         case C_WALKDOWN:
  4315.            tNode = treeNext(curNode);
  4316.            if (tNode->parent == curNode) {
  4317.           stepDown(tNode, &theBoard);
  4318.            } else {
  4319.           step(tNode, &theBoard);
  4320.            }
  4321.            curNode = tNode;
  4322.            break;
  4323.         case C_WALKUP:
  4324.            curNode = treeLast(curNode);
  4325.            step(curNode, &theBoard);
  4326.            break;
  4327.         case C_SEARCHCOMMENT:
  4328.            {
  4329.           nodep tBegin;
  4330.           tBegin = curNode;
  4331.           tNode = curNode;
  4332.           do {
  4333.              tNode = treeNext(tNode);
  4334.           }
  4335.           while (tNode != tBegin && !getprop(tNode, t_Comment));
  4336.           if (tNode != curNode) {
  4337.              if (tNode->parent == curNode) {
  4338.             stepDown(tNode, &theBoard);
  4339.              } else {
  4340.             step(tNode, &theBoard);
  4341.              }
  4342.              curNode = tNode;
  4343.           }
  4344.            }
  4345.            break;
  4346.         case C_SEARCHBACKCOMMENT:
  4347.            tNode = curNode;
  4348.            curNode = curNode;
  4349.            do {
  4350.           curNode = treeLast(curNode);
  4351.            }
  4352.            while (curNode != tNode && !getprop(curNode, t_Comment));
  4353.            step(curNode, &theBoard);
  4354.            break;
  4355.         case C_UPFORK:
  4356.            while (curNode->parent) {
  4357.           curNode = curNode->parent;
  4358.           if (treeCountSiblings(curNode) > 1)
  4359.              break;
  4360.            }
  4361.            step(curNode, &theBoard);
  4362.            break;
  4363.         case C_DOWNFORK:
  4364.            {
  4365.           while (curNode->child) {
  4366.              curNode = treeDown(curNode);
  4367.              if (treeCountSiblings(curNode) > 1)
  4368.             break;
  4369.           }
  4370.           step(curNode, &theBoard);
  4371.            }
  4372.            break;
  4373.         case C_END:
  4374.            while (curNode->child) {
  4375.           curNode = treeDown(curNode);
  4376.            }
  4377.            step(curNode, &theBoard);
  4378.            break;
  4379.         case C_BEGINNING:
  4380.            curNode = root;
  4381.            step(curNode, &theBoard);
  4382.            break;
  4383.         case C_SCORE:
  4384.            doScore(&theBoard, curNode);
  4385.            break;
  4386.         case C_GOTO:
  4387.            {
  4388.           char buf[7];
  4389.           nodep new;
  4390.           if ((*io->queryStr) ("Move to node # ?", buf, 5)) {
  4391.              searchNodeNum = atoi(buf);
  4392.              if (searchNodeNum == 0 && strcmp(buf, "0"))
  4393.             searchNodeNum = -1;
  4394.              if (searchNodeNum >= 0) {
  4395.             if (new = search(root)) {
  4396.                curNode = new;
  4397.                step(curNode, &theBoard);
  4398.                (*io->notifyClear) ();
  4399.             } else {
  4400.                (*io->notifyClear) ();
  4401.                (*io->notifyError) ("Node not found.");
  4402.             }
  4403.  
  4404.              }
  4405.           }
  4406.            }
  4407.            break;
  4408.         case C_QUIT:
  4409.            if (okExit(root))
  4410.           quitflg++;
  4411.            break;
  4412.         case C_WRITE:
  4413.            {
  4414.           char filename[50];
  4415.           if ((*io->queryStr) ("Save name? ", filename, 48)) {
  4416.              if (!strcmp("*", filename)) {
  4417.             if (!writeTree(name_buf, root))
  4418.                madechanges = 0;
  4419.              } else {
  4420.             if (!writeTree(filename, root))
  4421.                madechanges = 0;
  4422.              }
  4423.           }
  4424.            }
  4425.            break;
  4426.         case C_SAVESHORT:
  4427.            saveShort = !saveShort;
  4428.            break;
  4429.         case C_CURLEFT:
  4430.            xcur = (xcur - 1 + boardsize) % boardsize;
  4431.            (*io->setCursor) (xcur, ycur);
  4432.            (*io->refreshIO) ();
  4433.            break;
  4434.         case C_CURRIGHT:
  4435.            xcur = (xcur + 1) % boardsize;
  4436.            (*io->setCursor) (xcur, ycur);
  4437.            (*io->refreshIO) ();
  4438.            break;
  4439.         case C_CURUP:
  4440.            ycur = (ycur - 1 + boardsize) % boardsize;
  4441.            (*io->setCursor) (xcur, ycur);
  4442.            (*io->refreshIO) ();
  4443.            break;
  4444.         case C_CURDOWN:
  4445.            ycur = (ycur + 1) % boardsize;
  4446.            (*io->setCursor) (xcur, ycur);
  4447.            (*io->refreshIO) ();
  4448.            break;
  4449.         case C_UPLEFT:
  4450.            ycur = (ycur - 1 + boardsize) % boardsize;
  4451.            xcur = (xcur - 1 + boardsize) % boardsize;
  4452.            (*io->setCursor) (xcur, ycur);
  4453.            (*io->refreshIO) ();
  4454.            break;
  4455.         case C_UPRIGHT:
  4456.            xcur = (xcur + 1) % boardsize;
  4457.            ycur = (ycur - 1 + boardsize) % boardsize;
  4458.            (*io->setCursor) (xcur, ycur);
  4459.            (*io->refreshIO) ();
  4460.            break;
  4461.         case C_DOWNLEFT:
  4462.            xcur = (xcur - 1 + boardsize) % boardsize;
  4463.            ycur = (ycur + 1) % boardsize;
  4464.            (*io->setCursor) (xcur, ycur);
  4465.            (*io->refreshIO) ();
  4466.            break;
  4467.         case C_DOWNRIGHT:
  4468.            xcur = (xcur + 1) % boardsize;
  4469.            ycur = (ycur + 1) % boardsize;
  4470.            (*io->setCursor) (xcur, ycur);
  4471.            (*io->refreshIO) ();
  4472.            break;
  4473.      }
  4474.    }
  4475. }
  4476. SHAR_EOF
  4477. fi
  4478. if test -f 'edit.c'
  4479. then
  4480.     echo shar: "will not over-write existing file 'edit.c'"
  4481. else
  4482. cat << \SHAR_EOF > 'edit.c'
  4483. /* "mgt" Copyright (c) 1991 Shodan  */
  4484.  
  4485. #include "mgt.h"
  4486.  
  4487. int first;
  4488. nodep buffer = 0;
  4489.  
  4490.  
  4491. FUNCTION void writeStrEscaped(output, s)
  4492. FILE *output;
  4493. char *s;
  4494. {
  4495.    while (*s) {
  4496.       if (*s == ')' || *s == '(' || *s == ']' || *s == '[')
  4497.      fputc('\\', output);
  4498.       fputc(*(s++), output);
  4499.    }
  4500. }
  4501.  
  4502.  
  4503. #define WRITE(short,long) if (saveShort) fputs(short,output);else fputs(long,output)
  4504.  
  4505.  
  4506. static char *infoshort[] =
  4507. {"PB", "BR", "PW", "WR",
  4508.  "GN", "EV", "RO", "DT", "PC", "TM", "RE", "GC",
  4509.  "SO", "US", "KM"};
  4510.  
  4511. static char *infolong[] =
  4512. {
  4513.    "PlayerBlack", "BlackRank", "PlayerWhite", "WhiteRank", "GameName", "EVent", "ROund",
  4514.    "DaTe", "PlaCe", "TiMe", "REsult", "GameComment", "SOurce", "USer", "KoMi"};
  4515.  
  4516.  
  4517.  
  4518. static void writeFirst(output)
  4519. FILE *output;
  4520. {
  4521.    int p;
  4522.    if (saveShort) {
  4523.       fprintf(output, "GM[1]VW[]SZ[%d]", boardsize);
  4524.       if (handicap)
  4525.      fprintf(output, "HA[%d]", handicap);
  4526.    } else {
  4527.       fprintf(output, "GaMe[1]\nVieW[]\nSiZe[%d]\n", boardsize);
  4528.       if (handicap)
  4529.      fprintf(output, "HAndicap[%d]\n", handicap);
  4530.    }
  4531.  
  4532.    for (p = 0; p <= t_Komi - FIRSTINFO; p++) {
  4533.       if (info[p]) {
  4534.      WRITE(infoshort[p], infolong[p]);
  4535.      fputc('[', output);
  4536.      writeStrEscaped(output, info[p]);
  4537.      WRITE("]", "]\n");
  4538.       }
  4539.    }
  4540. }
  4541.  
  4542.  
  4543.  
  4544. FUNCTION void writeNode(output, n)
  4545. FILE *output;
  4546. nodep n;
  4547. {
  4548.    property *prop;
  4549.    char str[1445];
  4550.  
  4551.    WRITE(";", ";\n");
  4552.    if (first) {
  4553.       writeFirst(output);
  4554.       first = 0;
  4555.    }
  4556.    prop = n->p;
  4557.    while (prop) {
  4558.       switch (prop->t) {
  4559.      case t_AddBlack:
  4560.         if (writeCoordList(prop->data.stones, str)) {
  4561.            WRITE("AB", "AddBlack");
  4562.            fputs(str, output);
  4563.         }
  4564.         break;
  4565.      case t_AddWhite:
  4566.         if (writeCoordList(prop->data.stones, str)) {
  4567.            WRITE("AW", "AddWhite");
  4568.            fputs(str, output);
  4569.         }
  4570.         break;
  4571.      case t_White:
  4572.         if (writeCoordList(prop->data.stones, str)) {
  4573.            WRITE("W", "White");
  4574.            fputs(str, output);
  4575.         }
  4576.         break;
  4577.      case t_Black:
  4578.         if (writeCoordList(prop->data.stones, str)) {
  4579.            WRITE("B", "Black");
  4580.            fputs(str, output);
  4581.         }
  4582.         break;
  4583.      case t_AddEmpty:
  4584.         if (writeCoordList(prop->data.stones, str)) {
  4585.            WRITE("AE", "AddEmpty");
  4586.            fputs(str, output);
  4587.         }
  4588.         break;
  4589.      case t_Mark:
  4590.         if (writeCoordList(prop->data.stones, str)) {
  4591.            WRITE("M", "Mark");
  4592.            fputs(str, output);
  4593.         }
  4594.         break;
  4595.      case t_Letter:
  4596.         if (writeCoordList(prop->data.stones, str)) {
  4597.            WRITE("L", "Letter");
  4598.            fputs(str, output);
  4599.         }
  4600.         break;
  4601.      case t_Name:
  4602.         if (strlen(prop->data.comment)) {
  4603.            WRITE("N[", "Name[");
  4604.            writeStrEscaped(output, prop->data.comment);
  4605.            WRITE("]", "]\n");
  4606.         }
  4607.         break;
  4608.      case t_Pass:
  4609.         if (prop->data.player == t_Black)
  4610.            WRITE("B", "Black");
  4611.         else
  4612.            WRITE("W", "White");
  4613.         WRITE("[tt]", "[tt]\n");
  4614.         break;
  4615.  
  4616.      case t_Player:
  4617.         WRITE("PL[", "PLayer[");
  4618.         if (prop->data.player == t_Black)
  4619.            fputc('B', output);
  4620.         else
  4621.            fputc('W', output);
  4622.         WRITE("]", "]\n");
  4623.         break;
  4624.      case t_Comment:
  4625.         if (strlen(prop->data.comment)) {
  4626.            WRITE("C[", "Comment[");
  4627.            writeStrEscaped(output, prop->data.comment);
  4628.            WRITE("]", "]\n");
  4629.         }
  4630.         break;
  4631.       }
  4632.       prop = prop->next;
  4633.    }
  4634. }
  4635.  
  4636.  
  4637.  
  4638. FUNCTION void WriteSubTree(output, root, sib)
  4639. FILE *output;
  4640. nodep root;
  4641. int sib;
  4642. {
  4643.    WRITE("(", "(\n");
  4644.    do {
  4645.       if (sib && root->nextSibling) {
  4646.      WriteSubTree(output, root, 0);
  4647.      while (root->nextSibling) {
  4648.         root = root->nextSibling;
  4649.         WriteSubTree(output, root, 0);
  4650.      }
  4651.      root = NULL;
  4652.       } else {
  4653.      writeNode(output, root);
  4654.      root = root->child;
  4655.      sib = 1;
  4656.       }
  4657.    }
  4658.    while (root);
  4659.    WRITE(")", ")\n");
  4660. }
  4661.  
  4662.  
  4663.  
  4664. FUNCTION int writeCoordList(list, str)
  4665. coordList *list;
  4666. char *str;
  4667. {
  4668.    *str = 0;
  4669.    while (list) {
  4670.       sprintf(str + strlen(str), "[%c%c]", list->x + 'a', list->y + 'a');
  4671.       list = list->next;
  4672.    }
  4673.    if (!(strlen(str)))
  4674.       return 0;
  4675.    if (!saveShort)
  4676.       strcat(str, "\n");
  4677.    return 1;
  4678. }
  4679.  
  4680.  
  4681.  
  4682. FUNCTION int writeTree(name, root)
  4683. char *name;
  4684. nodep root;
  4685. {
  4686.    FILE *output;
  4687.  
  4688.    if (output = fopen(name, "w")) {
  4689.       first = 1;
  4690.       WriteSubTree(output, root, 1);
  4691.       fclose(output);
  4692.       return 0;
  4693.    } else {
  4694.       (*io->notifyError) ("Error saving file.");
  4695.       return 1;
  4696.    }
  4697. }
  4698.  
  4699.  
  4700.  
  4701. static void clearSpace(prop, x, y)
  4702. property *prop;
  4703. int x, y;
  4704. {
  4705.    while (prop) {
  4706.       switch (prop->t) {
  4707.      case t_AddEmpty:
  4708.      case t_AddBlack:
  4709.      case t_AddWhite:
  4710.      case t_Black:
  4711.      case t_White:
  4712.      case t_Mark:
  4713.      case t_Letter:
  4714.         clearCoord(x, y, &(prop->data.stones));
  4715.         break;
  4716.       }
  4717.       prop = prop->next;
  4718.    }
  4719. }
  4720.  
  4721.  
  4722. FUNCTION int addMark(n, t, x, y)
  4723. nodep n;
  4724. Token t;
  4725. int x, y;
  4726. {
  4727.    property *prop;
  4728.  
  4729.    if (prop = getprop(n, t)) {
  4730.       if ((getCoord(x, y, prop->data.stones))) {
  4731.      clearCoord(x, y, &(prop->data.stones));
  4732.      return 1;
  4733.       }
  4734.    } else {
  4735.       prop = (property *) malloc(sizeof(property));
  4736.       if (!prop)
  4737.      barf("Memory allocation failure (markStone)");
  4738.       prop->next = n->p;
  4739.       n->p = prop;
  4740.       prop->data.stones = 0;
  4741.       prop->t = t;
  4742.  
  4743.    }
  4744.    setCoord(x, y, &(prop->data.stones));
  4745.    return 0;
  4746. }
  4747.  
  4748.  
  4749.  
  4750.  
  4751. FUNCTION void addStone(n, t, x, y)
  4752. nodep n;
  4753. Token t;
  4754. int x, y;
  4755. {
  4756.    property *prop;
  4757.  
  4758.    clearSpace(n->p, x, y);
  4759.    if (!(prop = getprop(n, t))) {
  4760.       prop = (property *) calloc(1, sizeof(property));
  4761.       if (!prop)
  4762.      barf("Memory allocation failure (addStone)");
  4763.       prop->next = n->p;
  4764.       n->p = prop;
  4765.       prop->data.stones = 0;
  4766.       prop->t = t;
  4767.    }
  4768.    setCoord(x, y, &(prop->data.stones));
  4769.  
  4770. }
  4771.  
  4772. FUNCTION int makeMove(n, t, x, y)
  4773. nodep n;
  4774. Token t;
  4775. int x, y;
  4776. {
  4777.    nodep new;
  4778.    property *prop;
  4779.    int ret;
  4780.    ret = 0;
  4781.  
  4782.    if (!(n->p)) {
  4783.       new = n;
  4784.       ret = 1;
  4785.    } else {
  4786.  
  4787.       new = newNode();
  4788.       if (n->child)
  4789.      n->child->parent = new;
  4790.       new->parent = n;
  4791.       new->child = n->child;
  4792.       n->child = new;
  4793.    }
  4794.  
  4795.  
  4796.    prop = (property *) calloc(1, sizeof(property));
  4797.    if (!prop)
  4798.       barf("Memory allocation failure (makeMove)");
  4799.    new->p = prop;
  4800.    prop->data.stones = 0;
  4801.    prop->t = t;
  4802.  
  4803.    setCoord(x, y, &(prop->data.stones));
  4804.    return ret;
  4805.  
  4806. }
  4807.  
  4808. FUNCTION int passMove(n, t)
  4809. nodep n;
  4810. Token t;
  4811. {
  4812.    nodep new;
  4813.    property *prop;
  4814.    int ret;
  4815.    ret = 0;
  4816.  
  4817.    if (!(n->p)) {
  4818.       new = n;
  4819.       ret = 1;
  4820.    } else {
  4821.  
  4822.       new = newNode();
  4823.       if (n->child)
  4824.      n->child->parent = new;
  4825.       new->parent = n;
  4826.       new->child = n->child;
  4827.       n->child = new;
  4828.    }
  4829.  
  4830.  
  4831.    prop = (property *) calloc(1, sizeof(property));
  4832.    if (!prop)
  4833.       barf("Memory allocation failure (passMove)");
  4834.    new->p = prop;
  4835.    prop->data.player = t;
  4836.    prop->t = t_Pass;
  4837.  
  4838.    return ret;
  4839.  
  4840. }
  4841.  
  4842.  
  4843. FUNCTION void addPlayer(n, t)
  4844. nodep n;
  4845. Token t;
  4846. {
  4847.    property *prop;
  4848.    if (!(prop = getprop(n, t_Player))) {
  4849.       prop = (property *) calloc(1, sizeof(property));
  4850.       if (!prop)
  4851.      barf("Memory allocation failure (addPlayer)");
  4852.       addprop(n, prop);
  4853.    }
  4854.    prop->data.player = t;
  4855.    prop->t = t_Player;
  4856. }
  4857.  
  4858.  
  4859. FUNCTION void makeVariation(n)
  4860. nodep n;
  4861. {
  4862.    nodep new, last;
  4863.  
  4864.    if (!(n->child)) {
  4865.       new = newNode();
  4866.       new->parent = n;
  4867.       n->child = new;
  4868.    } else {
  4869.       new = newNode();
  4870.       new->parent = n;
  4871.       last = treeLastSibling(n->child);
  4872.       last->nextSibling = new;
  4873.       new->lastSibling = last;
  4874.    }
  4875. }
  4876.  
  4877.  
  4878. FUNCTION void cutTree(n)
  4879. nodep n;
  4880. {
  4881.    freeNode(buffer);
  4882.    if (n->nextSibling)
  4883.       n->nextSibling->lastSibling = n->lastSibling;
  4884.    if (n->lastSibling)
  4885.       n->lastSibling->nextSibling = n->nextSibling;
  4886.    else if (n->parent)
  4887.       n->parent->child = n->nextSibling;
  4888.    n->nextSibling = 0;
  4889.    n->lastSibling = 0;
  4890.    buffer = n;
  4891. }
  4892.  
  4893.  
  4894. FUNCTION boolean pasteTree(n)
  4895. nodep n;
  4896. {
  4897.    nodep last, sib;
  4898.    if (buffer) {
  4899.       for (last = buffer; last->child; last = last->child);
  4900.       if (n->child) {
  4901.      n->child->parent = last;
  4902.      for (sib = n->child->nextSibling; sib; sib = sib->nextSibling)
  4903.         sib->parent = last;
  4904.      last->child = n->child;
  4905.       }
  4906.       n->child = buffer;
  4907.       buffer->parent = n;
  4908.       buffer = (nodep) 0;
  4909.       return true;
  4910.    }
  4911.    return false;
  4912. }
  4913.  
  4914.  
  4915. FUNCTION void edComment(n)
  4916. nodep n;
  4917. {
  4918.    property *prop;
  4919.  
  4920.    if (!(prop = getprop(n, t_Comment))) {
  4921.       prop = (property *) calloc(1, sizeof(property));
  4922.       prop->t = t_Comment;
  4923.       prop->next = n->p;
  4924.       n->p = prop;
  4925.    }
  4926.    (*io->editComment) (prop->data.comment, &(prop->data.comment));
  4927.    if (!(prop->data.comment)) {
  4928.       n->p = prop->next;
  4929.       free(prop);
  4930.    }
  4931. }
  4932.  
  4933.  
  4934.  
  4935. FUNCTION void deleteNode(n)
  4936. nodep *n;
  4937. {
  4938.    nodep last;
  4939.    if (!((*n)->child)) {
  4940.       freeProps(*n);
  4941.       (*n)->p = 0;
  4942.    } else {
  4943.       if ((*n)->parent && (*n)->parent->child == *n)
  4944.      (*n)->parent->child = (*n)->child;
  4945.       if ((*n)->lastSibling) {
  4946.      (*n)->child->lastSibling = (*n)->lastSibling;
  4947.      (*n)->lastSibling->nextSibling = (*n)->child;
  4948.       }
  4949.       /* new parent for all of child's sibs */
  4950.  
  4951.       for (last = (*n)->child; last->nextSibling; last = last->nextSibling)
  4952.      last->parent = (*n)->parent;
  4953.       last->parent = (*n)->parent;
  4954.  
  4955.       /* Last of child's sibs get's to point to next sib of main node */
  4956.       last->nextSibling = (*n)->nextSibling;
  4957.  
  4958.       if ((*n)->nextSibling)
  4959.      (*n)->nextSibling = last;
  4960.       last = *n;
  4961.       *n = (*n)->child;
  4962.       delNode(last);
  4963.    }
  4964. }
  4965.  
  4966.  
  4967. FUNCTION void makeName(n)
  4968. nodep n;
  4969. {
  4970.    char newname[41];
  4971.    property *prop;
  4972.  
  4973.    (*io->queryStr) ("Name: ", newname, 40);
  4974.  
  4975.    if (prop = getprop(n, t_Name))
  4976.       free(prop->data.comment);
  4977.    else {
  4978.       prop = (property *) calloc(1, sizeof(property));
  4979.       addprop(n, prop);
  4980.       prop->t = t_Name;
  4981.    }
  4982.    prop->data.comment = dupStr(newname);
  4983. }
  4984.  
  4985.  
  4986. FUNCTION void replaceComment(n, str)
  4987. nodep n;
  4988. char *str;
  4989. {
  4990.    property *prop;
  4991.  
  4992.    if (!(prop = getprop(n, t_Comment))) {
  4993.       prop = (property *) calloc(1, sizeof(property));
  4994.       prop->t = t_Comment;
  4995.       prop->next = n->p;
  4996.       n->p = prop;
  4997.    } else
  4998.       free(prop->data.comment);
  4999.    prop->data.comment = dupStr(str);
  5000. }
  5001. SHAR_EOF
  5002. fi
  5003. if test -f 'mgt.c'
  5004. then
  5005.     echo shar: "will not over-write existing file 'mgt.c'"
  5006. else
  5007. cat << \SHAR_EOF > 'mgt.c'
  5008. /* "mgt" Copyright (c) 1991 Shodan  */
  5009.  
  5010.  
  5011. #include <signal.h>
  5012. #include "mgt.h"
  5013.  
  5014. int retVal = 0;
  5015. interface *io;            /* current interface routines */
  5016. int boardsize;            /* global for board size */
  5017. char *info[LASTINFO - FIRSTINFO + 2];
  5018. int handicap;
  5019. char *commentBuf;        /* pointer to current node's comment */
  5020. extern interface asciiInterface;
  5021. int prisoners[2];
  5022. FILE *input = 0;
  5023. char name_buf[512];
  5024. char *files[MAX_FILES];
  5025. int filecount, currentfile;
  5026.  
  5027. #ifdef DEBUG
  5028. FILE *debug;
  5029. unsigned long totalmemory;
  5030. #endif
  5031.  
  5032. #ifdef MGT_IBM
  5033. extern unsigned _stklen = 32000;
  5034. #endif
  5035.  
  5036. typedef struct {
  5037.    char *arg;
  5038.    int *flag;
  5039.    char **str;
  5040. }  argType;
  5041.  
  5042.  
  5043. int mailFlag = 0;
  5044. int saveShort = 0;
  5045. int tutor = 0;
  5046. char *saveName;
  5047.  
  5048.  
  5049.  
  5050. static argType argTable[] =
  5051. {
  5052.    {"-m", &mailFlag, &saveName},
  5053.    {"-s", &saveShort, NULL},
  5054.    {"-t", &tutor, NULL}
  5055. };
  5056.  
  5057.  
  5058. FUNCTION main(argc, argv)
  5059. int argc;
  5060. char **argv;
  5061. {
  5062.  
  5063. #ifdef DEBUG
  5064.    debug = fopen("debug", "w");
  5065. #endif
  5066.  
  5067.    io = &asciiInterface;
  5068.    input = stdin;
  5069.    init(argv, &argc);
  5070.    parseLine(argc, argv);
  5071.    doit();
  5072.    myexit();
  5073. }
  5074.  
  5075.  
  5076.  
  5077. FUNCTION void die()
  5078. {
  5079.    signal(SIGINT, SIG_DFL);
  5080.    myexit();
  5081. }
  5082.  
  5083.  
  5084. FUNCTION void myexit()
  5085. {
  5086.    (*io->clearScreen) ();
  5087.    (*io->refreshIO) ();
  5088.    (*io->close) ();
  5089.    printf("Thank you for using mgt\n");
  5090.    exit(retVal);
  5091. }
  5092.  
  5093.  
  5094.  
  5095. FUNCTION void openfile(f)
  5096. char *f;
  5097. {
  5098. #ifdef MGT_LIB
  5099.    char game_lib[] = MGT_LIB;
  5100. #endif                /* MGT_LIB */
  5101.    strcpy(name_buf, f);
  5102.    if (!(input = fopen(f, "r")))
  5103.       strcpy(name_buf, "");
  5104. #ifdef MGT_LIB
  5105.    /* if not in local directory, try library */
  5106.    if (!input) {
  5107.       strcpy(name_buf, game_lib);
  5108.       strcat(name_buf, f);
  5109.       input = fopen(name_buf, "r");
  5110.    }
  5111. #endif                /* MGT_LIB */
  5112. }
  5113.  
  5114.  
  5115. FUNCTION void barf(s)
  5116. char *s;
  5117. {
  5118.    int i;
  5119.    for (i = 24; i--;)
  5120.       fprintf(stderr, "\n");
  5121.    fprintf(stderr, "%s\n", s);
  5122.    exit(1);
  5123. }
  5124.  
  5125.  
  5126. FUNCTION void initEnv()
  5127. {
  5128.    extern char *getenv();
  5129.    char *env;
  5130.  
  5131.    if (env = getenv("MGT"))
  5132.       while (*env) {
  5133.      while (*env && *env != '_')
  5134.         env++;
  5135.      if (*env)
  5136.         env++;
  5137.      if (*env)
  5138.         (*io->readEnv) (&env);
  5139.       }
  5140. }
  5141.  
  5142.  
  5143. FUNCTION void init(argv, argc)
  5144. char *argv[];
  5145. int *argc;
  5146. {
  5147.    initEnv();
  5148.    (*io->open) (argv, argc);
  5149.    signal(SIGINT, die);
  5150.    readInit();
  5151. }
  5152.  
  5153.  
  5154.  
  5155. FUNCTION void helpCommandLine(errMesg)
  5156. char *errMesg;
  5157. {
  5158.    (*io->close) ();
  5159.    fprintf(stderr, "\nERROR: %s\n\n", errMesg);
  5160.    fprintf(stderr, "                   MGT %s\n", VERSION);
  5161.    fprintf(stderr, "\nUsage: mgt [opts] [files]\n");
  5162.    fprintf(stderr, "[opts] is any of:\n");
  5163.    fprintf(stderr, "-m filename        mail mode.  Autosave on quit.\n");
  5164.    fprintf(stderr, "-s                 use short format when saving.\n\n");
  5165.    exit(2);
  5166. }
  5167.  
  5168.  
  5169. FUNCTION void parseLine(argc, argv)
  5170. int argc;
  5171. char **argv;
  5172. {
  5173.    int i;
  5174.  
  5175.    filecount = 0;
  5176.  
  5177.    while (++argv, --argc > 0) {
  5178.       if (**argv != '-') {
  5179.      files[filecount++] = *argv;
  5180.      if (filecount == MAX_FILES)
  5181.         helpCommandLine("Too many files specified");
  5182.       } else {
  5183.      for (i = 0; i < sizeof(argTable) / sizeof(argType); i++)
  5184.         if (!strcmp(argTable[i].arg, *argv)) {
  5185.            if (argTable[i].str)
  5186.           if (--argc)
  5187.              *(argTable[i].str) = (*++argv);
  5188.           else
  5189.              helpCommandLine("String expected on option");
  5190.            (*(argTable[i].flag))--;
  5191.            break;
  5192.         }
  5193.      if (i == sizeof(argTable) / sizeof(argType))
  5194.         helpCommandLine("Bad option");
  5195.       }
  5196.    }
  5197.    if (!filecount)
  5198.       input = stdin;
  5199.    else {
  5200.       currentfile = 0;
  5201.       openfile(files[0]);
  5202.       if (!input)
  5203.      helpCommandLine("File not found");
  5204.    }
  5205.  
  5206. }
  5207. SHAR_EOF
  5208. fi
  5209. if test -f 'parse.c'
  5210. then
  5211.     echo shar: "will not over-write existing file 'parse.c'"
  5212. else
  5213. cat << \SHAR_EOF > 'parse.c'
  5214. /* "mgt" Copyright (c) 1991 Shodan  */
  5215.  
  5216. #include <string.h>
  5217. #include "mgt.h"
  5218.  
  5219.  
  5220. struct {
  5221.    char *str;
  5222.    Token val;
  5223. }  tokens[] = {
  5224.    {
  5225.       "W", t_White
  5226.    },
  5227.    {
  5228.       "B", t_Black
  5229.    },
  5230.    {
  5231.       "C", t_Comment
  5232.    },
  5233.    {
  5234.       "AW", t_AddWhite
  5235.    },
  5236.    {
  5237.       "AB", t_AddBlack
  5238.    },
  5239.    {
  5240.       "L", t_Letter
  5241.    },
  5242.    {
  5243.       "AE", t_AddEmpty
  5244.    },
  5245.    {
  5246.       "N", t_Name
  5247.    },
  5248.    {
  5249.       "M", t_Mark
  5250.    },
  5251.    {
  5252.       "SZ", t_Size
  5253.    },
  5254.    {
  5255.       "GN", t_GameName
  5256.    },
  5257.    {
  5258.       "GC", t_GameComment
  5259.    },
  5260.    {
  5261.       "EV", t_Event
  5262.    },
  5263.    {
  5264.       "RO", t_Round
  5265.    },
  5266.    {
  5267.       "DT", t_Date
  5268.    },
  5269.    {
  5270.       "PC", t_Place
  5271.    },
  5272.    {
  5273.       "PB", t_PlayerBlack
  5274.    },
  5275.    {
  5276.       "PW", t_PlayerWhite
  5277.    },
  5278.    {
  5279.       "RE", t_Result
  5280.    },
  5281.    {
  5282.       "US", t_User
  5283.    },
  5284.    {
  5285.       "TM", t_TimeLimit
  5286.    },
  5287.    {
  5288.       "SO", t_Source
  5289.    },
  5290.    {
  5291.       "BR", t_BlackRank
  5292.    },
  5293.    {
  5294.       "WR", t_WhiteRank
  5295.    },
  5296.    {
  5297.       "HA", t_Handicap
  5298.    },
  5299.    {
  5300.       "KM", t_Komi
  5301.    }, {
  5302.       "PL", t_Player
  5303.    }
  5304.  
  5305. };
  5306.  
  5307.  
  5308. char buf[1024], *curin, started;
  5309.  
  5310. FUNCTION void readInit()
  5311. {
  5312.    int p;
  5313.    buf[0] = '\0';
  5314.    curin = &buf[0];
  5315.    started = 1;
  5316.    boardsize = 19;
  5317.    handicap = 0;
  5318.    for (p = 0; p <= LASTINFO - FIRSTINFO + 1; p++) {
  5319.       if (info[p])
  5320.      free(info[p]);
  5321.       info[p] = 0;
  5322.    }
  5323. }
  5324.  
  5325.  
  5326. static char *readLine()
  5327. {
  5328.    curin = &buf[0];
  5329.    buf[0] = '\0';
  5330.    return fgets(&buf[0], 1023, input);
  5331. }
  5332.  
  5333.  
  5334. static char readChar()
  5335. {
  5336.    if (*curin)
  5337.       return *(curin++);
  5338.    curin = &buf[0];
  5339.    buf[0] = '\0';
  5340.    fgets(&buf[0], 1023, input);
  5341.    return 0;
  5342. }
  5343.  
  5344.  
  5345. static int getCoordStr(co)
  5346. coord *co;
  5347. {
  5348.    if (curin[0] == '[' && curin[1] >= 'a' && curin[1] <= 's'
  5349.        && curin[2] >= 'a' && curin[2] <= 's' && curin[3] == ']') {
  5350.       co->x = curin[1] - 'a';
  5351.       co->y = curin[2] - 'a';
  5352.       curin += 4;
  5353.       while (*curin == ' ' || *curin == '\t')
  5354.      curin++;
  5355.       if (*curin == '\n')
  5356.      readLine();
  5357.       return 1;
  5358.    } else
  5359.       return 0;
  5360. }
  5361.  
  5362.  
  5363. static void getCoordList(clp)
  5364. coordList **clp;
  5365. {
  5366.    coord co;
  5367.    while (getCoordStr(&co)) {
  5368.       setCoord(co.x, co.y, clp);
  5369.    }
  5370. }
  5371.  
  5372. static void addPass(n, t)
  5373. nodep n;
  5374. Token t;
  5375. {
  5376.    property *p;
  5377.    if (!(p = (property *) calloc(1, sizeof(property))))
  5378.       barf("Memory allocation error (addPass)");
  5379.    p->t = t_Pass;
  5380.    p->data.player = t;
  5381.    addprop(n, p);
  5382.  
  5383. }
  5384.  
  5385.  
  5386.  
  5387. static void doPlayer(n)
  5388. nodep n;
  5389.  
  5390. {
  5391.    property *p;
  5392.  
  5393.    if (curin[0] == '[' && curin[2] == ']' && (curin[1] == 'B' || curin[1] == 'W')) {
  5394.       p = (property *) calloc(1, sizeof(property));
  5395.       if (!p)
  5396.      barf("Memory allocation failure (doPlayer)");
  5397.       p->t = t_Player;
  5398.       p->data.player = curin[1] == 'B' ? t_Black : t_White;
  5399.       curin += 3;
  5400.       addprop(n, p);
  5401.    }
  5402. }
  5403.  
  5404.  
  5405. static Token tokenize()
  5406. {
  5407.    int i, len;
  5408.    char buf[4];
  5409.  
  5410.    len = 0;
  5411.    do {
  5412.       if (!*curin || *curin == '\n') {
  5413.      if (!readLine())
  5414.         return t_EOF;
  5415.       }
  5416.       if (*curin == ')') {
  5417.      curin++;
  5418.      return t_Close;
  5419.       }
  5420.       if (*curin == '(') {
  5421.      curin++;
  5422.      return t_Open;
  5423.       }
  5424.       if (*curin == ';') {
  5425.      curin++;
  5426.      return t_NewNode;
  5427.       }
  5428.       if (*curin >= 'A' && *curin <= 'Z')
  5429.      buf[len++] = *curin;
  5430.       curin++;
  5431.    } while (len < 3 && *curin != '[');
  5432.    buf[len] = 0;
  5433.    if (len == 1 || len == 2)
  5434.       for (i = 0; i < sizeof(tokens) / sizeof(tokens[0]); i++)
  5435.      if (!strcmp(buf, tokens[i].str))
  5436.         return tokens[i].val;
  5437.    while (*curin != ']') {
  5438.       if (!*++curin) {
  5439.      if (!readLine())
  5440.         return t_EOF;
  5441.       }
  5442.    }
  5443.    return t_WS;
  5444. }
  5445.  
  5446.  
  5447.  
  5448. static void addMoveArrayProp(t, n)
  5449. Token t;
  5450. nodep n;
  5451. {
  5452.    property *p;
  5453.  
  5454. #ifdef DEBUG
  5455.    totalmemory += sizeof(property);
  5456.    fprintf(debug, "%ld %ld\n", totalmemory, coreleft());
  5457. #endif
  5458.    if (!(p = getprop(n, t))) {
  5459.       p = (property *) calloc(1, sizeof(property));
  5460.  
  5461. #ifdef DEBUG
  5462.       totalmemory += sizeof(coordList);
  5463.       fprintf(debug, "%ld %ld\n", totalmemory, coreleft());
  5464. #endif
  5465.  
  5466.       if (!p)
  5467.      barf("Memory allocation failure (addMoveArrayProp)");
  5468.  
  5469.       p->data.stones = 0;
  5470.       p->t = t;
  5471.       addprop(n, p);
  5472.    }
  5473.    getCoordList(&(p->data.stones));
  5474. }
  5475.  
  5476.  
  5477. static void doSize()
  5478. {
  5479.    int size;
  5480.    char *s, c, b[25];
  5481.    s = &b[0];
  5482.    readChar();
  5483.    while ((c = readChar()) != ']')
  5484.       if (c && c != '\\')
  5485.      *s++ = c;
  5486.    *s = 0;
  5487.    size = atoi(b);
  5488.    if ((size > 1) && (size <= 19))
  5489.       boardsize = size;
  5490. }
  5491.  
  5492.  
  5493.  
  5494. static void doHandicap()
  5495. {
  5496.    int size;
  5497.    char *s, c, b[25];
  5498.    s = &b[0];
  5499.    readChar();
  5500.    while ((c = readChar()) != ']')
  5501.       if (c && c != '\\')
  5502.      *s++ = c;
  5503.    *s = 0;
  5504.    size = atoi(b);
  5505.    if ((size > 1) && (size <= 17))
  5506.       handicap = size;
  5507. }
  5508.  
  5509.  
  5510.  
  5511. static void doComment(n, t)
  5512. nodep n;
  5513. Token t;
  5514. {
  5515.    char c, *s, *buffer;
  5516.    property *p;
  5517.    int space;
  5518.  
  5519.    buffer = (char *) malloc(MAXCOMMENT);
  5520.    p = (property *) calloc(1, sizeof(property));
  5521.    if (!(p && buffer))
  5522.       barf("Memory Allocation Failure (doComment)");
  5523.    s = buffer;
  5524.    space = MAXCOMMENT - 1;
  5525.    readChar();
  5526.    while (space && (c = readChar()) != ']') {
  5527.       if (c == '\\')
  5528.      c = readChar();
  5529.       if (c) {
  5530.      *s++ = c;
  5531.      space--;
  5532.       }
  5533.    }
  5534.    if (*(s - 1) == '\n')
  5535.       s--;
  5536.    *s = 0;
  5537.    p->t = t;
  5538.    p->data.comment = dupStr(buffer);
  5539.    addprop(n, p);
  5540.    free(buffer);
  5541. }
  5542.  
  5543.  
  5544. static void doInfo(t)
  5545. Token t;
  5546. {
  5547.    char *buffer, *s, c;
  5548.    int space;
  5549.    buffer = (char *) malloc(MAXCOMMENT);
  5550.    if (!buffer)
  5551.       barf("Memory allocation failure (doInfo)");
  5552.    s = buffer;
  5553.    space = MAXCOMMENT - 1;
  5554.    readChar();
  5555.    while (space && (c = readChar()) != ']') {
  5556.       if (c == '\\')
  5557.      c = readChar();
  5558.       if (c) {
  5559.      *s++ = c;
  5560.      space--;
  5561.       }
  5562.    }
  5563.    if (*(s - 1) == '\n')
  5564.       s--;
  5565.    *s = 0;
  5566.    info[(int) t - FIRSTINFO] = dupStr(buffer);
  5567.    free(buffer);
  5568. }
  5569.  
  5570. FUNCTION void addChild(n, c)    /* add child c to node n */
  5571. nodep n, c;
  5572. {
  5573.    if (n) {
  5574.       if (n->child) {
  5575.      nodep s;
  5576.      s = treeLastSibling(child(n));
  5577.      s->nextSibling = c;
  5578.      c->lastSibling = s;
  5579.      c->parent = n;
  5580.       } else {
  5581.      n->child = c;
  5582.      c->parent = n;
  5583.       }
  5584.    }
  5585. }
  5586.  
  5587.  
  5588. FUNCTION nodep parse(lev)
  5589. int lev;
  5590. {
  5591.    nodep r, n, new;
  5592.    Token t;
  5593.  
  5594.    if (started) {
  5595.       started = 0;
  5596.  
  5597.       while (*curin != '(') {
  5598.      if (!readLine())
  5599.         break;
  5600.       }
  5601.    }
  5602.    r = n = 0;
  5603.    for (;;) {
  5604.       t = tokenize();
  5605.       switch (t) {
  5606.      case t_Size:
  5607.         doSize();
  5608.         break;
  5609.      case t_White:
  5610.      case t_Black:
  5611.         if (curin[1] == 't' && curin[2] == 't' && curin[0] == '[' && curin[3] == ']') {
  5612.            addPass(n, t);
  5613.            break;
  5614.         }
  5615.      case t_AddWhite:
  5616.      case t_AddBlack:
  5617.      case t_AddEmpty:
  5618.      case t_Mark:
  5619.      case t_Letter:
  5620.         if (n)
  5621.            addMoveArrayProp(t, n);
  5622.         else
  5623.            fprintf(stderr, "Error - property w/o node in data\n");
  5624.         break;
  5625.      case t_Player:
  5626.         if (n)
  5627.            doPlayer(n);
  5628.         else
  5629.            fprintf(stderr, "Error - property w/o node in data\n");
  5630.         break;
  5631.      case t_Name:
  5632.      case t_Comment:
  5633.         if (n)
  5634.            doComment(n, t);
  5635.         else
  5636.            fprintf(stderr, "Error - property w/o node in data\n");
  5637.         break;
  5638.      case t_NewNode:
  5639.         new = newNode();
  5640.         if (!r)
  5641.            r = new;
  5642.         else
  5643.            addChild(n, new);
  5644.         n = new;
  5645.         break;
  5646.      case t_Open:
  5647.         if (lev == 1 && !r)
  5648.            n = r = newNode();
  5649.         if (new = parse(lev + 1)) {
  5650.            addChild(n, new);
  5651.            if (!r)
  5652.           r = new;
  5653.         }
  5654.         break;
  5655.      case t_Close:
  5656.      case t_EOF:
  5657.         return r;
  5658.  
  5659.      case t_GameName:
  5660.      case t_GameComment:
  5661.      case t_Event:
  5662.      case t_Round:
  5663.      case t_Date:
  5664.      case t_Place:
  5665.      case t_PlayerBlack:
  5666.      case t_PlayerWhite:
  5667.      case t_Result:
  5668.      case t_User:
  5669.      case t_TimeLimit:
  5670.      case t_Source:
  5671.      case t_BlackRank:
  5672.      case t_WhiteRank:
  5673.  
  5674.         doInfo(t);
  5675.         break;
  5676.      case t_Komi:{
  5677.            char *ch, *end;
  5678.            doInfo(t_Komi);
  5679.            end = ch = info[(int) t_Komi - FIRSTINFO];
  5680.            while (*end)
  5681.           end++;
  5682.            for (end--; *end == '0' && (end != ch); end--);
  5683.            *++end = 0;
  5684.         }
  5685.         break;
  5686.      case t_Handicap:
  5687.         doHandicap();
  5688.         break;
  5689.      default:
  5690.         break;
  5691.       }
  5692.    }
  5693. }
  5694. SHAR_EOF
  5695. fi
  5696. if test -f 'play.c'
  5697. then
  5698.     echo shar: "will not over-write existing file 'play.c'"
  5699. else
  5700. cat << \SHAR_EOF > 'play.c'
  5701. /* "mgt" Copyright (c) 1991 Shodan  */
  5702.  
  5703.  
  5704. #include "mgt.h"
  5705. #include <string.h>
  5706. #include <stdio.h>
  5707.  
  5708. /* void printboard(char *s,pBoard b) { FILE *fil; int i,j;
  5709.  * fil=fopen("dump","a+"); if (!fil) {printf("can't open file");getch();}
  5710.  * fprintf(fil,"%s\n",s); for(i=0;i<boardsize;i++){ for(j=0;j<boardsize;j++)
  5711.  * fputc( b->b[i][j]==P_NOTHING?'.':(b->b[i][j]==P_BLACK?'*':'O'),fil);
  5712.  * fputc('\n',fil); } fclose(fil); } */
  5713.  
  5714.  
  5715.  
  5716.  
  5717. FUNCTION int legal(b, n, player, i, j)
  5718. pBoard b;
  5719. nodep n;
  5720. int i, j;
  5721. Token player;
  5722. {
  5723.    board a, copy;
  5724.    int same, x, y, savex, savey, savemove;
  5725.    boolean islegal;
  5726.    extern int moveNum;
  5727.    int savepris[2];
  5728.    extern int prisoners[];
  5729.  
  5730.    savemove = moveNum;
  5731.    savex = xcur;
  5732.    savey = ycur;
  5733.    savepris[0] = prisoners[0];
  5734.    savepris[1] = prisoners[1];
  5735.    copyBoard(b, ©);
  5736.  
  5737.    islegal = true;
  5738.  
  5739.    if (b->b[i][j] != P_NOTHING) {
  5740.       (*io->notifyError) ("There's already a piece there.");
  5741.       return false;
  5742.    }
  5743.    placeStone(©, i, j, (player == t_Black) ? P_BLACK : P_WHITE);
  5744.    if (!alive(©, i, j)) {
  5745.       (*io->notifyError) ("That move is suicide.");
  5746.       islegal = false;
  5747.    }
  5748.    if (islegal && (n = n->parent)) {
  5749.       boardClear(&a);
  5750.       buildTree0(n, &a);
  5751.       same = true;
  5752.       for (x = boardsize; same && x--;)
  5753.      for (y = boardsize; same && y--;) {
  5754.         same = (copy.b[x][y] == a.b[x][y]);
  5755.      }
  5756.       if (same) {
  5757.      (*io->notifyError) ("Can't retake the ko yet.");
  5758.      islegal = false;
  5759.       }
  5760.    }
  5761.    xcur = savex;
  5762.    ycur = savey;
  5763.    prisoners[0] = savepris[0];
  5764.    moveNum = savemove;
  5765.    prisoners[1] = savepris[1];
  5766.  
  5767.    return islegal;
  5768. }
  5769.  
  5770.  
  5771.  
  5772.  
  5773. FUNCTION boolean inRange(i, j)
  5774. {
  5775.    return i >= 0 && i < boardsize && j >= 0 && j < boardsize;
  5776. }
  5777.  
  5778. FUNCTION boolean alive0(b, m, i, j, t)
  5779. pBoard b;
  5780. pBoard m;
  5781. int i, j;
  5782. piece t;
  5783. {
  5784.    piece pt;
  5785.  
  5786.    pt = b->b[i][j];
  5787.    if ((pt != P_NOTHING && pt != t) || m->b[i][j] != P_NOTHING)
  5788.       return 0;
  5789.    m->b[i][j] = (pt == t) ? (piece) 1 : (piece) 2;
  5790.    if (pt == P_NOTHING)
  5791.       return 1;
  5792.    return
  5793.       (j < boardsize - 1 && alive0(b, m, i, j + 1, t)) ||
  5794.       (i < boardsize - 1 && alive0(b, m, i + 1, j, t)) ||
  5795.       (i && alive0(b, m, i - 1, j, t)) ||
  5796.       (j && alive0(b, m, i, j - 1, t));
  5797. }
  5798.  
  5799. FUNCTION boolean alive(b, i, j)    /* Does group at i,j have liberties? */
  5800. pBoard b;
  5801. int i, j;
  5802. {
  5803.    board m;
  5804.  
  5805.    boardClear(&m);
  5806.    return alive0(b, &m, i, j, b->b[i][j]);
  5807. }
  5808.  
  5809. void removeStones0(b, i, j, t)
  5810. pBoard b;
  5811. int i, j;
  5812. piece t;
  5813. {
  5814.    extern int prisoners[];
  5815.  
  5816.    if (b->b[i][j] != t)
  5817.       return;
  5818.    b->b[i][j] = P_NOTHING;
  5819.    prisoners[(int) t - 1]++;
  5820.    if (j < boardsize - 1)
  5821.       removeStones0(b, i, j + 1, t);
  5822.    if (i < boardsize - 1)
  5823.       removeStones0(b, i + 1, j, t);
  5824.    if (i)
  5825.       removeStones0(b, i - 1, j, t);
  5826.    if (j)
  5827.       removeStones0(b, i, j - 1, t);
  5828. }
  5829.  
  5830.  
  5831.  
  5832. FUNCTION void removeStones(b, i, j)
  5833. pBoard b;
  5834. int i, j;
  5835. {
  5836.    removeStones0(b, i, j, b->b[i][j]);
  5837. }
  5838.  
  5839. FUNCTION boolean tryKill(b, i, j, t)
  5840. pBoard b;
  5841. int i, j;
  5842. piece t;
  5843. {
  5844.    piece w;
  5845.    if (!inRange(i, j))
  5846.       return false;
  5847.    w = b->b[i][j];
  5848.    if (w != P_NOTHING && w != t && !alive(b, i, j)) {
  5849.       removeStones(b, i, j);
  5850.       return true;
  5851.    }
  5852.    return false;
  5853. }
  5854.  
  5855. FUNCTION void placeStone(b, i, j, t)
  5856. pBoard b;
  5857. int i, j;
  5858. piece t;
  5859. {
  5860.    if (inRange(i, j)) {
  5861.       b->b[i][j] = t;
  5862.       xcur = i;
  5863.       ycur = j;
  5864.       if (j)
  5865.      tryKill(b, i, j - 1, t);
  5866.       if (j < boardsize - 1)
  5867.      tryKill(b, i, j + 1, t);
  5868.       if (i)
  5869.      tryKill(b, i - 1, j, t);
  5870.       if (i < boardsize - 1)
  5871.      tryKill(b, i + 1, j, t);
  5872.    }
  5873. }
  5874.  
  5875. FUNCTION void boardSet(b, i, j, p)
  5876. pBoard b;
  5877. int i, j;
  5878. piece p;
  5879. {
  5880.    b->b[i][j] = p;
  5881. }
  5882.  
  5883. FUNCTION piece boardGet(b, i, j)
  5884. pBoard b;
  5885. int i, j;
  5886. {
  5887.    return b->b[i][j];
  5888. }
  5889.  
  5890.  
  5891. FUNCTION void boardClear(b)
  5892. pBoard b;
  5893. {
  5894.    memset((char *) (b->b), 0, 361 * sizeof(piece));
  5895.  
  5896.    /* int i, j; for (i = boardsize; i--;) for (j = boardsize; j--;) b->b[i][j]
  5897.     * = P_NOTHING; */
  5898. }
  5899.  
  5900. FUNCTION void copyBoard(a, b)
  5901. pBoard a, b;
  5902. {
  5903.    int i, j;
  5904.    for (i = boardsize; i--;)
  5905.       for (j = boardsize; j--;)
  5906.      b->b[i][j] = a->b[i][j];
  5907. }
  5908.  
  5909.  
  5910. int look(stone, array, index, i)
  5911. int stone, array[], *index, i;
  5912. {
  5913.    if (stone == P_NOTHING)
  5914.       array[(*index)++] = i;
  5915.    else if (stone == P_BLACK)
  5916.       return 1;
  5917.    else if (stone == P_WHITE)
  5918.       return 2;
  5919.    return 0;
  5920. }
  5921.  
  5922.  
  5923. int fillregion(b, x, y)
  5924. pBoard b;
  5925. int x, y;
  5926. {
  5927.    int goup[19], godown[19], up = 0, down = 0, found = 0, i;
  5928.  
  5929.    for (i = x; i < boardsize && b->b[i][y] == P_NOTHING; i++) {
  5930.       b->b[i][y] = P_CHECKED;
  5931.       if (y > 0)
  5932.      found |= look(b->b[i][y - 1], goup, &up, i);
  5933.       if (y < boardsize - 1)
  5934.      found |= look(b->b[i][y + 1], godown, &down, i);
  5935.    }
  5936.    if (i != boardsize) {
  5937.       if (b->b[i][y] == P_BLACK)
  5938.      found |= 1;
  5939.       if (b->b[i][y] == P_WHITE)
  5940.      found |= 2;
  5941.    }
  5942.    for (i = x - 1; i >= 0 && b->b[i][y] == P_NOTHING; i--) {
  5943.       b->b[i][y] = P_CHECKED;
  5944.       if (y > 0)
  5945.      found |= look(b->b[i][y - 1], goup, &up, i);
  5946.       if (y < boardsize - 1)
  5947.      found |= look(b->b[i][y + 1], godown, &down, i);
  5948.    }
  5949.    if (i != -1) {
  5950.       if (b->b[i][y] == P_BLACK)
  5951.      found |= 1;
  5952.       if (b->b[i][y] == P_WHITE)
  5953.      found |= 2;
  5954.    }
  5955.    while (up)
  5956.       found |= fillregion(b, goup[--up], y - 1);
  5957.    while (down)
  5958.       found |= fillregion(b, godown[--down], y + 1);
  5959.    return found;
  5960. }
  5961.  
  5962.  
  5963. FUNCTION void scoreBoard(b, score)
  5964. pBoard b;
  5965. int score[];
  5966. {
  5967.    int x, y, i, j, owner;
  5968.    piece newval;
  5969.  
  5970.    score[0] = 0;
  5971.    score[1] = 0;
  5972.    for (i = 0; i < boardsize; i++)
  5973.       for (j = 0; j < boardsize; j++) {
  5974.      owner = fillregion(b, i, j);
  5975.      if (!owner)
  5976.         owner = 3;
  5977.      switch (owner) {
  5978.         case 3:
  5979.            newval = P_DAME;
  5980.            break;
  5981.         case 2:
  5982.            newval = P_WHITETERR;
  5983.            break;
  5984.         case 1:
  5985.            newval = P_BLACKTERR;
  5986.            break;
  5987.      }
  5988.      for (x = 0; x < boardsize; x++)
  5989.         for (y = 0; y < boardsize; y++)
  5990.            if (b->b[x][y] == P_CHECKED) {
  5991.           b->b[x][y] = newval;
  5992.           if (owner != 3)
  5993.              score[owner - 1]++;
  5994.            }
  5995.       }
  5996. }
  5997. SHAR_EOF
  5998. fi
  5999. if test -f 'tree.c'
  6000. then
  6001.     echo shar: "will not over-write existing file 'tree.c'"
  6002. else
  6003. cat << \SHAR_EOF > 'tree.c'
  6004. /* "mgt" Copyright (c) 1991 Shodan  */
  6005.  
  6006. #include "mgt.h"
  6007.  
  6008.  
  6009. static int newNodeNum;
  6010.  
  6011.  
  6012. FUNCTION boolean getCoord(x, y, list)
  6013. int x, y;
  6014. coordList *list;
  6015. {
  6016.    for (; list; list = list->next)
  6017.       if (list->x == x && list->y == y)
  6018.      return true;
  6019.    return false;
  6020. }
  6021.  
  6022.  
  6023.  
  6024. FUNCTION coordList *addCoord(x, y)
  6025. int x, y;
  6026. {
  6027.    coordList *co;
  6028.  
  6029.    if (!(co = (coordList *) malloc(sizeof(coordList))))
  6030.       barf("Memory allocation failure (addCoord)");
  6031.    co->next = 0;
  6032.    co->x = x;
  6033.    co->y = y;
  6034.    return co;
  6035. }
  6036.  
  6037.  
  6038.  
  6039. FUNCTION void setCoord(x, y, startlist)
  6040. int x, y;
  6041. coordList **startlist;
  6042. {
  6043.    coordList *list;
  6044.    if (!*startlist)
  6045.       *startlist = addCoord(x, y);
  6046.    else {
  6047.       for (list = *startlist; list->next; list = list->next)
  6048.      if (x == list->x && y == list->y)
  6049.         return;
  6050.       list->next = addCoord(x, y);
  6051.    }
  6052. }
  6053.  
  6054.  
  6055. FUNCTION void clearCoord(x, y, startlist)
  6056. int x, y;
  6057. coordList **startlist;
  6058.  
  6059. {
  6060.    coordList *last, *list;
  6061.  
  6062.    last = 0;
  6063.    list = *startlist;
  6064.    while (list && (x != list->x || y != list->y)) {
  6065.       last = list;
  6066.       list = list->next;
  6067.    }
  6068.    if (list) {
  6069.       if (last)
  6070.      last->next = list->next;
  6071.       else
  6072.      *startlist = list->next;
  6073.       free(list);
  6074.    }
  6075. }
  6076.  
  6077.  
  6078. FUNCTION void initNodes()
  6079. {
  6080.    newNodeNum = 0;
  6081. }
  6082.  
  6083. FUNCTION nodep newNode()
  6084. {
  6085.    nodep new;
  6086. #ifdef DEBUG
  6087.    totalmemory += sizeof(node);
  6088.    fprintf(debug, "%ld %ld\n", totalmemory, coreleft());
  6089. #endif
  6090.    new = (nodep) calloc(1, sizeof(node));
  6091.    if (!new)
  6092.       barf("Memory allocation failure (newnode)");
  6093.    new->nodeNum = newNodeNum++;
  6094.    return new;
  6095. }
  6096.  
  6097. FUNCTION void freeNode(n)
  6098. nodep n;
  6099. {
  6100.    if (n) {
  6101.       freeNode(n->nextSibling);
  6102.       freeNode(n->child);
  6103.       delNode(n);
  6104.    }
  6105. }
  6106.  
  6107. FUNCTION char *dupStr(s)
  6108. char *s;
  6109. {
  6110.    char *c;
  6111. #ifdef DEBUG
  6112.    totalmemory += strlen(s) + 1;
  6113.    fprintf(debug, "%ld %ld\n", totalmemory, coreleft());
  6114. #endif
  6115.    c = (char *) malloc((unsigned) strlen(s) + 1);
  6116.    if (!c)
  6117.       barf("Memory allocation failure (dupstr)");
  6118.    strcpy(c, s);
  6119.    return c;
  6120. }
  6121.  
  6122.  
  6123.  
  6124. FUNCTION void freeProps(n)
  6125. nodep n;
  6126. {
  6127.    property *prop, *lastprop;
  6128.    coordList *cl, *lastcl;
  6129.    prop = n->p;
  6130.    while (prop) {
  6131.       switch (prop->t) {
  6132.      case t_AddEmpty:
  6133.      case t_AddBlack:
  6134.      case t_AddWhite:
  6135.      case t_Mark:
  6136.      case t_Letter:
  6137.      case t_Black:
  6138.      case t_White:
  6139.         cl = prop->data.stones;
  6140.         while (cl) {
  6141.            lastcl = cl;
  6142.            cl = cl->next;
  6143.            free(lastcl);
  6144.         }
  6145.         break;
  6146.      case t_Name:
  6147.      case t_Comment:
  6148.         free(prop->data.comment);
  6149.         break;
  6150.  
  6151.       }
  6152.  
  6153.       lastprop = prop;
  6154.       prop = prop->next;
  6155.       free(lastprop);
  6156.    }
  6157. }
  6158.  
  6159.  
  6160. FUNCTION void delNode(n)
  6161. nodep n;
  6162. {
  6163.    freeProps(n);
  6164.    free(n);
  6165. }
  6166.  
  6167. FUNCTION void addprop(n, p)
  6168. nodep n;
  6169. property *p;
  6170. {
  6171.    p->next = n->p;
  6172.    n->p = p;
  6173. }
  6174.  
  6175. FUNCTION property *getprop(n, t)
  6176. nodep n;
  6177. Token t;
  6178. {
  6179.    property *p;
  6180.    p = n->p;
  6181.    while (p && p->t != t)
  6182.       p = p->next;
  6183.    return p;
  6184. }
  6185.  
  6186. FUNCTION int treeCountSiblings(n)
  6187. nodep n;
  6188. {
  6189.    int i;
  6190.    nodep n1;
  6191.  
  6192.    n1 = n->child;
  6193.    i = 0;
  6194.    while (n1) {
  6195.       n1 = n1->nextSibling;
  6196.       i++;
  6197.    }
  6198.    return i;
  6199. }
  6200.  
  6201. FUNCTION nodep nthChild(n, c)    /* nodep, int */
  6202. nodep n;
  6203. int c;
  6204. {
  6205.  
  6206.    if (n->child) {
  6207.       n = child(n);
  6208.       while (c-- && n)
  6209.      n = nextSibling(n);
  6210.    } else {
  6211.       n = 0;
  6212.    }
  6213.    return n;
  6214. }
  6215.  
  6216. /* TREE WALK functions KEEP TRACK OF DEPTH AS WELL */
  6217.  
  6218. FUNCTION nodep parent(n)
  6219. nodep n;
  6220. {
  6221.    return n->parent;
  6222. }
  6223.  
  6224. FUNCTION nodep child(n)
  6225. nodep n;
  6226. {
  6227.    return n->child;
  6228. }
  6229.  
  6230. FUNCTION nodep lastSibling(n)
  6231. nodep n;
  6232. {
  6233.    return n->lastSibling;
  6234. }
  6235.  
  6236. FUNCTION nodep nextSibling(n)
  6237. nodep n;
  6238. {
  6239.    return n->nextSibling;
  6240. }
  6241.  
  6242. FUNCTION nodep treeLastSibling(n)
  6243. nodep n;
  6244. {
  6245.    while (n->nextSibling) {
  6246.       n = n->nextSibling;
  6247.    }
  6248.    return n;
  6249. }
  6250.  
  6251. /* go to next node down the tree. Stop if at bottom. */
  6252. FUNCTION nodep treeDown(n)
  6253. nodep n;
  6254. {
  6255.    if (n->child) {
  6256.       BUG("treeDown: going down\n");
  6257.       return child(n);
  6258.    } else {
  6259.       BUG("treeDown: stop\n");
  6260.       return n;
  6261.    }
  6262. }
  6263.  
  6264. /* backup, stop if at top */
  6265. FUNCTION nodep treeUp(n)
  6266. nodep n;
  6267. {
  6268.    if (n->parent) {
  6269.       BUG("treeUp: going up\n");
  6270.       return parent(n);
  6271.    } else {
  6272.       BUG("treeUp: staying\n");
  6273.       return n;
  6274.    }
  6275. }
  6276.  
  6277.  
  6278. /* go to next node backing up the tree only */
  6279. FUNCTION nodep treeNextUp(n)
  6280. nodep n;
  6281. {
  6282.    if (n->nextSibling) {
  6283.       BUG("nextSibling ");
  6284.       return nextSibling(n);
  6285.    } else if (n->parent) {
  6286.       BUG("nextup-parent ");
  6287.       while (n->parent && !n->nextSibling)
  6288.      n = parent(n);
  6289.       if (n->nextSibling)
  6290.      return nextSibling(n);
  6291.       else
  6292.      return n;
  6293.    } else if (n->child) {
  6294.       BUG("child ");
  6295.       return child(n);
  6296.    } else {
  6297.       BUG("current ");
  6298.       return n;
  6299.    }
  6300. }
  6301.  
  6302.  
  6303. /* go to next node, backup if neccessary */
  6304. FUNCTION nodep treeNext(n)
  6305. nodep n;
  6306. {
  6307.    nodep r;
  6308.  
  6309.    BUG("treeNext:");
  6310.    if (n != (r = treeDown(n))) {
  6311.       BUG("going down ");
  6312.    } else {
  6313.       BUG("going up ");
  6314.       r = treeNextUp(n);
  6315.    }
  6316.    BUG("\n");
  6317.    return r;
  6318. }
  6319.  
  6320.  
  6321.  
  6322. FUNCTION nodep lastChildOfLastSibling(n)
  6323. nodep n;
  6324. {
  6325.  
  6326.    while (n->nextSibling)
  6327.       n = nextSibling(n);
  6328.    if (n->child)
  6329.       return lastChildOfLastSibling(child(n));
  6330.    else
  6331.       return n;
  6332. }
  6333.  
  6334. /* go to next node, backup if neccessary */
  6335. FUNCTION nodep treeLast(n)
  6336. nodep n;
  6337. {
  6338.    nodep r;
  6339.  
  6340.    if (n->lastSibling) {
  6341.       n = lastSibling(n);
  6342.       if (n->child)
  6343.      r = lastChildOfLastSibling(child(n));
  6344.       else
  6345.      r = n;
  6346.    } else if (n->parent) {
  6347.       r = parent(n);
  6348.    } else if (n->child) {
  6349.       r = lastChildOfLastSibling(child(n));
  6350.    } else {
  6351.       r = n;
  6352.    }
  6353.    return r;
  6354. }
  6355. SHAR_EOF
  6356. fi
  6357. if test -f 'mgt.h'
  6358. then
  6359.     echo shar: "will not over-write existing file 'mgt.h'"
  6360. else
  6361. cat << \SHAR_EOF > 'mgt.h'
  6362. /* "mgt" Copyright (c) 1991 Shodan  */
  6363.  
  6364. #define VERSION "2.2"
  6365.  
  6366. #ifdef DEBUG
  6367. #define BUG(s) fprintf(debug,s)
  6368. #else
  6369. #define BUG(s)
  6370. #endif
  6371.  
  6372. #define FUNCTION
  6373. #define false 0
  6374. #define true 1
  6375.  
  6376. #define MAX(a,b) ((a)>(b)?a:b)
  6377. #define MIN(a,b) ((a)<(b)?a:b)
  6378.  
  6379. #define MAX_FILES 200
  6380. #define MAX_LETTERS 12
  6381. #define MAXCOMMENT 4097
  6382. #define MAXCOMMENTLINES 300
  6383. #define MAXCOMMENTWIDTH 50
  6384.  
  6385. typedef int boolean;
  6386.  
  6387. typedef enum {
  6388.    C_QUIT = 0,
  6389.    C_DOWN, C_UP,
  6390.    C_WALKDOWN, C_WALKUP,
  6391.    C_END, C_BEGINNING,
  6392.    C_SEARCHCOMMENT, C_SEARCHBACKCOMMENT,
  6393.    C_DOWNFORK, C_UPFORK,
  6394.    C_GOTO,
  6395.    C_WRITE,
  6396.    C_ADDBLACK, C_ADDWHITE,
  6397.    C_ADDVAR,
  6398.    C_TREECUT,
  6399.    C_ADDLETTER, C_ADDMARK,
  6400.    C_LOAD, C_PASTE,
  6401.    C_EDCOMMENT,
  6402.    C_DELNODE, C_ADDNAME, C_SCORE, C_PASSMOVE, C_TOPLAY, C_TOGGLESTONE, C_BACKFILE, C_NEXTFILE,
  6403.    C_REDRAW, C_SAVESHORT, C_TUTORSWAP, C_SAVESCREEN, C_INFO, C_MOVE,
  6404.    C_DOWNLEFT, C_CURDOWN, C_DOWNRIGHT, C_CURLEFT,
  6405.    C_CURRIGHT, C_UPLEFT, C_CURUP, C_UPRIGHT,
  6406.    C_LASTCOMMAND, C_UNDO
  6407. }  command;
  6408.  
  6409.  
  6410. /* C_COMMENTSCROLLDOWN, C_COMMENTSCROLLUP, C_TREESCROLLDOWN, C_TREESCROLLUP, */
  6411.  
  6412. #define C_NOTHING ((command) 75)
  6413. #define C_CHOSECHILD ((command) 76)
  6414. #define C_NEXTCMD ((command) 127)
  6415.  
  6416. typedef enum {
  6417.    t_White,
  6418.    t_Black,
  6419.    t_Open,
  6420.    t_Close,
  6421.    t_NewNode,
  6422.    t_Comment,
  6423.    t_AddWhite,
  6424.    t_AddBlack,
  6425.    t_Letter,
  6426.    t_Mark,
  6427.    t_AddEmpty,
  6428.    t_Name,
  6429.    t_Pass,
  6430.    t_Player,
  6431.    t_Size,
  6432.    t_Handicap,
  6433.    t_PlayerBlack,
  6434.    t_BlackRank,
  6435.    t_PlayerWhite,
  6436.    t_WhiteRank,
  6437.    t_GameName,
  6438.    t_Event,
  6439.    t_Round,
  6440.    t_Date,
  6441.    t_Place,
  6442.    t_TimeLimit,
  6443.    t_Result,
  6444.    t_GameComment,
  6445.    t_Source,
  6446.    t_User,
  6447.    t_Komi,
  6448.  
  6449.    t_WS,
  6450.    t_EOF
  6451. }
  6452.    Token;
  6453.  
  6454.  
  6455. #define FIRSTINFO ((int)t_PlayerBlack)
  6456. #define LASTINFO  ((int)t_User)
  6457.  
  6458.  
  6459. typedef enum {
  6460.    P_NOTHING = 0, P_BLACK, P_WHITE, P_DAME, P_BLACKTERR, P_WHITETERR, P_CHECKED
  6461. }
  6462.    piece;
  6463.  
  6464. typedef piece boardType[19][19];
  6465.  
  6466. typedef struct {
  6467.    boardType b;
  6468. }
  6469.    board, *pBoard;
  6470.  
  6471.  
  6472. typedef int (*pfi) ();
  6473.  
  6474. typedef struct {
  6475.    char *name;
  6476.    char *option;
  6477.    char *storage;
  6478.    pfi open, close, refreshIO, plotPiece, displayComment;
  6479.    pfi clearComment, initializeBoard, clearScreen, idle;
  6480.    pfi drawTree, highlightLast, readEnv, notifyMessage;
  6481.    pfi notifyClear, queryStr, setCursor, plotMark, plotLetter;
  6482.    pfi getPoint, editComment, askYN, notifyError, displayInfo;
  6483.    pfi getInfoToChange, editInfo;
  6484. }
  6485.    interface, *interfaceP;
  6486.  
  6487.  
  6488. typedef struct {
  6489.    char x, y;
  6490. }
  6491.    coord;
  6492.  
  6493.  
  6494. typedef struct coordstruct {
  6495.    char x, y;
  6496.    struct coordstruct *next;
  6497. }  coordList;
  6498.  
  6499.  
  6500. typedef struct propertyRec {
  6501.    struct propertyRec *next;
  6502.    Token t;
  6503.    union {
  6504.       coordList *stones;
  6505.       char *comment;
  6506.       Token player;
  6507.    }  data;
  6508. }
  6509.    property;
  6510.  
  6511.  
  6512. typedef struct noderec {
  6513.    property *p;
  6514.    int nodeNum;
  6515.    struct noderec *parent, *child, *nextSibling, *lastSibling;
  6516. }
  6517.    node, *nodep;
  6518.  
  6519.  
  6520. /* board coordinates used to indicate a pass */
  6521.  
  6522. #define PASSVAL 25
  6523.  
  6524.  
  6525.  
  6526. #include "proto.h"
  6527. #include <stdio.h>
  6528.  
  6529. #ifdef MGT_IBM
  6530. #include <alloc.h>
  6531. #endif
  6532.  
  6533.  
  6534. extern char *info[LASTINFO - FIRSTINFO + 2];
  6535. extern int handicap;
  6536.  
  6537. extern interface *io;
  6538. extern int boardsize;
  6539. extern FILE *input;
  6540. extern int xcur, ycur;
  6541. extern Token curPlayer;
  6542. extern int mailFlag;
  6543. extern int saveShort;
  6544. extern int tutor;
  6545. extern char *saveName;
  6546. extern int retVal;
  6547. extern char name_buf[512];
  6548. extern filecount, currentfile;
  6549. extern char *files[MAX_FILES];
  6550.  
  6551. #ifdef DEBUG
  6552. extern FILE *debug;
  6553. extern unsigned long totalmemory;
  6554. #endif
  6555. SHAR_EOF
  6556. fi
  6557. if test -f 'proto.h'
  6558. then
  6559.     echo shar: "will not over-write existing file 'proto.h'"
  6560. else
  6561. cat << \SHAR_EOF > 'proto.h'
  6562. extern void clearLast();
  6563. extern void highlightLast();
  6564. extern void doPlace();
  6565. extern void doProps();
  6566. extern void doPropComment();
  6567. extern void buildTree0();
  6568. extern void buildTree();
  6569. extern void setPiece();
  6570. extern void updateBoard();
  6571. extern char *commentGet();    /* int */
  6572. extern int commentLines();
  6573. extern void formatComment();
  6574. extern int okChange();
  6575. extern int okExit();
  6576. extern nodep search();        /* return 0 on failure */
  6577. extern void step();
  6578. extern void stepDown();
  6579. extern void doScore();
  6580. extern nodep loadFile();
  6581. extern nodep makeTutor();
  6582. extern void doit();
  6583. extern void writeStrEscaped();
  6584. extern void writeNode();
  6585. extern void WriteSubTree();
  6586. extern int writeCoordList();
  6587. extern int writeTree();
  6588. extern int addMark();
  6589. extern void addStone();
  6590. extern int makeMove();
  6591. extern int passMove();
  6592. extern void addPlayer();
  6593. extern void makeVariation();
  6594. extern void cutTree();
  6595. extern boolean pasteTree();
  6596. extern void edComment();
  6597. extern void deleteNode();
  6598. extern void makeName();
  6599. extern void replaceComment();
  6600. extern main();
  6601. extern void die();
  6602. extern void myexit();
  6603. extern void openfile();
  6604. extern void barf();
  6605. extern void initEnv();
  6606. extern void init();
  6607. extern void helpCommandLine();
  6608. extern void parseLine();
  6609. extern void readInit();
  6610. extern void addChild();        /* add child c to node n */
  6611. extern nodep parse();
  6612. extern int legal();
  6613. extern boolean inRange();
  6614. extern boolean alive0();
  6615. extern boolean alive();        /* Does group at i,j have liberties? */
  6616. extern void removeStones();
  6617. extern boolean tryKill();
  6618. extern void placeStone();
  6619. extern void boardSet();
  6620. extern piece boardGet();
  6621. extern void boardClear();
  6622. extern void copyBoard();
  6623. extern void scoreBoard();
  6624. extern boolean getCoord();
  6625. extern coordList *addCoord();
  6626. extern void setCoord();
  6627. extern void clearCoord();
  6628. extern void initNodes();
  6629. extern nodep newNode();
  6630. extern void freeNode();
  6631. extern char *dupStr();
  6632. extern void freeProps();
  6633. extern void delNode();
  6634. extern void addprop();
  6635. extern property *getprop();
  6636. extern int treeCountSiblings();
  6637. extern nodep nthChild();    /* nodep, int */
  6638. extern nodep parent();
  6639. extern nodep child();
  6640. extern nodep lastSibling();
  6641. extern nodep nextSibling();
  6642. extern nodep treeLastSibling();
  6643. extern nodep treeDown();
  6644. extern nodep treeUp();
  6645. extern nodep treeNextUp();
  6646. extern nodep treeNext();
  6647. extern nodep lastChildOfLastSibling();
  6648. extern nodep treeLast();
  6649. SHAR_EOF
  6650. fi
  6651. if test -f 'mou.h'
  6652. then
  6653.     echo shar: "will not over-write existing file 'mou.h'"
  6654. else
  6655. cat << \SHAR_EOF > 'mou.h'
  6656. /*****************************************************************************
  6657.  * PROJECT:  Mouse routines with 'real' graphic cursor in text mode.
  6658.  *****************************************************************************
  6659.  * MODULE:  MOU.H
  6660.  *****************************************************************************
  6661.  * DESCRIPTION:
  6662.  *   Header file for the mouse routines.
  6663.  *
  6664.  *****************************************************************************
  6665.  * MODIFICATION NOTES:
  6666.  *    Date     Author Comment
  6667.  * 07-Jan-1991   dk   Fixed bugs and set up for release to Usenet.
  6668.  * 26-Oct-1990   dk   Initial file.
  6669.  *****************************************************************************
  6670.  *
  6671.  * DISCLAIMER:
  6672.  *
  6673.  * Programmers may incorporate any or all code into their programs,
  6674.  * giving proper credit within the source. Publication of the
  6675.  * source routines is permitted so long as proper credit is given
  6676.  * to Dave Kirsch.
  6677.  *
  6678.  * Copyright (C) 1990, 1991 by Dave Kirsch.  You may use this program, or
  6679.  * code or tables extracted from it, as desired without restriction.
  6680.  * I can not and will not be held responsible for any damage caused from
  6681.  * the use of this software.
  6682.  *
  6683.  *****************************************************************************
  6684.  * This source works with Turbo C 2.0 and MSC 6.0 and above.
  6685.  *****************************************************************************/
  6686.  
  6687. /********************************************************/
  6688. /* 26-Oct-1990 - dk                                     */
  6689. /*                                                      */
  6690. /*  Standard types and constants I use in my programs.  */
  6691. /*                                                      */
  6692. /********************************************************/
  6693.  
  6694. typedef unsigned char       byte;
  6695. typedef unsigned short int  word;
  6696. typedef unsigned short int  mouseboolean;
  6697. typedef unsigned long  int  dword;
  6698.  
  6699. #define FALSE 0
  6700. #define TRUE (!FALSE)
  6701.  
  6702. #ifdef __TURBOC__
  6703.   #define FAST pascal     /* for fast calling of functions -- Turbo C */
  6704. #else
  6705.   #define FAST _fastcall  /* for fast calling of functions -- MicroSoft C 6.0 */
  6706.   #define asm _asm
  6707. #endif
  6708. #define LOCAL   near   /* function can not be called outside of this module */
  6709. #define PRIVATE static /* function is private */
  6710. #define STATIC  static /* private variables */
  6711.  
  6712. #ifndef MK_FP
  6713.   #define MK_FP(seg,ofs)  ((void far *) \
  6714.                              (((unsigned long)(seg) << 16) | (unsigned)(ofs)))
  6715. #endif
  6716.  
  6717. #ifndef poke
  6718. #define poke(a,b,c)     (*((int  far*)MK_FP((a),(b))) = (int)(c))
  6719. #define pokeb(a,b,c)    (*((char far*)MK_FP((a),(b))) = (char)(c))
  6720. #define peek(a,b)       (*((int  far*)MK_FP((a),(b))))
  6721. #define peekb(a,b)      (*((char far*)MK_FP((a),(b))))
  6722. #endif
  6723.  
  6724. /***************************************************/
  6725. /* Mon 07-Jan-1991 - dk                            */
  6726. /*                                                 */
  6727. /*  Variables and defines for the mouse routines.  */
  6728. /*                                                 */
  6729. /***************************************************/
  6730.  
  6731. /* Size of mouse "click" ahead buffer. */
  6732. #define MOUSEBUFFERSIZE 16
  6733.  
  6734. /* Bit defines for mouse driver function 12 -- define handler. */
  6735. #define MOUSEMOVE      1
  6736. #define LEFTBPRESS     2
  6737. #define LEFTBRELEASE   4
  6738. #define RIGHTBPRESS    8
  6739. #define RIGHTBRELEASE 16
  6740. #define MIDBPRESS     32
  6741. #define MIDBRELEASE   64
  6742.  
  6743. #define LEFTBDOWN  1
  6744. #define RIGHTBDOWN 2
  6745. #define MIDBDOWN   4
  6746.  
  6747. /* Shift states for byte a 0:417h
  6748.    bit 7 =1 INSert active
  6749.    bit 6 =1 Caps Lock active
  6750.    bit 5 =1 Num Lock active
  6751.    bit 4 =1 Scroll Lock active
  6752.    bit 3 =1 either Alt pressed
  6753.    bit 2 =1 either Ctrl pressed
  6754.    bit 1 =1 Left Shift pressed
  6755.    bit 0 =1 Right Shift pressed
  6756. */
  6757.  
  6758. #define SHIFT_RIGHTSHIFT 0x01
  6759. #define SHIFT_LEFTSHIFT  0x02
  6760. #define SHIFT_SHIFT      0x03 /* Either shift key. */
  6761. #define SHIFT_CTRL       0x04
  6762. #define SHIFT_ALT        0x08
  6763. #define SHIFT_SCROLLLOCK 0x10
  6764. #define SHIFT_NUMLOCK    0x20
  6765. #define SHIFT_CAPSLOCK   0x40
  6766. #define SHIFT_INS        0x80
  6767.  
  6768. /* Mouse information record */
  6769. struct minforectype {
  6770.   word buttonstat;
  6771.   word    cx, cy;
  6772.   byte shiftstate;
  6773. };
  6774.  
  6775. #define MOUINFOREC struct minforectype
  6776.  
  6777. extern word mousehidden;           /* Is the mouse on? Additive flag */
  6778. extern mouseboolean mouseinstalled;     /* Is the mouse installed? */
  6779.  
  6780. extern volatile word mousex, mousey; /* Mouse coordinates in characters. */
  6781.  
  6782. /* Initialize the mouse routines -- must be called. */
  6783. void    FAST MOUinit(void);
  6784.  
  6785. /* Deinitialize the mouse routines -- must be called on shutdown.
  6786.    Failure to call it will most likely result in a system crash if the mouse
  6787.    is moved. */
  6788. void    FAST MOUdeinit(void);
  6789.  
  6790. /* Hide the mouse cursor */
  6791. void    FAST MOUhide(void);
  6792.  
  6793. /* Hide the mouse cursor if it moves or is in a specific rectangular region
  6794.    of the screen. */
  6795. void    FAST MOUconditionalhide(int x1, int y1, int x2, int y2);
  6796.  
  6797. /* Show the mouse cursor */
  6798. void    FAST MOUshow(void);
  6799.  
  6800. /* return TRUE if there are events waiting in the buffer. */
  6801. mouseboolean FAST MOUcheck(void);
  6802.  
  6803. /* look at the next event in the buffer, but don't pull it out. */
  6804. void    FAST MOUpreview(MOUINFOREC *mouinforec);
  6805.  
  6806. /* get and remove next event from the buffer. */
  6807. void    FAST MOUget(MOUINFOREC *mouinforec);
  6808.  
  6809. /* return the current status of the mouse buttons (see defines above). */
  6810. word    FAST MOUbuttonstatus(void);
  6811.  
  6812. /* Set the mouse cursor to a specific screen position. */
  6813. void FAST MOUsetpos(word x, word y);
  6814. 
  6815. SHAR_EOF
  6816. fi
  6817. if test -f 'Smart-Go.def'
  6818. then
  6819.     echo shar: "will not over-write existing file 'Smart-Go.def'"
  6820. else
  6821. cat << \SHAR_EOF > 'Smart-Go.def'
  6822.                    DEFINITION OF THE SMART-GO FORMAT
  6823.  
  6824. From the Dissertation of Anders Kierulf
  6825.  
  6826. "Smart Game Board:
  6827. a Workbench for Game-Playing
  6828. Programs, with Go and Othello
  6829. as Case Studies"
  6830.  
  6831. Entered by Greg Hale with permission for distribution. See the many sample 
  6832. files from the 'My Go Teacher' series for examples. 
  6833.     
  6834. ------------
  6835.  
  6836. A standard file format to exchange machine-readable games, problems,
  6837. and opening libraries would save time and work.  That goal may not be
  6838. too far away.  A standard for exchanging collections of Othello games
  6839. is being worked out by Erik Jensen, Emmanuel Lazard, and Brian Rose in
  6840. collaboration with the author.  For Go, a new standard has recently
  6841. been proposed [Connelley 89, High 89]; it seems to suffer from a wealth
  6842. of features, but any standard for exchanging Go games is welcome, and
  6843. will be supported by the Smart Game Board.
  6844.  
  6845. The current file format is specialized for the needs of the Smart Game
  6846. Board.  It is based on an earlier proposal for a standard for Go games
  6847. [Kierulf 87b] which was not widely adopted.  The following description
  6848. is not a new proposal; it is intended for those who want to read or
  6849. white files that are compatible with the Smart Game Board.
  6850.  
  6851. The game collections (documents) of the Smart Game Board are stored as
  6852. text files.  This has the advantage that files can be manipulated with
  6853. standard text utilities, and that it's easier to exchange games by
  6854. electronic mail.  The disadvantage is that text files are less compact
  6855. than binary files.
  6856.  
  6857. The Smart Game Board stores the game trees of each document, with all
  6858. their nodes and properties, and nothing more.  Thus the file format
  6859. reflects the regular internal structure of a tree of property lists.
  6860. There are no exceptions; if a game needs to store some information on
  6861. file with the document, a (game-specific) property must be defined for
  6862. that purpose.
  6863.  
  6864. I will first define the syntax of the game collections, then discuss
  6865. syntax and semantic of various properties.
  6866.  
  6867.  
  6868. GAME COLLECTIONS
  6869.  
  6870. A collection of game sis simply the concatenation of the game trees.
  6871. The structure of each tree is indicated by parentheses.  A tree is
  6872. written as "(" followed by a sequence of nodes (as long as the tree is
  6873. unbranched) and a tree for each son, and terminated by ")".  Each node
  6874. is preceded by a separator, and contains a list of zero or more
  6875. properties.
  6876.  
  6877. Thus the main branch of the game is stored first in the file, and
  6878. programs can easily read that part (until the first closing
  6879. parenthesis) and ignore the rest.
  6880.  
  6881. The conventions of EBNF are discussed in [Wirth 85].  A quick summary:
  6882.  
  6883. "..." : terminal symbols
  6884. [...] : option: occurs at most once
  6885. {...} : repetition: any number of times, including zero
  6886. (...) : grouping
  6887.   |   : exclusive-or
  6888.  
  6889. The overall definition of the file format is as follows:
  6890.  
  6891.         Collection      = {GameTree}.
  6892.         GameTree        = "(" Sequence {GameTree} ")".
  6893.         Sequence        = Node {Node}.
  6894.         Node            = ";" {Property}
  6895.  
  6896. Any text before the first opening parenthesis is reserved for future
  6897. extensions and is ignored when reading a file.  Spaces, tabs, line
  6898. breaks and so on can be inserted anywhere between properties and are
  6899. also ignored.
  6900.  
  6901.  
  6902. GAME-INDEPENDENT PROPERTIES
  6903.  
  6904. Each property is identified by one or two capital letters.  The
  6905. property value is enclosed in brackets; lists of points or integers are
  6906. written as a sequence of property values.  Within text, a closing
  6907. bracket is prefixed by a backslash, and a backslash is doubled.  Moves
  6908. and points are game-specific and are defined later.
  6909.  
  6910.         Property        = PropIdent PropValue {PropValue}.
  6911.         PropIdent       = UpperCase [UpperCase | Digit].
  6912.         PropValue       = "[" [Number | Text | Real | Triple
  6913.                                   | Color | Move | Point | ... ] "]"
  6914.         Number          = ["+" | "-"] Digit {Digit}.
  6915.         Text            = { any character; "\]" = "]", "\\" = "\"}.
  6916.         Real            = { Number ["." {Digit}].
  6917.         Triple          = ("1" | "2").
  6918.         Color           = ("B" | "W").
  6919.  
  6920. Move and Point are game-specific and are described later.  The
  6921. following properties are understood by all games.  The property type is
  6922. given in brackets.
  6923.  
  6924.         "B" : Black move                [move, game-specific]
  6925.         "W" : White move                [move, game-specific]
  6926.         "C" : Comment                   [Text]
  6927.         "N" : Node Name                 [Text]
  6928.  
  6929. The purpose of providing both a node name and a comment is to have a
  6930. short identifier like "doesn't work" or "Dia. 15" that can be displayed
  6931. directly with the properties of the node, even if the comment is turned
  6932. off or shown in a separate window.  There is no limit to the length of
  6933. texts; programs must be able to ignore the rest of texts that are too
  6934. long for them to handle.  Reasonable limits are 32 characters for node
  6935. names and at least 2000 characters for comments.
  6936.  
  6937.         "V" : Node value                [number]
  6938.  
  6939. Positive values are good for Black, negative values are good for
  6940. White.  The interpretation of particular values is game-specific.
  6941.  
  6942.         "CH": Check mark                [triple]
  6943.         "GB": good for black            [triple]
  6944.         "GW": good for white            [triple]
  6945.         "TE": good move (tesuji)        [triple]
  6946.         "BM": bad move                  [triple]
  6947.  
  6948. The normal value for such properties is one, properties that are
  6949. doubled for emphasis have the value two.
  6950.  
  6951.         "BL": time left for Black       [real]
  6952.         "WL": time left for White       [real]
  6953.  
  6954. All times are given in seconds, or fractions thereof {Hale: these can
  6955. be negative, indicating player is playing past time limit set}.
  6956.  
  6957.         "FG": figure                    [none]
  6958.  
  6959. The figure property is used to divide a game into different figures for
  6960. printing: a new figure starts at the node with a figure property.
  6961.  
  6962.         "AB": add black stones          [point list, game specific]
  6963.         "AW": add white stones          [point list, game specific]
  6964.         "AE": add empty stones          [point list, game specific]
  6965.         "PL": player to play first      [color]
  6966.  
  6967. The above properties are used to set up positions in games with only
  6968. black and white stones.  The following properties are all part of the
  6969. game info:
  6970.  
  6971.         "GN": game name                 [text]
  6972.         "GC": game comment              [text]
  6973.         "EV": event (tournament)        [text]
  6974.         "RO": round                     [text]
  6975.         "DT": date                      [text]
  6976.         "PC": place                     [text]
  6977.         "PB": black player name         [text]
  6978.         "PW": white player name         [text]
  6979.         "RE": result, outcome           [text]
  6980.         "US": user (who entered game)   [text]
  6981.         "TM": time limit per player     [text]
  6982.         "SO": source (book, journal...) [text]
  6983.  
  6984. The format in these game-info strings is free, but to be able to search
  6985. for specific games in game collections, it is recommended to adhere to
  6986. the following conventions:
  6987.  
  6988.         - Date is ISO-standard: "YYYY-MM-DD".
  6989.         - Result as "0" (zero) for a draw, "B+score" for a black win,
  6990.                 and "W+score" for a white win, e.g. "B+2.5", "W+64"
  6991.         - Time limit as a number, in minutes.
  6992.  
  6993. In addition, names, events, and places should be spelled the same im all games.
  6994.  
  6995. The following properties may only be present at the root node:
  6996.  
  6997.         "GM": game [number] (Go=1, Othello=2, chess=3, Nine Mens Morris=5)
  6998.         "SZ": board size        [number]
  6999.         "VW": partial view      [point list, game-specific]
  7000.         "BS": black species     [number] (human=0, modem=-1, computer>0)
  7001.         "WS": white species     [number]
  7002.  
  7003. The game number helps the program reject games it cannot handle (this
  7004. property was mandatory as long as an application could play different
  7005. games).  The view gives two corner points of a rectangular subsection;
  7006. an empty list denotes the whole board.  The species denotes the kind of
  7007. player (the source of the more input), with different version of
  7008. computer algorithms denoted by positive numbers (default algorithm =
  7009. 1).
  7010.  
  7011. Computer algorithms may add the following properties:
  7012.  
  7013.         "EL": evaluation of computer move       [number]
  7014.         "EX": expected next move                [move, game-specific]
  7015.  
  7016. Some games support markings on the board: selected points,
  7017. triangles/crosses, or letters (a sequence of letters is shown on the
  7018. points given in the list, starting with "A"):
  7019.  
  7020.         "SL": selected points                   [point list, game-specific]
  7021.         "M" : marked points                     [point list, game-specific]
  7022.         "L" : letters on points                 [point list, game-specific]
  7023.  
  7024.  
  7025. GO-SPECIFIC PROPERTIES
  7026.  
  7027. In my proposal for a standard [Kierul 87b], I intentionally broke with
  7028. the tradition of labeling moves (and points) with letters "A"-"T"
  7029. (excluding "i") and numbers 1-19.  Two lowercase letters in the range
  7030. "a"-"s" were used instead, for reasons of simplicity and compactness.
  7031. This was criticized mainly because it was not human-readable, but as
  7032. that is not an important feature of this file format, I continue to use
  7033. that notation.
  7034.  
  7035. (Hale: diagram omitted)
  7036.  
  7037. The first letter designated the column (left to right), the second the
  7038. row (top to bottom).  The upper left part of the board is used for
  7039. smaller boards, e.g. letters "a"-"m" for 13*13.  (Column before row
  7040. follows the principle "horizontal before vertical" used in x-y
  7041. coordinate systems.  The upper left corner as origin of the board
  7042. corresponds to the way we read, and most modern computers use it as
  7043. origin of the screen coordinates to simplify integration of text and
  7044. graphics.)  A pass move is written as "tt".
  7045.  
  7046. The board must be quadratic, no smaller than 2x2, and no larger than
  7047. 19x19.
  7048.  
  7049. Additional game info properties are defined for Go:
  7050.  
  7051.         "BR": Black's rank              [text]
  7052.         "WR": White's rank              [text]
  7053.         "HA": handicap                  [number]
  7054.         "KM": komi                      [real]
  7055.  
  7056. Sets of board points can be marked as territory, as secure stones, or
  7057. just as a region of the board (e.g. to designate eye space):
  7058.  
  7059.         "TB": Black's territory         [point list]
  7060.         "TW": White's territory         [point list]
  7061.         "SC": secure stones             [point list]
  7062.         "RG": region of the board       [point list]
  7063.  
  7064. SHAR_EOF
  7065. fi
  7066. if test -f 'README'
  7067. then
  7068.     echo shar: "will not over-write existing file 'README'"
  7069. else
  7070. cat << \SHAR_EOF > 'README'
  7071. -----------------------------------------------------------------------
  7072.  
  7073.            "mgt" Copyright 1991 Shodan
  7074.         All Rights Reserved.
  7075.         Program by Greg Hale
  7076.  
  7077. Permission to use, copy, modify, and distribute this software and its
  7078. documentation for any purpose and without fee is hereby granted,
  7079. provided that this entire comment and copyright notice appear in all
  7080. copies and that both that copyright notice and this permission notice
  7081. appear in supporting documentation.  No representations are made about
  7082. the suitability of this software for any purpose.  It is provided "as
  7083. is" without express or implied warranty.
  7084.  
  7085. -----------------------------------------------------------------------
  7086.  
  7087. To compile under UNIX, type 'make'
  7088.  
  7089. Under VMS, delete the mou.c file and then type '@build'
  7090.  
  7091. Under MS-DOS with Borland-C, type 'make -f makefile.bc'
  7092.  
  7093. -----------------------------------------------------------------------
  7094.               THERE IS NO X VERSION OF THIS PROGRAM
  7095. -----------------------------------------------------------------------
  7096.  
  7097. *** Be sure to get the From My Go Teacher tutorial materials available
  7098. *** on anonymous ftp at milton.u.washington.edu.
  7099.  
  7100. -----------------------------------------------------------------------
  7101.  
  7102. Please send copies of extensions to:  hale@scam.berkeley.edu
  7103.  
  7104. Thanks to the following for suggestions, debugging, code writing, and testing:
  7105.  
  7106.            mgt - you know why he's here :)
  7107.  
  7108.     Kurt Wallnau - for playing and suggesting
  7109.     Jeff Boscole - for sleepless nights of debugging and testing
  7110.     Thos Sumner  - for extensive help with explaining some UNIX particulars
  7111.  
  7112.     Adrian Mariano - (adrian@u.washington.edu) 
  7113.              - massive code extensions, plus IBM version
  7114.     Tim Casey      (tcasey@triton.umn.edu)
  7115.     Mike Dobbins - lots testing and suggestions
  7116.     Eric Osman   - for getting things to work under VMS
  7117.     Steve Hollasch - debugging assistance
  7118.     Huayong Yang - comments, bug reports
  7119.  
  7120. --------------------------------------
  7121. Changes from version 2.1 to 2.2
  7122.  
  7123.   o Increased speed of moving backwards through game record or jumping
  7124.     to an arbitrary node.
  7125.   o Tutor mode
  7126.   o Support for informational properties
  7127.   o Support for PLayer property, and passing (as a move)
  7128.   o Removed restriction on number of letters or marks
  7129.   o Detection of ko during game play
  7130.  
  7131.   o For the IBM version: Mouse support and improved display for the 
  7132.  
  7133. --------------------------------------
  7134. Changes:
  7135.  
  7136. 2/6/90 V1.0.   First release.  All is holding together fine, but no
  7137.     optimization has been done yet.  That is next on the list.  My
  7138.     apologies to the CPU's. :(
  7139.  
  7140. 2/1/91 V2.0.   mgt is more optimized.  IBM version support, revision of
  7141.     display, fixed lots of little bugs, more commands, basic editing
  7142.     of comments, save & load, play-by-mail facility added.
  7143.  
  7144. SHAR_EOF
  7145. fi
  7146. if test -f 'Makefile'
  7147. then
  7148.     echo shar: "will not over-write existing file 'Makefile'"
  7149. else
  7150. cat << \SHAR_EOF > 'Makefile'
  7151. #   There is NO X version of this program
  7152. #
  7153. #        "mgt" Copyright 1991 Shodan
  7154. #        All Rights Reserved.
  7155. #        Program by Greg Hale and Adrian Mariano
  7156. #
  7157. #Permission to use, copy, modify, and distribute this software and its
  7158. #documentation for any purpose and without fee is hereby granted,
  7159. #provided that this entire comment and copyright notice appear in all
  7160. #copies and that both that copyright notice and this permission notice
  7161. #appear in supporting documentation.  No representations are made about
  7162. #the suitability of this software for any purpose.  It is provided "as
  7163. #is" without express or implied warranty.
  7164. #
  7165. #Please send copies of extensions to:
  7166. #
  7167. # hale@scam.berkeley.edu
  7168. # 128.32.138.4    scam.berkeley.edu
  7169. #
  7170. #Donations for the 'From My Go Teacher' series may be sent to:
  7171. #    Shodan
  7172. #    P.O. Box 4456
  7173. #    Berkeley, CA 94704
  7174. #    (415) 849-9475
  7175. #
  7176. #
  7177. # Makefile for mgt
  7178. # by Greg Hale and Adrian Mariano
  7179. #
  7180. # *** C compile flags.
  7181. #
  7182. # -O: optimize
  7183. # -DDEBUG: turn on program debugging
  7184. #
  7185. # *** CONFIGURATION ***
  7186. #
  7187. # Choose one of
  7188. #   -DMGT_UNIX  Compile under UNIX
  7189. #   -DMGT_IBM   Compile on IBM PC under Turbo C (Use the other Makefile!)
  7190. #
  7191. #   -DMGT_LIB="/usr/hale/mgt.lib/":   defines a library directory for games
  7192. #
  7193.  
  7194. DEFS=-DMGT_UNIX
  7195.  
  7196. # If you read this Makefile, you may notice many references to an 
  7197. # X Windows program.  This program is under development but has not yet
  7198. # been released.  Send email inquiries to tcasey@triton.unm.edu.
  7199.  
  7200.  
  7201. CFLAGS = -O $(DEFS)
  7202. CC = cc
  7203.  
  7204. # DIRECTORIES - CONFIGURE DESTINATIONS
  7205. # BINDIR is where it is installed
  7206. DEST        =        .
  7207. BINDIR        =        .
  7208. ASC_PROGRAM    =        mgt
  7209. MAN             =        mgt.doc
  7210. SHAR         =        mgt.sh
  7211.  
  7212. # files which make up the shell archive along with sources
  7213.  
  7214. FILES = Smart-Go.def README Makefile format mgt.6 Spec.io Makefile.bc \
  7215. Build.com mailgo mailgo.6 mgtdoc.asc Sample.01 Sample.02 Rules Prop.lst \
  7216. README.IBM
  7217.  
  7218. SH_OBJS= help.o \
  7219. build.o comment.o doit.o edit.o mgt.o parse.o play.o tree.o
  7220.  
  7221. SH_SRCS= help.c \
  7222. ascii.c build.c comment.c doit.c edit.c mgt.c parse.c play.c tree.c
  7223.  
  7224. ASC_OBJS= ascii.o
  7225.  
  7226. ASC_LIBS= -lcurses -ltermlib 
  7227.  
  7228. OBJECTS = help.o \
  7229. ascii.o build.o comment.o doit.o edit.o mgt.o parse.o play.o tree.o
  7230.  
  7231.  
  7232. SRCS = help.c asc_ibm.inc asc_unix.inc mou.c\
  7233. ascii.c build.c comment.c doit.c edit.c mgt.c parse.c play.c tree.c
  7234.  
  7235. HDRS = mgt.h proto.h mou.h
  7236.  
  7237. all: ascii
  7238.         
  7239.  
  7240. X11: 
  7241.     @echo "The X11 version is not yet available.  You can only"
  7242.     @echo "make the ascii version."
  7243.  
  7244.  
  7245. ascii.o: ascii.c asc_unix.inc
  7246.  
  7247.  
  7248. ascii: $(ASC_PROGRAM) man
  7249.  
  7250.  
  7251. $(ASC_PROGRAM): $(SH_OBJS) $(ASC_OBJS)
  7252.     @echo -n "loading $(ASC_PROGRAM)..."
  7253.     @$(CC) $(SH_OBJS) $(ASC_OBJS) $(ASC_LIBS) -o $(DEST)/$(ASC_PROGRAM);
  7254.     @echo "done."
  7255.  
  7256. $(MAN): mgt.6
  7257.     @echo -n "Creating mgt manual..."
  7258.     @nroff -man mgt.6 > $(MAN)
  7259.     @echo "done."
  7260.  
  7261. mailgo.doc: mailgo.6
  7262.     @echo -n "Creating mailgo manual..."
  7263.     @nroff -man mailgo.6 > mailgo.doc
  7264.     @echo "done."
  7265.  
  7266. man: $(MAN) mailgo.doc
  7267.  
  7268. clean:
  7269.     @echo -n "removing extra files..."
  7270.     @-rm -f *.o $(DEST)/$(X_PROGRAM) $(DEST)/$(ASC_PROGRAM) $(SHAR)
  7271.     @echo "done."
  7272.  
  7273. proto:
  7274.     @echo -n "making proto.h file..."
  7275.     @-rm -f ./proto.h
  7276.     @egrep "FUNCTION" $(SH_SRCS) | sed "s/(.*)/();/" | sed "s/^.*://" | sed "s/FUNCTION/extern/"  | cat > ./proto.h
  7277.     @echo "done."
  7278.  
  7279. lint:
  7280.     @echo -n "making lint file..."
  7281.     @-rm -f ./lint.out
  7282.     @lint -u $(DEFS) $(SH_SRCS) > ./lint.out
  7283.     @echo "done."
  7284.  
  7285. new: proto clean all
  7286.  
  7287. mgtdoc.asc: $(MAN)
  7288.     @echo -n "Making ascii doc file..."
  7289.     @cat $(MAN) | col -b > mgtdoc.asc;
  7290.     @echo "done."
  7291.  
  7292.  
  7293. shar: mgtdoc.asc
  7294.     @shar $(SRCS) $(HDRS) $(FILES) > $(SHAR)
  7295.  
  7296. install: $(PROGRAM) $(ARCHIVE)
  7297.     @-install $(DEST)/$(PROGRAM) $(BINDIR)/$(PROGRAM)
  7298.  
  7299.  
  7300.  
  7301.  
  7302. SHAR_EOF
  7303. fi
  7304. if test -f 'format'
  7305. then
  7306.     echo shar: "will not over-write existing file 'format'"
  7307. else
  7308. cat << \SHAR_EOF > 'format'
  7309. #!/bin/csh -f
  7310. foreach f ( $* )
  7311. indent -ndj -i3 -ip0 -npcs -cli3 -di3 -npsl -ncdb -l80 $f
  7312. end
  7313.  
  7314. SHAR_EOF
  7315. chmod +x 'format'
  7316. fi
  7317. if test -f 'mgt.6'
  7318. then
  7319.     echo shar: "will not over-write existing file 'mgt.6'"
  7320. else
  7321. cat << \SHAR_EOF > 'mgt.6'
  7322. .TH MGT 6  "30 April 1992"
  7323. .SH NAME
  7324. mgt - game record display/editor for the oriental game of go
  7325. .SH SYNOPSIS
  7326. .B mgt
  7327. [\-m filename] [\-s] [-t] [files]
  7328. .SH DESCRIPTION
  7329. Go is an ancient oriental strategy game based on the capturing of territory.
  7330. The players alternate putting stones on the board, 
  7331. trying to surround as many empty intersections as possible.  
  7332. .LP
  7333. .B Mgt
  7334. allows the user to examine Go game tree files created through the 
  7335. Macintosh(tm) programs 
  7336. .B Smart-Go (tm)
  7337. or
  7338. .B Go Explorer (tm). 
  7339. .B Mgt
  7340. also has basic Go game tree editing capabilities and may be used to
  7341. create or edit game tree files.
  7342. The on\-line material provided by a
  7343. rather extensive and growing database allows many hours of instructional
  7344. enjoyment of various studies and tutorials concerning the game of Go. 
  7345. .LP
  7346. .B Mailgo 
  7347. is a utility which manages E-mail Go games using  
  7348. .B mgt 
  7349. as the Go board editor.  It is included in the 
  7350. .B mgt 
  7351. package.  
  7352. .LP
  7353. The 
  7354. .B mgt 
  7355. program was originally developed to be a companion for the series, 
  7356. "From My Go Teacher",
  7357. archived at scam.berkeley.edu and milton.u.washington.edu for ftp.
  7358. Also available is the Internet GO Board communications program, 'go',
  7359. also by Greg Hale, which connects up two terminals in real\-time
  7360. anywhere in the world.
  7361. .SH COMMAND LINE OPTIONS
  7362. .TP 8
  7363. .B \-m filename
  7364. Invoke a set of options used by the 
  7365. .B mailgo
  7366. program for managing email games.  If a filename is specified for
  7367. loading (see below), the game record is loaded, and 
  7368. .B mgt
  7369. automatically moves to the end of the main variation of the game record.
  7370. The game can be modified without confirmation.
  7371. If the game record has been modified, 
  7372. it will be automatically saved, on exit, to the filename 
  7373. specified after the \-m and 
  7374. .B mgt
  7375. will return success (zero).  If the game record has not been modified, 
  7376. or has not been allowed to be saved, then 
  7377. .B mgt 
  7378. will return failure (nonzero). 
  7379. .LP
  7380. .TP 8
  7381. .B \-s
  7382. Change save format used to write save files.  The default save format is
  7383. the long format Smart\-Go file.  Using this option results in 
  7384. short format Smart\-Go files.
  7385. .LP
  7386. .TP 8
  7387. .B \-t
  7388. Invoke tutor mode where you select variations by playing on the board.
  7389. The key for making a move has special behavior in this mode.  See the 
  7390. section on the "space or 0" keyboard command for a description.
  7391. .LP
  7392. .TP 8
  7393. .B files
  7394. These are the files to be loaded.  The Unix and IBM version support 
  7395. wildcards.  If no file is specified, 
  7396. .B mgt 
  7397. loads a blank board.  If you attempt to modify a file that was loaded,
  7398. .B mgt 
  7399. will prompt for confirmation the first time.  
  7400. .LP
  7401. .SH OPERATION
  7402. .B Mgt
  7403. can be used to view and edit game records, 
  7404. or as an electronic game board for a two person 
  7405. game.  There are many keyboard commands which execute 
  7406. the various editing and display functions.
  7407. .LP
  7408. .TP 8
  7409. Step down the game tree to the next move.  Stop at the end of a variation
  7410. and do not visit other variations.
  7411. .LP
  7412. .TP 8
  7413. <
  7414. Move back up the game tree.  (Previous move)
  7415. .LP
  7416. .TP 8
  7417.  .
  7418. Go to the next node using a tree traversal which will visit all nodes.
  7419. Sometimes the order of traversal can be confusing.
  7420. .LP
  7421. .TP 8
  7422. ,
  7423. Go to the previous node -- the opposite of "." forward movement.
  7424. .LP
  7425. .TP 8
  7426. e
  7427. Go to end of the current variation.
  7428. .LP
  7429. .TP 8
  7430. b
  7431. Go to beginning of the game tree. 
  7432. .LP
  7433. .TP 8
  7434. }
  7435. Go forward like the "." command until a comment.
  7436. .LP
  7437. .TP 8
  7438. {
  7439. Go backwards like the "," command until a comment.
  7440. .LP
  7441. .TP 8
  7442. g
  7443. Go to a specified node.  Type in the desired node number.
  7444. .LP
  7445. .TP 8
  7446. Move forward until there is a variation branch in the game tree.
  7447. .LP
  7448. .TP 8
  7449. Move backwards until there is a variation branch in the game tree.
  7450. .LP
  7451. .TP 8
  7452. k and i 
  7453. Scroll the game tree variation window up and down.
  7454. A \- at the top of the variation window, and 
  7455. a + at the bottom indicate that more variations are available.
  7456. .LP
  7457. .TP 8
  7458. j and u 
  7459. Scroll comment window up and down.
  7460. A \- at the top of the comment, and 
  7461. a + at the bottom indicate that more comments are available.
  7462. .LP
  7463. .TP 8
  7464. Load new file.  Will prompt for confirmation if the current file has been
  7465. modified.
  7466. .LP
  7467. .TP 8
  7468. r
  7469. Load previous file.  (Reverse through the file list)
  7470. .LP
  7471. .TP 8
  7472. f
  7473. Load next file.  (Forward through the file list)
  7474. .LP
  7475. .TP 8
  7476. Write out Smart\-Go file.  Will prompt for a filename.  The special 
  7477. filename * will save with the current name (which appears in the upper 
  7478. right corner).  
  7479. .LP
  7480. .TP 8
  7481. space or 0 
  7482. Make a move.  The current player turn is indicated by the > < 
  7483. around the captured stones on the lower right.
  7484. Normally, this adds the move to the game tree and moves to a new node.
  7485. In tutor mode, it checks the various game continuations.  If one of them 
  7486. contains the move you made, it moves to that variation.  If not, it prints 
  7487. an error message.  The game tree cannot be modified in tutor mode.
  7488. .LP
  7489. .TP 8
  7490. Pass.  Enter a pass move.
  7491. .LP
  7492. .TP 8
  7493. o
  7494. Other player.  Changes whose turn it is, adding a token in the game tree to 
  7495. force the change whenever this node is visited.  If the player is forced by 
  7496. such a token, the current player turn is indicated by } { characters on the 
  7497. lower right.  
  7498. .LP
  7499. .TP 8
  7500. t
  7501. Toggle stone color.  Changes whose turn it is without adding any tokens in 
  7502. the game tree.  This will not work if the game tree has a PLayer token 
  7503. (generated by the o key) at the current node.
  7504. .LP 
  7505. .TP 8 
  7506. Set/unset black stones. 
  7507. .LP 
  7508. .TP 8 
  7509. Set/unset white stones. 
  7510. .LP 
  7511. .TP 8 
  7512. q or ESC.  
  7513. Quit.  q will 
  7514. prompt for confirmation.  ESC will not prompt for confirmation.  
  7515. .LP 
  7516. .TP 8 
  7517. Create a variation below the current node.  The variation will initially
  7518. contain a null node.  You must move to that variation to make a move in
  7519. it.  If the "v" command is invoked at a node which is at the end of a
  7520. variation, variation "A" is created with a null node.  Subsequent
  7521. invocations of the "v" command will create the "B", "C"... variations. 
  7522. .LP 
  7523. .TP 8 
  7524. Cut tree.  Moves the 
  7525. current node and everything below it to a temporary holding buffer.  (Moves 
  7526. your location back to the parent of the node you are one when you invoke it.) 
  7527. .LP 
  7528. .TP 8 
  7529. Paste tree.  Pastes the temporary holding buffer in after the 
  7530. current node.  Usually the  opposite of cutting the tree. 
  7531. .LP 
  7532. .TP 8 
  7533. Edit the 
  7534. current comment.  Use the emacs cursor keys ^P for up, ^N for down, ^F for 
  7535. right ^B for back, ^A to move to the beginning of the line, ^E to move to 
  7536. the end of the line, and ^D to delete a character, and ^K to delete to the 
  7537. end of the line.  Ctrl\-I will toggle between insert and overwrite modes.
  7538. Only a comment as large as the comment 
  7539. window may be edited.  Pressing c on a comment larger than the window will 
  7540. cause the extra to be lost.  Press Ctrl\-W or ESC to conclude comment 
  7541. editing and write the new comment into the game record in memory.
  7542. Press Ctrl\-O to exit comment editing and
  7543. keep the old comment, discarding any changes.
  7544. .LP 
  7545. .TP 8 
  7546. Delete node.  Deletes the current node, replacing it with its 
  7547. child.  If the current node has no child, then clear the properties of the 
  7548. current node. 
  7549. .LP 
  7550. .TP 8 
  7551. Name the current node.  You will be prompted for the 
  7552. name. 
  7553. .LP 
  7554. .TP 8 
  7555. Score the game.  After selecting this, move the cursor 
  7556. around and remove the dead groups with 0 or space.  You can undo one (and 
  7557. only one) kill with the u key.  Pressing return will 
  7558. score the game and print the (Japanese) score in the comment area.
  7559. If you missed some dead groups, continue removing them.  Press q when you 
  7560. wish to exit scoring mode.  You will be prompted to either keep the score 
  7561. information as a comment for the current node or restore the old comment.
  7562. .LP
  7563. .TP 8
  7564. Ctrl\-I
  7565. Enter info mode.  In this mode, the various informational properties of the 
  7566. current file are displayed and may be edited.  To edit an item, press the 
  7567. letter associated with it, and enter the new text.  This letter must be 
  7568. entered in upper case.  To see a list of letters, press ?.  
  7569. The comment window scrolling keys can be used to 
  7570. scroll the info display.  The supported info properties are:
  7571. Size,
  7572. Handicap,
  7573. playerBlack,
  7574. bLackrank,
  7575. playerWhite,
  7576. whIterank,
  7577. Gamename,
  7578. Event,
  7579. rouNd,
  7580. Date,
  7581. Place,
  7582. Time,
  7583. Result,
  7584. gameComment,
  7585. sOurce,
  7586. User,
  7587. Komi.  The capital letters in this list indicate which letter selects that 
  7588. info property.  
  7589. .LP
  7590. .TP 8
  7591. Ctrl\-T
  7592. Toggle tutor mode.  (See the section on space or 0 for explanation.)
  7593. .LP
  7594. .TP 8
  7595. Ctrl\-W
  7596. Toggle the format used for writing Smart\-Go files between long and short.  
  7597. .LP
  7598. .TP 8
  7599. Ctrl\-L 
  7600. Refresh the screen.
  7601. .LP
  7602. .TP 8
  7603. Ctrl\-F 
  7604. Save the current screen to a file.
  7605. .LP
  7606. .TP 8
  7607. Display a help screen.
  7608. .LP
  7609. .TP 8
  7610. 12346789 
  7611. Move the cursor around.  Assumes standard numeric keypad orientation.
  7612. .LP
  7613. .SH ENVIRONMENT SETTINGS
  7614. All of the characters used for the commands and the display are configurable 
  7615. via environment variables.  For the ascii interface, use:
  7616. .LP
  7617. .sp
  7618. .if n \{.nf
  7619. setenv MGT '_ASCCOM:q><.,eb}{][gwzxv\\!lm#^cdn
  7620.                     spotrfLWTFI012346789kiju&
  7621.             _ASCCHAR:@O:+\-.+|\-++++'
  7622.        (command should appear all on one line with a 
  7623.         single space separating _ASCCHAR from the
  7624.         previous string.)
  7625. .fi
  7626. \}
  7627. .if t \{.nf
  7628. setenv MGT '_ASCCOM:q><.,eb}{][gwzxv\\!lm#^cdnspotrfLWTFI012346789kiju&
  7629.             _ASCCHAR:@O=+\-.+|\-++++' 
  7630. .fi 
  7631. .in +.25i 
  7632. (command should appear all 
  7633. on one line with a single space separating _ASCCHAR from the previous string.) 
  7634. .in -.25i 
  7635. \} 
  7636. .LP 
  7637. to get the default characters.  (This is csh syntax.  For 
  7638. other shells, the syntax will be different.)  
  7639. Place this line in your .cshrc so the alternate characters are 
  7640. always in effect.  The _ASCCOM string allows you to change the keyboard 
  7641. commands.  Upper case letters stand for control characters. The _ASCCHAR 
  7642. string specifies the display characters.  For example, to use # for black 
  7643. stones, change the @ to # in the _ASCCHAR string.
  7644. You need only include one of the two declarations ("_ASCCOM:" or 
  7645. "_ASCCHAR:") if you only want to change the commands or characters
  7646. but not both.
  7647. To set the default display type to inverse video, use _ASCINV in the 
  7648. MGT environment variable.
  7649. If multiple contradictory specifications occur in the MGT
  7650. environment variable, the last that appear will be used by the program.
  7651. .LP
  7652. With the IBM version, the same effects may be achieved under DOS 4.0 with
  7653. a SET command placed in the AUTOEXEC.BAT file.  Under previous DOS 
  7654. versions, quotes were interpreted literally and "|", ">" and "<" characters
  7655. have special meanings and thus cannot be put into environment variables
  7656. with the SET command.
  7657. Under VMS, the command is just MGT = "_ASCCHAR:..."
  7658. .LP
  7659. .SH COMMENT FORMATTING
  7660. Comments are expected to consist of long lines, each of which is one 
  7661. paragraph.  A single long line will be formatted to fit the display. 
  7662. Line breaks will be ignored if they are preceeded by a space, but will be 
  7663. respected otherwise. 
  7664. .SH DISPLAYS
  7665. All displays have in common the purpose of displaying a go tree.
  7666. .LP
  7667. ASCII display:
  7668. .LP
  7669. .sp
  7670. .ft CW
  7671. .nf
  7672.     A B C D E F G H  S T
  7673.    +---------------  ---+   -Suppose this is the second
  7674.  19|. . . @ . . . .  . .|19| line of the comment.  Since
  7675.  18|. O O @ @ @ O .  . .|18| there is some more of the
  7676.  17|. @ @ O O O O .  . .|17| comment above us unseen, 
  7677.  16|. @ O + . . . .  . .|16| the - appears to the left
  7678.  15|. @ O . O . . .  . .|15| of 'Suppose'.
  7679.  14|. . @ O . . . .  . .|14|
  7680.  13|. . @ . . . . .  . .|13|
  7681.  12|. . . . . . . .  . .|12|
  7682.  11|. . . . . . . .  . .|11| And here, when there is
  7683.  10|. . . + . . . .  . .|10| more of the comment
  7684.   9|. . . . . . . .  . .| 9| below, the '+'
  7685.   8|. . . . . . . .  . .| 8|+appears to our left.
  7686.   7|. . . . . . . .  . .| 7|
  7687.   6|. . . . . . . .  . .| 6|   Node #173: Name
  7688.   5|. . . . . . . .  . .| 5|-B: variation 1 hit 'B' to see
  7689.   4|. . . + . . . .  . .| 4| C: variation 2 hit 'C'
  7690.   3|. . . . . . . .  . .| 3| D: variation 3 etc...            
  7691.   2|. . . . . . . .  . .| 2| E: variation 4
  7692.   1|. . . . . . . .  . .| 1|+F: variation 5
  7693.    +---------------  ---+    ? for help    read   long
  7694.     A B C D E F G H  S T     
  7695.  Black #11 at 'D19'               @: 0      > O: 0 <
  7696. .fi
  7697. .ft
  7698. .LP
  7699. The bottom line indicates that Black has just made move #11.  On the bottom 
  7700. right, the angle brackets around the white stone indicate that it is 
  7701. White's turn.  Above that, the word "read" indicates that the Smart\-Go file 
  7702. hasn't been modified, and "long" indicates that the default save format is 
  7703. the long format.  "Read" will change to "edit" if you modify the file, and 
  7704. it will say "tutor" if you enter tutor mode.
  7705. .SH FILES
  7706. The 
  7707. .B From My Go Teacher
  7708. tutorial lessons, and many professional game records all available at 
  7709. milton.u.washington.edu.
  7710. .LP
  7711. Internet go, a program to play go over internet, available on milton.
  7712. .LP 
  7713. Smart\-Go.def, the Smart\-Go format definition.
  7714. .sp
  7715. .SH BUGS
  7716. .LP
  7717. Comment editing is limited to one screen.
  7718. .LP
  7719. Only a subset of Smart-Go is supported.
  7720. .LP
  7721. Send further bug reports to "adrian@u.washington.edu"
  7722. or "hale@scam.Berkeley.EDU"
  7723. .fi
  7724. .sp
  7725. .SH AUTHORS
  7726. Greg Hale (hale@scam.berkeley.edu)
  7727. .LP
  7728. Jeff Boscole
  7729. .LP
  7730. Adrian Mariano (adrian@u.washington.edu)
  7731. .sp
  7732. .SH SEE ALSO
  7733. rn rec.games.go \- a newsgroup on the game
  7734. .br
  7735. Graded go problems for beginners, vol 1-4,
  7736. Ishi Press (Highly recommended)
  7737. .br
  7738. In the Beginning, 
  7739. Ishi Press.
  7740. .br
  7741. The Treasure Chest Enigma, 
  7742. Ishi Press.
  7743.  
  7744.  
  7745.  
  7746.  
  7747. SHAR_EOF
  7748. fi
  7749. if test -f 'Spec.io'
  7750. then
  7751.     echo shar: "will not over-write existing file 'Spec.io'"
  7752. else
  7753. cat << \SHAR_EOF > 'Spec.io'
  7754.                         INTERFACE SPECIFICATION FOR MGT
  7755.  
  7756. If you wish to add a new interface to mgt, these are the functions you need to 
  7757. come up with.
  7758.  
  7759. void open()
  7760.         Initialize interface.  Any *interface* specific initialization is done
  7761.         here.
  7762.  
  7763. void close()
  7764.         Leave the interface.
  7765.  
  7766. void refreshIO()
  7767.         update screen to look like memory image.  Somewhat curses specific.
  7768.         Probably will be a null function null(){} in most interfaces.
  7769.  
  7770. void plotPiece(pBoard b, int i, int j)
  7771.         Plots the piece contained in b at i,j on the real screen.
  7772.         Board is read by call boardGet(b, i, j) which returns
  7773.         one of P_NOTHING, P_BLACK, P_WHITE, P_DAME, P_BLACKTERR,
  7774.         or P_WHITETERR. 
  7775.  
  7776.  
  7777. void clearComment()
  7778.         Clears comment window
  7779.  
  7780. void initBoard()
  7781.         Draw a blank board of size 'boardsize'
  7782.  
  7783. void clearScreen()
  7784.         clears screen. 
  7785.  
  7786. int idle(nodep n) 
  7787.         Gets the next command.  Acts like an event driven loop.
  7788.         Waits for keystroke.  Returns a command casted to an int
  7789.         to indicate the command for doit.c to process.
  7790.  
  7791. void drawTree(nodep n)
  7792.         Show the variations that are available in the var list on 
  7793.         the right when starting at node n. (in Ascii version)
  7794.         Interface-local variables exists to handle scrolling.
  7795.         scrolling should be handled by the interface alone.
  7796.  
  7797. void highlightLast(int x, y, movenum, turn)
  7798.         Show last move number, current turn, whose move it is,
  7799.         and the prisoner count.
  7800.         turn==0 means Black just moved.
  7801.         If x and y are equal to PASSVAL then the move was a pass.
  7802.         Use these to get current player turn and prisoner count
  7803.         extern int prisoners[black=0,white=1] ;
  7804.         extern int curPlayer;
  7805.  
  7806. void readEnv(char **env)
  7807.         Check *env for environment string.  Increment it to point to 
  7808.         the first character not used.
  7809.  
  7810. void notifyMessage(char *s)
  7811.         Print single line message someplace.
  7812.  
  7813. void notifyClear()
  7814.         Clear notify message area
  7815.  
  7816. int queryStr(char *query, char *dst, int maxLen)
  7817.         Print query out.  Get at most maxLen chars into dst.
  7818.         Return length of the result.
  7819.  
  7820. void setCursor(int i, int j)
  7821.         Move cursor (pointer) to position i,j on go board
  7822.  
  7823. void plotMark(pBoard b,int i,int j) 
  7824.         Plot mark at position i,j on displayed board.
  7825.         DOES NOT modify *b.
  7826.         Mark is erased by call to plotPiece
  7827.  
  7828. void plotLetter(int i, int j, char c)
  7829.         Puts letter c on the screen at board position i,j
  7830.  
  7831. int getPoint()    
  7832.         Allow user to specify a board position (Cursor
  7833.         keys, mouse, etc) Used when scoring the game.
  7834.         Uses globals xcur and ycur to
  7835.         store the position.  The return value 
  7836.         can be C_QUIT to abort score.  C_SCORE to calculate
  7837.         the score.  C_REDRAW to redraw screen, or C_NOTHING
  7838.         to kill the group we're on right now.
  7839.  
  7840. void editComment(char *inp, char **out)
  7841.         Edit a comment.  inp contains the input comment to be
  7842.         edited.  THIS MUST BE free()'d.  out contains the return
  7843.         pointer.  It should be allocated to the appropriate size
  7844.         and the new edited comment should be placed in the
  7845.         allocated space.
  7846.  
  7847. int askYN(char *query, int defalt)
  7848.         Prompt user with query.  The query will NOT end in " (y/n)? " 
  7849.         If needed by the interface, this should be added here. 
  7850.         Returns 1 for yes, 0 for no.  defalt contains the default 
  7851.         response (1 for yes, 0 for no).
  7852.  
  7853. void notifyError(char *errormsg)
  7854.         Display error message.  Give user a chance to see it, and
  7855.         clear message.  
  7856.  
  7857. void displayInfo(char *s)
  7858.         Formats and displays string s as a list of game information.  Each
  7859.         informational item starts on its own line but may contain newlines.
  7860.  
  7861. Token getInfoToChange()
  7862.         Passes back an informational token to change, or t_EOF to escape
  7863.         from the info editor.  (Scrolling of the info region should be 
  7864.         handled internally here.)
  7865.  
  7866. void editInfo(char *input, char **output, property info_item)
  7867.     Edits the info item corresponding to info_item.  The current
  7868.         text is given in input which should be freed.  The replacement
  7869.         text should be put in *output which needs to be allocated by 
  7870.         this function.  (This works like the comment editor.)
  7871. SHAR_EOF
  7872. fi
  7873. if test -f 'Makefile.bc'
  7874. then
  7875.     echo shar: "will not over-write existing file 'Makefile.bc'"
  7876. else
  7877. cat << \SHAR_EOF > 'Makefile.bc'
  7878. # Makefile for Borland C++ 2.0
  7879. # Place your library directory below
  7880.  
  7881. LIB=c:\prog\c\lib
  7882. MDL=c
  7883.  
  7884. mgt.exe: ascii.obj build.obj comment.obj doit.obj edit.obj\
  7885.          parse.obj play.obj tree.obj mgt.obj help.obj mou.obj
  7886.     tlink /c /x $(LIB)\c0$(MDL) $(LIB)\wildargs ascii build comment doit \
  7887.           edit mgt parse play tree mou help ,mgt,mgt,\
  7888.           $(LIB)\c$(MDL) 
  7889.  
  7890. ascii.obj: asc_ibm.inc ascii.c
  7891.  
  7892. .c.obj: 
  7893.     bccx -m$(MDL) -w-pia -G -Z -O -c -DMGT_IBM $*.c
  7894.  
  7895.  
  7896.  
  7897. SHAR_EOF
  7898. fi
  7899. if test -f 'Build.com'
  7900. then
  7901.     echo shar: "will not over-write existing file 'Build.com'"
  7902. else
  7903. cat << \SHAR_EOF > 'Build.com'
  7904. $!
  7905. $!    BUILD.COM for VMS, by Eric Osman (osman@hannah.enet.dec.com)
  7906. $!
  7907. $!    This procedure checks all .C files in the current directory, and
  7908. $!    compiles any whose .OBJ file is older.  Then, all files are
  7909. $!    linked.
  7910. $!
  7911. $!    CAUTION:    .H files are not checked, so if you change one,
  7912. $!            you'll need to delete the .OBJ files of any .C
  7913. $!            files that depend on that .H file.  That will allow
  7914. $!            this BUILD.COM to recompile those .C files.
  7915. $!
  7916. $!    Usage:
  7917. $!
  7918. $!        @build [-Dname[=value]] [-g]
  7919. $!
  7920. $!    If -D is given, a corresponding /DEFINE is fed to the C compiler.
  7921. $!
  7922. $!    If -g is given, the linker is told to link a debug version.
  7923. $!
  7924. $!    Author:  Eric Osman   8-8-90
  7925. $!
  7926. $ on warning then exit
  7927. $ on control_y then goto hey_stop
  7928. $ cpl = "call do_cpl"
  7929.  
  7930.     !! Find macro definitions and link switches
  7931.  
  7932. $ n = 1
  7933. $ macros = ""
  7934. $ link_switches = ""
  7935. $ plup: if n .le. 8
  7936. $ then    next = p'n'
  7937. $    n = n + 1
  7938. $    qual = f$edit (f$extr(0,2,next),"upcase")
  7939. $    if qual .eqs. "-D"
  7940. $    then    definition = f$extr(2,f$len(next)-2,next)
  7941. $        macros = macros + "/define=""" + definition + """"
  7942. $    else if qual .eqs. "-G"
  7943. $    then    link_switches = link_switches + "/debug"
  7944. $    endif
  7945. $    endif
  7946. $    goto plup
  7947. $ endif
  7948.  
  7949.     !! Get all dates
  7950.  
  7951. $ write sys$output "[Getting list of sources and objects]"
  7952. $ dir/date/col=1/nohead/notrail/out=temp.txt *.c.0,*.obj.0/exclude=foo.*
  7953. $ write sys$output "[Examining dates]"
  7954. $ close/nolog b_chan
  7955. $ close/nolog link_chan
  7956. $ open b_chan temp.txt
  7957. $ open/write link_chan temp.opt
  7958. $ num = 0
  7959. $ slup:
  7960. $ read/end=nomore b_chan file_line
  7961. $ read/end=nomore b_chan date_line
  7962. $ type = f$parse (file_line,,,"type")
  7963. $ name = f$parse (file_line,,,"name")
  7964. $ if "''type'" .eqs. ".C"
  7965. $ then    src_'num' = "''name'"
  7966. $    num = num + 1
  7967. $    write link_chan name + ".obj"
  7968. $    date_tag = name + "_SRC_DATE"
  7969. $ else date_tag = name + "_OBJ_DATE"
  7970. $ endif
  7971. $ date = f$edit(date_line,"trim")
  7972. $ 'date_tag' = f$cvt(f$el(0," ",date) + ":" + f$el(1," ",date))
  7973. $ goto slup
  7974. $ nomore: close b_chan
  7975. $ close link_chan
  7976. $ n_srces = num
  7977. $ num = 0
  7978. $ dlup:
  7979. $ src_name = src_'num'
  7980. $ src_date = 'src_name'_src_date
  7981. $ if f$type ('src_name'_obj_date) .eqs. ""
  7982. $ then obj_date = ""
  7983. $ else obj_date = 'src_name'_obj_date
  7984. $ endif
  7985. $ cpl 'src_name' "''src_date'" "''obj_date'"
  7986. $ num = num + 1
  7987. $ if num .lt. n_srces then goto dlup
  7988. $ delete temp.txt.
  7989. $
  7990.     !! Link objects
  7991.  
  7992. $ app sys$input temp.opt
  7993. sys$share:vaxcrtl.exe/share
  7994. $ set verify
  7995. $ link /exe=mgt temp/opt 'link_switches'
  7996. $ delete temp.opt. ! 'f$ver(0)'
  7997. $ exit
  7998. $ hey_stop:
  7999. $ set noverify
  8000. $ exit
  8001.  
  8002. $ do_cpl:
  8003. $ subroutine
  8004. $ on warning then exit
  8005. $ src = p1 + ".c"
  8006. $ obj = p1 + ".obj"
  8007. $ if f$search (obj) .eqs. "" then goto cpl_it
  8008. $ if p2 .lts. p3
  8009. $ then
  8010. $    write sys$output "[''obj' already o.k.]"
  8011. $    exit
  8012. $ endif
  8013. $ cpl_it:
  8014. $ def/user sys sys$library:
  8015. $ set verify
  8016. $ cc 'src' 'macros'/include=(decw$include:,sys$library:)/deb/mach/obj=temp.obj
  8017. $ rename temp.obj 'obj' ! 'f$ver(0)'
  8018. $ exit
  8019. $ endsubroutine
  8020.  
  8021. SHAR_EOF
  8022. fi
  8023. if test -f 'mailgo'
  8024. then
  8025.     echo shar: "will not over-write existing file 'mailgo'"
  8026. else
  8027. cat << \SHAR_EOF > 'mailgo'
  8028. #!/bin/sh
  8029. #
  8030. #  mailgo 1.56    E-mail go game management program by Adrian Mariano
  8031. #     5/3/92      I place it on the public domain.  Please send improvements
  8032. #                 to me at adrian@u.washington.edu.
  8033. #  Syntax: mailgo [-r] filename
  8034. #          mailgo -n [filename]
  8035. #          mailgo -c 
  8036. #  Filename should contain a mailgo go game
  8037. #  
  8038. #  -r resends the file to the opponent
  8039. #  -n start a new game, using data in filename to get address
  8040. #  -c removes temporary files left when abnormally terminated
  8041. #
  8042. #  Invokes the game processor in the environment variable MAILGO, or attempts
  8043. #  to run mgt from the inherited path if MAILGO is not set.
  8044. #
  8045. #  System V Unix users should change the assignment to the MAILER variable
  8046. #  from 'mail' to 'mailx' or 'elm' or some other compatible mailer.
  8047. #
  8048.  
  8049. MAILER=mail
  8050.  
  8051.  
  8052. if [ $# -eq 0 ]
  8053. then
  8054.   echo ' '
  8055.   echo 'Syntax: mailgo [-r] filename'
  8056.   echo '        mailgo -n [filename]'
  8057.   echo '        mailgo -c '
  8058.   echo ' '
  8059.   echo 'Mailgo is a program to manage email go games.'
  8060.   echo 'Filename should contain a mailgo go game'
  8061.   echo '  '
  8062.   echo '  -r resends the file to the opponent'
  8063.   echo '  -n start a new game, using data in filename to get address'
  8064.   echo '  -c removes temporary files left when abnormally terminated'
  8065.   echo ' '
  8066.   exit
  8067. fi
  8068. case $1 in
  8069.   -c) if [ $# -ne 1 ]
  8070.        then
  8071.          echo Wrong number of parameters
  8072.          exit
  8073.        else
  8074.          rm -f MailGo* MailFile* MailOut*
  8075.          exit
  8076.        fi;;
  8077.   -r) if [ $# != 2 ]
  8078.        then
  8079.          echo Wrong number of parameters
  8080.          exit
  8081.        fi
  8082.        if grep "\---GoGaMeEnD---" $2 >/dev/null 2>&1
  8083.        then
  8084.          name=`sed -n '2,5s/TO: //p' $2`
  8085.          hisfile=`sed -n '2,5s/TOFILE: //p' $2`
  8086.          echo Remailing response to $name, $hisfile
  8087.          $MAILER -s "Remailed Go Game: $hisfile" $name < $2
  8088.          exit
  8089.        else
  8090.          echo Invalid input file $2
  8091.          exit
  8092.        fi;;
  8093.   -n) if [ $# -gt 2 ]
  8094.        then
  8095.          echo Wrong number of parameters
  8096.          exit
  8097.        fi
  8098.        if [ $# -eq 2 ]
  8099.        then
  8100.          if [ ! -s $2 ]
  8101.          then
  8102.            echo File $2 not found.
  8103.            exit
  8104.          fi
  8105.          opponent=`sed -n '2,5s/TO: //p' $2`
  8106.          echo Opponent address: $opponent
  8107.          hisfile=`sed -n '2,5s/TOFILE: //p' $2`
  8108.          echo His game file: $hisfile
  8109.          me=`sed -n '2,5s/FROM: //p' $2`
  8110.          echo Your address: $me
  8111.          myfile=`sed -n '2,5s/FROMFILE: //p' $2`
  8112.          echo Your game file: $myfile
  8113.        else
  8114.          echo -n "Opponent address: "
  8115.          read opponent
  8116.          echo -n "Opponent game filename: "
  8117.          read hisfile
  8118.          echo -n "Your address: "
  8119.          read me
  8120.          echo -n "Your game filename: "
  8121.          read myfile
  8122.        fi
  8123.        echo -n "Black player name: "
  8124.        read bpname
  8125.        echo -n "             rank: "
  8126.        read bprank
  8127.        echo -n "White player name: "
  8128.        read wpname
  8129.        echo -n "             rank: "
  8130.        read wprank
  8131.        echo -n "Handicap: "
  8132.        read handicap
  8133.        echo -n "Komi: "
  8134.        read komi
  8135.        echo -n "Game record format (Long/Short/Extrashort): "
  8136.        read format
  8137.        case $format in
  8138.          L | l) format='L' ;;
  8139.          E | e) format='E' ;;
  8140.          *)     format='S' ;;
  8141.        esac
  8142.        started=`date|awk '{print $3, $2, $6}'`
  8143.        if grep "W\[\]" $myfile >/dev/null 2>&1  
  8144.        then
  8145.          echo -n "File $myfile contains game possibly in progress.  Clobber (y/N)? "
  8146.          read res
  8147.          case $res in
  8148.            Y | y) ;;
  8149.            *)  echo -n "Your game filename: "
  8150.                read myfile;;
  8151.          esac
  8152.        fi
  8153.        cat <<END_END >$myfile
  8154. ---GoGaMeStArT---
  8155. FROM: $me
  8156. FROMFILE: $myfile
  8157. TO: $opponent
  8158. TOFILE: $hisfile
  8159. NEWGAME
  8160. FORMAT: $format
  8161. END_END
  8162.        cat <<END_END > MailGo$$
  8163. (
  8164. ;
  8165. GaMe[1]
  8166. VieW[]
  8167. SiZe[19]
  8168. Comment[ Black: $bpname, $bprank
  8169.  White: $wpname, $wprank
  8170.  Handicap: $handicap
  8171.  Komi: $komi
  8172.  Started: $started
  8173. ]
  8174. PlayerBlack[$bpname]
  8175. BlackRanking[$bprank]
  8176. PlayerWhite[$wpname]
  8177. WhiteRanking[$wprank]
  8178. KoMi[$komi]
  8179. DaTe[$started]
  8180. END_END
  8181.        case $handicap in
  8182.          2) echo "AB[dp][pd]" >> MailGo$$ ;;
  8183.          3) echo "AB[dp][pd][pp]" >> MailGo$$ ;;
  8184.          4) echo "AB[dd][dp][pd][pp]" >> MailGo$$ ;;
  8185.          5) echo "AB[dd][dp][jj][pd][pp]" >> MailGo$$ ;;
  8186.          6) echo "AB[dd][dj][dp][pd][pj][pp]" >> MailGo$$ ;;
  8187.          7) echo "AB[dd][dj][dp][jj][pd][pj][pp]" >> MailGo$$ ;;
  8188.          8) echo "AB[dd][dj][dp][jd][jp][pd][pj][pp]" >> MailGo$$ ;;
  8189.          9) echo "AB[dd][dj][dp][jd][jj][jp][pd][pj][pp]" >> MailGo$$ ;;
  8190.        esac
  8191.        if [ $handicap -ge 2 -a $handicap -le 9 ]
  8192.        then
  8193.            echo "PL[W]HA[$handicap]" >> MailGo$$ ;
  8194.        fi
  8195.        echo ")" >> MailGo$$
  8196.        case $format in
  8197.          L) sflag='';;
  8198.          *) sflag=-s;;
  8199.        esac
  8200.        if ${MAILGO-mgt} $sflag -m MailOut$$ MailGo$$
  8201.        then
  8202.          if [ -s MailOut$$ ]
  8203.          then
  8204.            cat MailOut$$ >>$myfile
  8205.          else
  8206.            cat MailGo$$ >>$myfile
  8207.          fi
  8208.        else
  8209.          echo -n "No move made, or mgt error. Send anyway (y/N)? "
  8210.          read res
  8211.          case $res in
  8212.            Y | y) cat MailGo$$ >>$myfile;;
  8213.            *) echo   NOT mailing new game.
  8214.               rm -f MailGo$$ MailOut$$
  8215.               exit;;
  8216.          esac
  8217.        fi
  8218.        rm -f MailOut$$ MailGo$$
  8219.        echo Mailing new game to $opponent, $hisfile
  8220.        echo >> $myfile
  8221.        echo "---GoGaMeEnD---" >> $myfile
  8222.        $MAILER -s "New Go Game: $hisfile" $opponent <$myfile
  8223.        exit
  8224.        ;;
  8225. esac
  8226. if [ $# -ne 1 ]
  8227. then
  8228.   echo Wrong number of parameters
  8229.   exit
  8230. fi
  8231. if [ ! -s $1 ]
  8232. then
  8233.   echo File $1 not found
  8234.   exit
  8235. fi
  8236. sed -n '/---GoGaMeStArT---/,/---GoGaMeEnD---/{s/---GoGaMe.*---//
  8237. p
  8238. }' $1 > MailGo$$
  8239. if [ ! -s MailGo$$ ]
  8240. then
  8241.   echo Invalid input file $1
  8242.   exit
  8243. fi
  8244. if sed -n 6,7p MailGo$$ | grep FORMAT > /dev/null 2>&1
  8245. then
  8246.   format=`sed -n '6,7s/FORMAT: //p' MailGo$$`
  8247.   if [ ! \( $format = 'L' -o $format = 'E' \) ] 
  8248.   then
  8249.     format='S'
  8250.   fi
  8251. else
  8252.   format='L'
  8253. fi
  8254. case $format in
  8255.   L) sflag='';;
  8256.   *) sflag='-s';;
  8257.  
  8258. #  E) sflag='-s';;
  8259. #  S) sflag='-s'
  8260. #     sed -n  -e 'H' -e '$g' -e '$s/\n;/;/g' -e '$s/^\n//' -e '$p' <MailGo$$ >MailGoX$$
  8261. #     mv -f MailGoX$$ MailGo$$ ;;
  8262.  
  8263. esac
  8264. if ${MAILGO-mgt} $sflag -m MailOut$$ MailGo$$
  8265. then
  8266.   echo >> MailOut$$
  8267.   echo ---GoGaMeStArT--- > MailFile$$
  8268.   sed -n '1,/(/s/FROM/TO/p' MailGo$$ >> MailFile$$
  8269.   sed -n '1,/(/s/TO/FROM/p' MailGo$$ >> MailFile$$
  8270.   echo FORMAT: $format >> MailFile$$
  8271.   if [ $format = 'S' ]
  8272.   then
  8273.     sed 's/\(;[BC]\[\)/\
  8274. \1/g' MailOut$$ >>MailFile$$
  8275.   else
  8276.     cat MailOut$$ >> MailFile$$
  8277.   fi
  8278.   echo "---GoGaMeEnD---" >> MailFile$$
  8279.   name=`sed -n '2,5s/FROM: //p' MailGo$$`
  8280.   fileout=`sed -n '2,5s/TOFILE: //p' MailGo$$`
  8281.   tofile=`sed -n '2,5s/FROMFILE: //p' MailGo$$`
  8282.   if sed -n 6p MailGo$$ | grep NEW > /dev/null 2>&1 && [ -s $fileout ]
  8283.   then
  8284.     echo -n "File $fileout exists.  Clobber (y/N)? "
  8285.     read res
  8286.     case $res in
  8287.       Y | y) rm -f $fileout ;;
  8288.       *) echo -n "Output filename: "
  8289.          read newfileout
  8290.          sed "2,5s/FROMFILE: $fileout/FROMFILE: $newfileout/" MailFile$$>Mfil$$
  8291.          mv Mfil$$ MailFile$$
  8292.          fileout=$newfileout ;;
  8293.     esac
  8294.   fi
  8295.   echo Mailing response to $name, $tofile
  8296.   $MAILER -s "Go Game: $tofile" $name < MailFile$$ 
  8297.   rm -f MailGo$$ MailOut$$ $1
  8298.   if grep "\---GoGaMeEnD---" $fileout > /dev/null 2>&1 || [ ! -s $fileout ]
  8299.   then
  8300.     mv MailFile$$ $fileout
  8301.   else
  8302.     echo Save file $fileout doesn\'t look like a mailgo file.  
  8303.     echo "Overwrite it anyway (y/N)?"
  8304.     read res
  8305.     case $res in
  8306.       y | Y) mv -f MailFile$$ $fileout;;
  8307.       *)     echo Game record left in MailFile$$;;
  8308.     esac
  8309.   fi
  8310. else
  8311.   echo No move made, or mgt error.  NOT mailing response.
  8312.   rm -f MailGo$$ MailOut$$
  8313. fi
  8314.  
  8315.  
  8316.  
  8317.  
  8318.  
  8319.  
  8320. SHAR_EOF
  8321. chmod +x 'mailgo'
  8322. fi
  8323. if test -f 'mailgo.6'
  8324. then
  8325.     echo shar: "will not over-write existing file 'mailgo.6'"
  8326. else
  8327. cat << \SHAR_EOF > 'mailgo.6'
  8328. .TH MAILGO 6  "5 April 1991"
  8329. .SH NAME
  8330. mailgo - shell script for using mgt to automate email go games
  8331. .SH SYNOPSIS
  8332. .B mailgo [\-r] [\-n] [\-c] [filename]
  8333. .SH DESCRIPTION
  8334. .B mailgo
  8335. helps manage email games by processing Smart-Go game records received by
  8336. mail, invoking mgt, and automatically sending your next move back.
  8337. .LP
  8338. Invoking 
  8339. .B mailgo 
  8340. with no flags instructs the program to search the specified file for a
  8341. go game, ignoring mail headers or other such garbage.  
  8342. .B mailgo 
  8343. will invoke the game processor specified in the environment variable
  8344. MAILGO or of this variable is undefined, will attempt to run 
  8345. .B mgt
  8346. from the inherited path.
  8347. .LP
  8348. If your opponent loses your move, you can resend the game with the \-r
  8349. switch.
  8350. .LP
  8351. To start a new game, use the \-n switch.  Without a file, you will be 
  8352. prompted for your address, your opponent's address, and the filename for
  8353. both your and your opponent's local game record.  The game processor will
  8354. then be invoked for you to make the first move.  If a filename is specified,
  8355. the address and filename data is taken from that file.
  8356. .LP
  8357. The \-c flag causes the program to delete any extraneous files it might have
  8358. created during a previous run which was abnormally terminated.
  8359. .SH FILE FORMAT
  8360. .LP
  8361. .sp
  8362. .if
  8363.  Leading garbage ignored
  8364.  
  8365.  ---GoGaMeStArT---
  8366.  TO: opponent@hissite
  8367.  TOFILE: his_game_record
  8368.  FROM: me@mysite
  8369.  FROMFILE: my_game_record
  8370.  FORMAT: format_code
  8371.  (
  8372.  Smart\-Go game data
  8373.  )
  8374.  ---GoGaMeEnD---
  8375.  
  8376.  Trailing garbage ignored
  8377. .fi
  8378. .LP
  8379. The game data file contains a leading tag to indicate the start of 
  8380. the data.  It contains both addresses, as should be used to mail the
  8381. game files, and it contains the files to store the games in.  In the
  8382. example above, you are playing opponent@hissite, and the game is being
  8383. stored in my_game_record.
  8384. .LP
  8385. The file format used can be either long, short, or extrashort indicated by L, 
  8386. S, and E respectively.  The long format uses the full size Smart-Go file 
  8387. saved with no options from mgt.  The extrashort format uses mgt with the \-s 
  8388. option to save short format files.  This format may cause problems for some
  8389. mailers, however, because the lines will grow longer than 512 bytes.
  8390. The short format is similar to the extrashort format but has extra newlines
  8391. inserted.  The short format is the default when selecting format from
  8392. the prompt, but the long format is the default if a file contains no FORMAT
  8393. line.
  8394. When 
  8395. .B mailgo
  8396. is used normally, the file specified on the command line is removed at
  8397. successful completion, and the new game is saved to the file specified in
  8398. the received game record.  If the destination file does not look like
  8399. a mailgo file, 
  8400. .B mailgo
  8401. will query for confirmation.
  8402. .SH FILES
  8403. mgt
  8404. .LP
  8405. Smart-Go.def, the Smart\-Go format definition.
  8406. .sp
  8407. .SH BUGS
  8408. .LP
  8409. If you attempt to start a new game, but are not the first player to make a 
  8410. real move, then you will have to convince mgt that you have changed the game 
  8411. record.  Do this by pressing z twice on a blank spot to set and remove a black 
  8412. stone.
  8413. .fi
  8414. .sp
  8415. .SH AUTHOR
  8416. Adrian Mariano (adrian@u.washington.edu)
  8417.  
  8418. SHAR_EOF
  8419. fi
  8420. if test -f 'mgtdoc.asc'
  8421. then
  8422.     echo shar: "will not over-write existing file 'mgtdoc.asc'"
  8423. else
  8424. cat << \SHAR_EOF > 'mgtdoc.asc'
  8425.  
  8426.  
  8427.  
  8428.    30 April 1992                                                       MGT(6)
  8429.  
  8430.  
  8431.  
  8432.    NAME
  8433.      mgt - game record display/editor for the oriental game of go
  8434.  
  8435.    SYNOPSIS
  8436.      mgt [-m filename] [-s] [-t] [files]
  8437.  
  8438.    DESCRIPTION
  8439.      Go is an ancient oriental strategy game based on the capturing of terri-
  8440.      tory.  The players alternate putting stones on the board, trying to sur-
  8441.      round as many empty intersections as possible.
  8442.  
  8443.      Mgt allows the user to examine Go game tree files created through the
  8444.      Macintosh(tm) programs Smart-Go (tm) or Go Explorer (tm). Mgt also has
  8445.      basic Go game tree editing capabilities and may be used to create or
  8446.      edit game tree files.  The on-line material provided by a rather exten-
  8447.      sive and growing database allows many hours of instructional enjoyment
  8448.      of various studies and tutorials concerning the game of Go.
  8449.  
  8450.      Mailgo is a utility which manages E-mail Go games using mgt as the Go
  8451.      board editor.  It is included in the mgt package.
  8452.  
  8453.      The mgt program was originally developed to be a companion for the
  8454.      series, "From My Go Teacher", archived at scam.berkeley.edu and
  8455.      milton.u.washington.edu for ftp.  Also available is the Internet GO
  8456.      Board communications program, 'go', also by Greg Hale, which connects up
  8457.      two terminals in real-time anywhere in the world.
  8458.  
  8459.    COMMAND LINE OPTIONS
  8460.  
  8461.      -m filename
  8462.              Invoke a set of options used by the mailgo program for managing
  8463.              email games.  If a filename is specified for loading (see
  8464.              below), the game record is loaded, and mgt automatically moves
  8465.              to the end of the main variation of the game record.  The game
  8466.              can be modified without confirmation.  If the game record has
  8467.              been modified, it will be automatically saved, on exit, to the
  8468.              filename specified after the -m and mgt will return success
  8469.              (zero).  If the game record has not been modified, or has not
  8470.              been allowed to be saved, then mgt will return failure
  8471.              (nonzero).
  8472.  
  8473.      -s      Change save format used to write save files.  The default save
  8474.              format is the long format Smart-Go file.  Using this option
  8475.              results in short format Smart-Go files.
  8476.  
  8477.      -t      Invoke tutor mode where you select variations by playing on the
  8478.              board.  The key for making a move has special behavior in this
  8479.              mode.  See the section on the "space or 0" keyboard command for
  8480.              a description.
  8481.  
  8482.      files   These are the files to be loaded.  The Unix and IBM version sup-
  8483.              port wildcards.  If no file is specified, mgt loads a blank
  8484.              board.  If you attempt to modify a file that was loaded, mgt
  8485.  
  8486.  
  8487.                                                                             1
  8488.  
  8489.  
  8490.  
  8491.  
  8492.  
  8493.  
  8494.    MGT(6)                                                       30 April 1992
  8495.  
  8496.  
  8497.              will prompt for confirmation the first time.
  8498.  
  8499.    OPERATION
  8500.      Mgt can be used to view and edit game records, or as an electronic game
  8501.      board for a two person game.  There are many keyboard commands which
  8502.      execute the various editing and display functions.
  8503.  
  8504.      >       Step down the game tree to the next move.  Stop at the end of a
  8505.              variation and do not visit other variations.
  8506.  
  8507.      <       Move back up the game tree.  (Previous move)
  8508.  
  8509.       .      Go to the next node using a tree traversal which will visit all
  8510.              nodes.  Sometimes the order of traversal can be confusing.
  8511.  
  8512.      ,       Go to the previous node -- the opposite of "." forward movement.
  8513.  
  8514.      e       Go to end of the current variation.
  8515.  
  8516.      b       Go to beginning of the game tree.
  8517.  
  8518.      }       Go forward like the "." command until a comment.
  8519.  
  8520.      {       Go backwards like the "," command until a comment.
  8521.  
  8522.      g       Go to a specified node.  Type in the desired node number.
  8523.  
  8524.      ]       Move forward until there is a variation branch in the game tree.
  8525.  
  8526.      [       Move backwards until there is a variation branch in the game
  8527.              tree.
  8528.  
  8529.      k and i Scroll the game tree variation window up and down.  A - at the
  8530.              top of the variation window, and a + at the bottom indicate that
  8531.              more variations are available.
  8532.  
  8533.      j and u Scroll comment window up and down.  A - at the top of the com-
  8534.              ment, and a + at the bottom indicate that more comments are
  8535.              available.
  8536.  
  8537.      #       Load new file.  Will prompt for confirmation if the current file
  8538.              has been modified.
  8539.  
  8540.      r       Load previous file.  (Reverse through the file list)
  8541.  
  8542.      f       Load next file.  (Forward through the file list)
  8543.  
  8544.      w       Write out Smart-Go file.  Will prompt for a filename.  The spe-
  8545.              cial filename * will save with the current name (which appears
  8546.              in the upper right corner).
  8547.  
  8548.      space or 0
  8549.              Make a move.  The current player turn is indicated by the > <
  8550.              around the captured stones on the lower right.  Normally, this
  8551.  
  8552.  
  8553.    2
  8554.  
  8555.  
  8556.  
  8557.  
  8558.  
  8559.  
  8560.    30 April 1992                                                       MGT(6)
  8561.  
  8562.  
  8563.              adds the move to the game tree and moves to a new node.  In
  8564.              tutor mode, it checks the various game continuations.  If one of
  8565.              them contains the move you made, it moves to that variation.  If
  8566.              not, it prints an error message.  The game tree cannot be modi-
  8567.              fied in tutor mode.
  8568.  
  8569.      p       Pass.  Enter a pass move.
  8570.  
  8571.      o       Other player.  Changes whose turn it is, adding a token in the
  8572.              game tree to force the change whenever this node is visited.  If
  8573.              the player is forced by such a token, the current player turn is
  8574.              indicated by } { characters on the lower right.
  8575.  
  8576.      t       Toggle stone color.  Changes whose turn it is without adding any
  8577.              tokens in the game tree.  This will not work if the game tree
  8578.              has a PLayer token (generated by the o key) at the current node.
  8579.  
  8580.      z       Set/unset black stones.
  8581.  
  8582.      x       Set/unset white stones.
  8583.  
  8584.      q or ESC.
  8585.              Quit.  q will prompt for confirmation.  ESC will not prompt for
  8586.              confirmation.
  8587.  
  8588.      v       Create a variation below the current node.  The variation will
  8589.              initially contain a null node.  You must move to that variation
  8590.              to make a move in it.  If the "v" command is invoked at a node
  8591.              which is at the end of a variation, variation "A" is created
  8592.              with a null node.  Subsequent invocations of the "v" command
  8593.              will create the "B", "C"... variations.
  8594.  
  8595.      !       Cut tree.  Moves the current node and everything below it to a
  8596.              temporary holding buffer.  (Moves your location back to the
  8597.              parent of the node you are one when you invoke it.)
  8598.  
  8599.      ^       Paste tree.  Pastes the temporary holding buffer in after the
  8600.              current node.  Usually the  opposite of cutting the tree.
  8601.  
  8602.      c       Edit the current comment.  Use the emacs cursor keys ^P for up,
  8603.              ^N for down, ^F for right ^B for back, ^A to move to the begin-
  8604.              ning of the line, ^E to move to the end of the line, and ^D to
  8605.              delete a character, and ^K to delete to the end of the line.
  8606.              Ctrl-I will toggle between insert and overwrite modes.  Only a
  8607.              comment as large as the comment window may be edited.  Pressing
  8608.              c on a comment larger than the window will cause the extra to be
  8609.              lost.  Press Ctrl-W or ESC to conclude comment editing and write
  8610.              the new comment into the game record in memory.  Press Ctrl-O to
  8611.              exit comment editing and keep the old comment, discarding any
  8612.              changes.
  8613.  
  8614.      d       Delete node.  Deletes the current node, replacing it with its
  8615.              child.  If the current node has no child, then clear the proper-
  8616.              ties of the current node.
  8617.  
  8618.  
  8619.                                                                             3
  8620.  
  8621.  
  8622.  
  8623.  
  8624.  
  8625.  
  8626.    MGT(6)                                                       30 April 1992
  8627.  
  8628.  
  8629.      n       Name the current node.  You will be prompted for the name.
  8630.  
  8631.      s       Score the game.  After selecting this, move the cursor around
  8632.              and remove the dead groups with 0 or space.  You can undo one
  8633.              (and only one) kill with the u key.  Pressing return will score
  8634.              the game and print the (Japanese) score in the comment area.  If
  8635.              you missed some dead groups, continue removing them.  Press q
  8636.              when you wish to exit scoring mode.  You will be prompted to
  8637.              either keep the score information as a comment for the current
  8638.              node or restore the old comment.
  8639.  
  8640.      Ctrl-I  Enter info mode.  In this mode, the various informational pro-
  8641.              perties of the current file are displayed and may be edited.  To
  8642.              edit an item, press the letter associated with it, and enter the
  8643.              new text.  This letter must be entered in upper case.  To see a
  8644.              list of letters, press ?. The comment window scrolling keys can
  8645.              be used to scroll the info display.  The supported info proper-
  8646.              ties are: Size, Handicap, playerBlack, bLackrank, playerWhite,
  8647.              whIterank, Gamename, Event, rouNd, Date, Place, Time, Result,
  8648.              gameComment, sOurce, User, Komi.  The capital letters in this
  8649.              list indicate which letter selects that info property.
  8650.  
  8651.      Ctrl-T  Toggle tutor mode.  (See the section on space or 0 for explana-
  8652.              tion.)
  8653.  
  8654.      Ctrl-W  Toggle the format used for writing Smart-Go files between long
  8655.              and short.
  8656.  
  8657.      Ctrl-L  Refresh the screen.
  8658.  
  8659.      Ctrl-F  Save the current screen to a file.
  8660.  
  8661.      ?       Display a help screen.
  8662.  
  8663.      12346789
  8664.              Move the cursor around.  Assumes standard numeric keypad orien-
  8665.              tation.
  8666.  
  8667.    ENVIRONMENT SETTINGS
  8668.      All of the characters used for the commands and the display are confi-
  8669.      gurable via environment variables.  For the ascii interface, use:
  8670.  
  8671.      setenv MGT '_ASCCOM:q><.,eb}{][gwzxv\!lm#^cdn
  8672.                          spotrfLWTFI012346789kiju&
  8673.                  _ASCCHAR:@O:+-.+|-++++'
  8674.             (command should appear all on one line with a
  8675.              single space separating _ASCCHAR from the
  8676.              previous string.)
  8677.  
  8678.  
  8679.      to get the default characters.  (This is csh syntax.  For other shells,
  8680.      the syntax will be different.) Place this line in your .cshrc so the
  8681.      alternate characters are always in effect.  The _ASCCOM string allows
  8682.      you to change the keyboard commands.  Upper case letters stand for
  8683.  
  8684.  
  8685.    4
  8686.  
  8687.  
  8688.  
  8689.  
  8690.  
  8691.  
  8692.    30 April 1992                                                       MGT(6)
  8693.  
  8694.  
  8695.      control characters. The _ASCCHAR string specifies the display charac-
  8696.      ters.  For example, to use # for black stones, change the @ to # in the
  8697.      _ASCCHAR string.  You need only include one of the two declarations
  8698.      ("_ASCCOM:" or "_ASCCHAR:") if you only want to change the commands or
  8699.      characters but not both.  To set the default display type to inverse
  8700.      video, use _ASCINV in the MGT environment variable.  If multiple con-
  8701.      tradictory specifications occur in the MGT environment variable, the
  8702.      last that appear will be used by the program.
  8703.  
  8704.      With the IBM version, the same effects may be achieved under DOS 4.0
  8705.      with a SET command placed in the AUTOEXEC.BAT file.  Under previous DOS
  8706.      versions, quotes were interpreted literally and "|", ">" and "<" charac-
  8707.      ters have special meanings and thus cannot be put into environment vari-
  8708.      ables with the SET command.  Under VMS, the command is just MGT =
  8709.      "_ASCCHAR:..."
  8710.  
  8711.    COMMENT FORMATTING
  8712.      Comments are expected to consist of long lines, each of which is one
  8713.      paragraph.  A single long line will be formatted to fit the display.
  8714.      Line breaks will be ignored if they are preceeded by a space, but will
  8715.      be respected otherwise.
  8716.  
  8717.    DISPLAYS
  8718.      All displays have in common the purpose of displaying a go tree.
  8719.  
  8720.      ASCII display:
  8721.  
  8722.          A B C D E F G H  S T
  8723.         +---------------  ---+   -Suppose this is the second
  8724.       19|. . . @ . . . .  . .|19| line of the comment.  Since
  8725.       18|. O O @ @ @ O .  . .|18| there is some more of the
  8726.       17|. @ @ O O O O .  . .|17| comment above us unseen,
  8727.       16|. @ O + . . . .  . .|16| the - appears to the left
  8728.       15|. @ O . O . . .  . .|15| of 'Suppose'.
  8729.       14|. . @ O . . . .  . .|14|
  8730.       13|. . @ . . . . .  . .|13|
  8731.       12|. . . . . . . .  . .|12|
  8732.       11|. . . . . . . .  . .|11| And here, when there is
  8733.       10|. . . + . . . .  . .|10| more of the comment
  8734.        9|. . . . . . . .  . .| 9| below, the '+'
  8735.        8|. . . . . . . .  . .| 8|+appears to our left.
  8736.        7|. . . . . . . .  . .| 7|
  8737.        6|. . . . . . . .  . .| 6|   Node #173: Name
  8738.        5|. . . . . . . .  . .| 5|-B: variation 1 hit 'B' to see
  8739.        4|. . . + . . . .  . .| 4| C: variation 2 hit 'C'
  8740.        3|. . . . . . . .  . .| 3| D: variation 3 etc...
  8741.        2|. . . . . . . .  . .| 2| E: variation 4
  8742.        1|. . . . . . . .  . .| 1|+F: variation 5
  8743.         +---------------  ---+    ? for help    read   long
  8744.          A B C D E F G H  S T
  8745.       Black #11 at 'D19'               @: 0      > O: 0 <
  8746.  
  8747.      The bottom line indicates that Black has just made move #11.  On the
  8748.      bottom right, the angle brackets around the white stone indicate that it
  8749.  
  8750.  
  8751.                                                                             5
  8752.  
  8753.  
  8754.  
  8755.  
  8756.  
  8757.  
  8758.    MGT(6)                                                       30 April 1992
  8759.  
  8760.  
  8761.      is White's turn.  Above that, the word "read" indicates that the
  8762.      Smart-Go file hasn't been modified, and "long" indicates that the
  8763.      default save format is the long format.  "Read" will change to "edit" if
  8764.      you modify the file, and it will say "tutor" if you enter tutor mode.
  8765.  
  8766.    FILES
  8767.      The From My Go Teacher tutorial lessons, and many professional game
  8768.      records all available at milton.u.washington.edu.
  8769.  
  8770.      Internet go, a program to play go over internet, available on milton.
  8771.  
  8772.      Smart-Go.def, the Smart-Go format definition.
  8773.  
  8774.  
  8775.    BUGS
  8776.  
  8777.      Comment editing is limited to one screen.
  8778.  
  8779.      Only a subset of Smart-Go is supported.
  8780.  
  8781.      Send further bug reports to "adrian@u.washington.edu" or
  8782.      "hale@scam.Berkeley.EDU"
  8783.  
  8784.  
  8785.    AUTHORS
  8786.      Greg Hale (hale@scam.berkeley.edu)
  8787.  
  8788.      Jeff Boscole
  8789.  
  8790.      Adrian Mariano (adrian@u.washington.edu)
  8791.  
  8792.  
  8793.    SEE ALSO
  8794.      rn rec.games.go - a newsgroup on the game
  8795.      Graded go problems for beginners, vol 1-4, Ishi Press (Highly recom-
  8796.      mended)
  8797.      In the Beginning, Ishi Press.
  8798.      The Treasure Chest Enigma, Ishi Press.
  8799.  
  8800.  
  8801.  
  8802.  
  8803.  
  8804.  
  8805.  
  8806.  
  8807.  
  8808.  
  8809.  
  8810.  
  8811.  
  8812.  
  8813.  
  8814.  
  8815.  
  8816.  
  8817.    6
  8818.  
  8819.  
  8820.  
  8821. SHAR_EOF
  8822. fi
  8823. if test -f 'Sample.01'
  8824. then
  8825.     echo shar: "will not over-write existing file 'Sample.01'"
  8826. else
  8827. cat << \SHAR_EOF > 'Sample.01'
  8828. (
  8829. ;
  8830. GaMe[1]
  8831. VieW[]
  8832. SiZe[19]
  8833. Comment[A game between two amateurs both ranked betwen 10 kyu and 15 kyu
  8834.     
  8835.  
  8836. Result:  with no komi, black wins by 4]
  8837. ;
  8838. Black[pd]
  8839. ;
  8840. White[qp]
  8841. ;
  8842. Black[dp]
  8843. ;
  8844. White[dc]
  8845. ;
  8846. Black[op]
  8847. ;
  8848. White[po]
  8849. ;
  8850. Black[lp]
  8851. ;
  8852. White[pl]
  8853. ;
  8854. Black[de]
  8855. ;
  8856. White[cd]
  8857. ;
  8858. Black[ed]
  8859. ;
  8860. White[ce]
  8861. ;
  8862. Black[cf]
  8863. ;
  8864. White[ec]
  8865. ;
  8866. Black[ci]
  8867. ;
  8868. White[fd]
  8869. ;
  8870. Black[fe]
  8871. ;
  8872. White[gd]
  8873. ;
  8874. Black[ph]
  8875. ;
  8876. White[qi]
  8877. ;
  8878. Black[nc]
  8879. ;
  8880. White[cn]
  8881. ;
  8882. Black[dn]
  8883. ;
  8884. White[cp]
  8885. ;
  8886. Black[co]
  8887. ;
  8888. White[bo]
  8889. ;
  8890. Black[do]
  8891. ;
  8892. White[dq]
  8893. ;
  8894. Black[bp]
  8895. ;
  8896. White[bq]
  8897. ;
  8898. Black[ap]
  8899. ;
  8900. White[cq]
  8901. ;
  8902. Black[bn]
  8903. ;
  8904. White[ep]
  8905. ;
  8906. Black[eo]
  8907. ;
  8908. White[fq]
  8909. ;
  8910. Black[fp]
  8911. ;
  8912. White[eq]
  8913. ;
  8914. Black[gp]
  8915. ;
  8916. White[gq]
  8917. ;
  8918. Black[hq]
  8919. ;
  8920. White[hp]
  8921. ;
  8922. Black[ho]
  8923. ;
  8924. White[iq]
  8925. ;
  8926. Black[ip]
  8927. ;
  8928. White[hr]
  8929. ;
  8930. Black[jq]
  8931. ;
  8932. White[ir]
  8933. ;
  8934. Black[jr]
  8935. ;
  8936. White[go]
  8937. ;
  8938. Black[gn]
  8939. ;
  8940. White[io]
  8941. ;
  8942. Black[hn]
  8943. ;
  8944. White[hp]
  8945. ;
  8946. Black[fo]
  8947. ;
  8948. White[jp]
  8949. ;
  8950. Black[kq]
  8951. ;
  8952. White[jn]
  8953. ;
  8954. Black[kd]
  8955. ;
  8956. White[jc]
  8957. ;
  8958. Black[kc]
  8959. ;
  8960. White[jd]
  8961. ;
  8962. Black[lg]
  8963. ;
  8964. White[ke]
  8965. ;
  8966. Black[le]
  8967. ;
  8968. White[kf]
  8969. ;
  8970. Black[lf]
  8971. ;
  8972. White[if]
  8973. ;
  8974. Black[gg]
  8975. ;
  8976. White[ge]
  8977. ;
  8978. Black[ff]
  8979. ;
  8980. White[jh]
  8981. ;
  8982. Black[hj]
  8983. ;
  8984. White[jk]
  8985. ;
  8986. Black[mk]
  8987. ;
  8988. White[pq]
  8989. ;
  8990. Black[oq]
  8991. ;
  8992. White[qh]
  8993. ;
  8994. Black[qg]
  8995. ;
  8996. White[pi]
  8997. ;
  8998. Black[oh]
  8999. ;
  9000. White[oi]
  9001. ;
  9002. Black[ni]
  9003. ;
  9004. White[nh]
  9005. ;
  9006. Black[ng]
  9007. ;
  9008. White[nj]
  9009. ;
  9010. Black[mh]
  9011. ;
  9012. White[mj]
  9013. ;
  9014. Black[lm]
  9015. ;
  9016. White[kp]
  9017. ;
  9018. Black[lo]
  9019. ;
  9020. White[lq]
  9021. ;
  9022. Black[lr]
  9023. ;
  9024. White[js]
  9025. ;
  9026. Black[mq]
  9027. ;
  9028. White[oo]
  9029. ;
  9030. Black[no]
  9031. ;
  9032. White[nn]
  9033. ;
  9034. Black[nm]
  9035. ;
  9036. White[mn]
  9037. ;
  9038. Black[lj]
  9039. ;
  9040. White[mi]
  9041. ;
  9042. Black[li]
  9043. ;
  9044. White[mo]
  9045. ;
  9046. Black[np]
  9047. ;
  9048. White[nk]
  9049. ;
  9050. Black[ml]
  9051. ;
  9052. White[nl]
  9053. ;
  9054. Black[mm]
  9055. ;
  9056. White[om]
  9057. ;
  9058. Black[il]
  9059. ;
  9060. White[hh]
  9061. ;
  9062. Black[gh]
  9063. ;
  9064. White[gf]
  9065. ;
  9066. Black[kg]
  9067. ;
  9068. White[jg]
  9069. ;
  9070. Black[ii]
  9071. ;
  9072. White[bf]
  9073. ;
  9074. Black[df]
  9075. ;
  9076. White[cg]
  9077. ;
  9078. Black[dg]
  9079. ;
  9080. White[bh]
  9081. ;
  9082. Black[ch]
  9083. ;
  9084. White[bg]
  9085. ;
  9086. Black[bi]
  9087. ;
  9088. White[gi]
  9089. ;
  9090. Black[hi]
  9091. ;
  9092. White[dd]
  9093. ;
  9094. Black[ee]
  9095. ;
  9096. White[hg]
  9097. ;
  9098. Black[fg]
  9099. ;
  9100. White[ji]
  9101. ;
  9102. Black[gj]
  9103. ;
  9104. White[nh]
  9105. ;
  9106. Black[pg]
  9107. ;
  9108. White[aq]
  9109. ;
  9110. Black[ao]
  9111. ;
  9112. White[jl]
  9113. ;
  9114. Black[kl]
  9115. ;
  9116. White[im]
  9117. ;
  9118. Black[hl]
  9119. ;
  9120. White[ln]
  9121. ;
  9122. Black[pr]
  9123. ;
  9124. White[qr]
  9125. ;
  9126. Black[ps]
  9127. ;
  9128. White[qs]
  9129. ;
  9130. Black[or]
  9131. ;
  9132. White[km]
  9133. ;
  9134. Black[ko]
  9135. ;
  9136. White[lk]
  9137. ;
  9138. Black[kk]
  9139. ;
  9140. White[ll]
  9141. ;
  9142. Black[kj]
  9143. ;
  9144. White[jj]
  9145. ;
  9146. Black[jo]
  9147. ;
  9148. White[rg]
  9149. ;
  9150. Black[rf]
  9151. ;
  9152. White[rh]
  9153. ;
  9154. Black[ip]
  9155. ;
  9156. White[hq]
  9157. ;
  9158. Black[in]
  9159. ;
  9160. White[kn]
  9161. ;
  9162. Black[hm]
  9163. ;
  9164. White[kb]
  9165. ;
  9166. Black[lb]
  9167. ;
  9168. White[ka]
  9169. ;
  9170. Black[la]
  9171. ;
  9172. White[jb]
  9173. ;
  9174. Black[lc]
  9175. ;
  9176. White[ih]
  9177. ;
  9178. Black[ah]
  9179. ;
  9180. White[ag]
  9181. ;
  9182. Black[ai]
  9183. ;
  9184. White[be]
  9185. ;
  9186. Black[sg]
  9187. ;
  9188. White[sh]
  9189. ;
  9190. Black[ks]
  9191. ;
  9192. White[is]
  9193. ;
  9194. Black[ik]
  9195. ;
  9196. White[kh]
  9197. ;
  9198. Black[lh]
  9199. ;
  9200. White[jm]
  9201. ;
  9202. Black[sf]
  9203. ;
  9204. White[ni]
  9205. ;
  9206. Black[pp]
  9207. ;
  9208. White[qq]
  9209. )
  9210.  
  9211. SHAR_EOF
  9212. fi
  9213. if test -f 'Sample.02'
  9214. then
  9215.     echo shar: "will not over-write existing file 'Sample.02'"
  9216. else
  9217. cat << \SHAR_EOF > 'Sample.02'
  9218. (
  9219. ;
  9220. GaMe[1]
  9221. SiZe[19]
  9222. VieW[]
  9223. Comment[16th Honinbo League Playoff
  9224.     
  9225. White: Sakata Eio 9-dan    
  9226.     
  9227. Black: Kitani Minoru 9-dan
  9228.     
  9229. Komi: 4 1/2    
  9230.  
  9231. Result: White wins by 3 1/2 points]
  9232. Black[qd]
  9233. ;
  9234. White[dc]
  9235. ;
  9236. Black[pq]
  9237. ;
  9238. White[cq]
  9239. ;
  9240. Black[oc]
  9241. ;
  9242. White[po]
  9243. ;
  9244. Black[qo]
  9245. ;
  9246. White[qn]
  9247. ;
  9248. Black[qp]
  9249. ;
  9250. White[pm]
  9251. ;
  9252. Black[nq]
  9253. ;
  9254. White[qi]
  9255. ;
  9256. Black[ce]
  9257. ;
  9258. White[dh]
  9259. ;
  9260. Black[ee]
  9261. ;
  9262. White[cb]
  9263. ;
  9264. Black[cc]
  9265. ;
  9266. White[gc]
  9267. ;
  9268. Black[bc]
  9269. ;
  9270. White[bb]
  9271. ;
  9272. Black[qg]
  9273. ;
  9274. White[dd]
  9275. ;
  9276. Black[de]
  9277. ;
  9278. White[cg]
  9279. ;
  9280. Black[co]
  9281. ;
  9282. White[cm]
  9283. ;
  9284. Black[ep]
  9285. ;
  9286. White[do]
  9287. ;
  9288. Black[dp]
  9289. ;
  9290. White[cp]
  9291. ;
  9292. Black[dn]
  9293. ;
  9294. White[bo]
  9295. ;
  9296. Black[eo]
  9297. ;
  9298. White[cn]
  9299. ;
  9300. Black[el]
  9301. ;
  9302. White[dk]
  9303. ;
  9304. Black[ql]
  9305. ;
  9306. White[rm]
  9307. ;
  9308. Black[rj]
  9309. ;
  9310. White[qe]
  9311. Comment[Complications start. Creating two weak groups. ]
  9312. ;
  9313. Black[qj]
  9314. ;
  9315. White[rd]
  9316. ;
  9317. Black[qc]
  9318. ;
  9319. White[qf]
  9320. ;
  9321. Black[pg]
  9322. ;
  9323. White[rc]
  9324. ;
  9325. Black[rb]
  9326. ;
  9327. White[oe]
  9328. ;
  9329. Black[mc]
  9330. ;
  9331. White[op]
  9332. ;
  9333. Black[on]
  9334. ;
  9335. White[pn]
  9336. ;
  9337. Black[oq]
  9338. ;
  9339. White[mo]
  9340. ;
  9341. Black[mp]
  9342. Comment[Severe attack. ]
  9343. ;
  9344. White[lo]
  9345. Comment[Counters aggressively. ]
  9346. ;
  9347. Black[no]
  9348. ;
  9349. White[np]
  9350. ;
  9351. Black[nm]
  9352. Comment[Black cuts. Brings on crisis.]
  9353. ;
  9354. White[pj]
  9355. ;
  9356. Black[pi]
  9357. ;
  9358. White[pk]
  9359. ;
  9360. Black[rl]
  9361. ;
  9362. White[ml]
  9363. ;
  9364. Black[nl]
  9365. ;
  9366. White[nk]
  9367. ;
  9368. Black[mk]
  9369. ;
  9370. White[om]
  9371. Comment[Exquisite shinogi tesuji. Lets W secure his endangered group]
  9372. ;
  9373. Black[nj]
  9374. ;
  9375. White[ok]
  9376. ;
  9377. Black[ll]
  9378. ;
  9379. White[lp]
  9380. ;
  9381. Black[mq]
  9382. ;
  9383. White[mn]
  9384. ;
  9385. Black[mm]
  9386. ;
  9387. White[nn]
  9388. ;
  9389. Black[rf]
  9390. Comment[Turns toward other weak group. ]
  9391. ;
  9392. White[re]
  9393. ;
  9394. Black[rg]
  9395. ;
  9396. White[nd]
  9397. ;
  9398. Black[nc]
  9399. ;
  9400. White[nf]
  9401. ;
  9402. Black[nh]
  9403. ;
  9404. White[lf]
  9405. ;
  9406. Black[le]
  9407. ;
  9408. White[mh]
  9409. ;
  9410. Black[mi]
  9411. ;
  9412. White[me]
  9413. ;
  9414. Black[mg]
  9415. ;
  9416. White[ld]
  9417. ;
  9418. Black[ke]
  9419. ;
  9420. White[md]
  9421. ;
  9422. Black[kb]
  9423. ;
  9424. White[kc]
  9425. ;
  9426. Black[jb]
  9427. ;
  9428. White[id]
  9429. ;
  9430. Black[kf]
  9431. ;
  9432. White[oi]
  9433. ;
  9434. Black[ph]
  9435. ;
  9436. White[jc]
  9437. Comment[Manages to rescue weak group. ]
  9438. ;
  9439. Black[ib]
  9440. ;
  9441. White[fd]
  9442. ;
  9443. Black[eg]
  9444. ;
  9445. White[lg]
  9446. Comment[Double attack.]
  9447. ;
  9448. Black[lh]
  9449. ;
  9450. White[kg]
  9451. ;
  9452. Black[if]
  9453. ;
  9454. White[hg]
  9455. ;
  9456. Black[hf]
  9457. ;
  9458. White[gf]
  9459. ;
  9460. Black[ge]
  9461. ;
  9462. White[fe]
  9463. ;
  9464. Black[jg]
  9465. ;
  9466. White[he]
  9467. Comment[First time that B is the one under pressure.]
  9468. ;
  9469. Black[gg]
  9470. ;
  9471. White[ff]
  9472. ;
  9473. Black[dg]
  9474. ;
  9475. White[ef]
  9476. ;
  9477. Black[df]
  9478. ;
  9479. White[fg]
  9480. ;
  9481. Black[ch]
  9482. ;
  9483. White[bh]
  9484. ;
  9485. Black[ci]
  9486. ;
  9487. White[bf]
  9488. ;
  9489. Black[ei]
  9490. ;
  9491. White[cj]
  9492. ;
  9493. Black[gh]
  9494. ;
  9495. White[fh]
  9496. ;
  9497. Black[eh]
  9498. ;
  9499. White[dj]
  9500. ;
  9501. Black[di]
  9502. ;
  9503. White[bi]
  9504. ;
  9505. Black[fi]
  9506. ;
  9507. White[gi]
  9508. ;
  9509. Black[gj]
  9510. ;
  9511. White[hh]
  9512. ;
  9513. Black[ii]
  9514. ;
  9515. White[mf]
  9516. ;
  9517. Black[jh]
  9518. Comment[Fight ends. ]
  9519. ;
  9520. White[er]
  9521. Comment[W has taken the lead.]
  9522. ;
  9523. Black[fk]
  9524. ;
  9525. White[ro]
  9526. ;
  9527. Black[rp]
  9528. ;
  9529. White[fq]
  9530. ;
  9531. Black[in]
  9532. ;
  9533. White[go]
  9534. ;
  9535. Black[gn]
  9536. ;
  9537. White[jn]
  9538. ;
  9539. Black[jm]
  9540. ;
  9541. White[fn]
  9542. ;
  9543. Black[hn]
  9544. ;
  9545. White[fo]
  9546. ;
  9547. Black[en]
  9548. ;
  9549. White[fm]
  9550. ;
  9551. Black[dl]
  9552. ;
  9553. White[cl]
  9554. ;
  9555. Black[hl]
  9556. ;
  9557. White[km]
  9558. ;
  9559. Black[jl]
  9560. ;
  9561. White[lq]
  9562. ;
  9563. Black[ip]
  9564. ;
  9565. White[lr]
  9566. ;
  9567. Black[hq]
  9568. ;
  9569. White[os]
  9570. ;
  9571. Black[or]
  9572. ;
  9573. White[gq]
  9574. ;
  9575. Black[dq]
  9576. ;
  9577. White[dr]
  9578. ;
  9579. Black[be]
  9580. ;
  9581. White[hb]
  9582. ;
  9583. Black[ic]
  9584. ;
  9585. White[sb]
  9586. ;
  9587. Black[ra]
  9588. ;
  9589. White[ie]
  9590. ;
  9591. Black[hc]
  9592. ;
  9593. White[gb]
  9594. ;
  9595. Black[gr]
  9596. ;
  9597. White[hi]
  9598. ;
  9599. Black[hj]
  9600. ;
  9601. White[ns]
  9602. ;
  9603. Black[ps]
  9604. ;
  9605. White[mr]
  9606. ;
  9607. Black[pp]
  9608. ;
  9609. White[oo]
  9610. ;
  9611. Black[rr]
  9612. ;
  9613. White[ej]
  9614. ;
  9615. Black[fj]
  9616. ;
  9617. White[ir]
  9618. ;
  9619. Black[hr]
  9620. ;
  9621. White[jr]
  9622. ;
  9623. Black[jo]
  9624. ;
  9625. White[kn]
  9626. ;
  9627. Black[ab]
  9628. ;
  9629. White[qk]
  9630. ;
  9631. Black[rk]
  9632. ;
  9633. White[oj]
  9634. ;
  9635. Black[ia]
  9636. ;
  9637. White[jp]
  9638. ;
  9639. Black[fr]
  9640. ;
  9641. White[iq]
  9642. ;
  9643. Black[hp]
  9644. ;
  9645. White[eq]
  9646. ;
  9647. Black[af]
  9648. ;
  9649. White[kl]
  9650. ;
  9651. Black[kk]
  9652. ;
  9653. White[ko]
  9654. ;
  9655. Black[ag]
  9656. ;
  9657. White[kh]
  9658. ;
  9659. Black[ki]
  9660. ;
  9661. White[bg]
  9662. ;
  9663. Black[gm]
  9664. ;
  9665. White[ng]
  9666. ;
  9667. Black[mh]
  9668. ;
  9669. White[sl]
  9670. ;
  9671. Black[so]
  9672. ;
  9673. White[rn]
  9674. ;
  9675. Black[hd]
  9676. ;
  9677. White[gd]
  9678. ;
  9679. Black[lm]
  9680. ;
  9681. White[ri]
  9682. ;
  9683. Black[si]
  9684. ;
  9685. White[sf]
  9686. ;
  9687. Black[sg]
  9688. ;
  9689. White[io]
  9690. ;
  9691. Black[ho]
  9692. ;
  9693. White[cd]
  9694. ;
  9695. Black[bd]
  9696. ;
  9697. White[pd]
  9698. ;
  9699. Black[pc]
  9700. ;
  9701. White[se]
  9702. ;
  9703. Black[nr]
  9704. ;
  9705. White[ms]
  9706. ;
  9707. Black[ha]
  9708. ;
  9709. White[ga]
  9710. ;
  9711. Black[lc]
  9712. ;
  9713. White[kd]
  9714. ;
  9715. Black[ed]
  9716. ;
  9717. White[ec]
  9718. ;
  9719. Black[fl]
  9720. ;
  9721. White[ah]
  9722. ;
  9723. Black[ae]
  9724. ;
  9725. White[je]
  9726. ;
  9727. Black[jf]
  9728. ;
  9729. White[ni]
  9730. ;
  9731. Black[mj]
  9732. ;
  9733. White[ih]
  9734. ;
  9735. Black[sc]
  9736. ;
  9737. White[sd]
  9738. ;
  9739. Black[od]
  9740. ;
  9741. White[pf]
  9742. ;
  9743. Black[db]
  9744. ;
  9745. White[eb]
  9746. ;
  9747. Black[ba]
  9748. ;
  9749. White[da]
  9750. ;
  9751. Black[do]
  9752. ;
  9753. White[hs]
  9754. ;
  9755. Black[og]
  9756. ;
  9757. White[of]
  9758. ;
  9759. Black[es]
  9760. ;
  9761. White[ds]
  9762. ;
  9763. Black[fs]
  9764. ;
  9765. White[jo]
  9766. ;
  9767. Black[ac]
  9768. ;
  9769. White[pe]
  9770. )
  9771. SHAR_EOF
  9772. fi
  9773. if test -f 'Rules'
  9774. then
  9775.     echo shar: "will not over-write existing file 'Rules'"
  9776. else
  9777. cat << \SHAR_EOF > 'Rules'
  9778. This files contains rules to the game of Go in Smart-Go format.  It should be 
  9779. viewed with the mgt program.
  9780.  
  9781. (
  9782. ;
  9783. GaMe[1]
  9784. VieW[]
  9785. SiZe[19]
  9786. Comment[        THE GAME OF GO
  9787.       A Brief Introduction
  9788.  
  9789.        by Adrian Mariano
  9790.  
  9791.  
  9792.  
  9793.    press . to move forward
  9794.    press , to move backward ]
  9795. ;
  9796. 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.]
  9797. ;
  9798. 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.]
  9799. ;
  9800. Comment[When a player has nothing left to do, he passes.  After two consecutive passes, the game is over.]
  9801. ;
  9802. Comment[An empty intersection adjacent to a stone \(orthogonally\) is called a liberty. 
  9803.  
  9804. 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.]
  9805. AddWhite[jj][js][ss]
  9806. Mark[ij][ji][kj][jk][is][jr][ks][rs][sr]
  9807. AddEmpty[aa]
  9808. ;
  9809. AddBlack[dc][dd][ed][fd][fe][ge]
  9810. 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.]
  9811. AddWhite[in][io][jn][jo][kl][km][ll][lm]
  9812. Mark[ff][gf][he][gd][ee][de][cd][fc][ec][cc][db]
  9813. 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]
  9814. ;
  9815. AddBlack[ij][ji][jj]
  9816. 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]
  9817. Comment[A group is captured if its last liberty is taken away.
  9818.  
  9819.  
  9820. Here is a black group with seven liberties.]
  9821. ;
  9822. AddWhite[hj]
  9823. Comment[A single white stone next to the group reduces it to six liberties.]
  9824. ;
  9825. AddWhite[ik][jh][jk][ki][kj]
  9826. 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.\)]
  9827. ;
  9828. White[ii]
  9829. Comment[The final white move captures the black group.]
  9830. ;
  9831. AddWhite[qh][qi][qj][rg][rk][sg][sk]
  9832. AddBlack[rh][ri][rj][sh][sj]
  9833. AddEmpty[aa][hj][ii][ik][jh][jk][ki][kj]
  9834. Comment[The black group has only one liberty.  White can capture the black group by playing inside black at T11.]
  9835. ;
  9836. White[si]
  9837. ;
  9838. AddBlack[rh][ri][rj][sh][sj]
  9839. 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.]
  9840. AddWhite[qh][qj][rg][rk][sg][sk]
  9841. AddEmpty[aa][qi][si]
  9842. ;
  9843. Comment[Another rule of Go is the Ko rule.  It is illegal to make a move which recreates preceeding board positions \(to prevent loops\).
  9844.  
  9845.  
  9846. Suppose black captures the white stone at J12.]
  9847. AddBlack[hh][ig][ii]
  9848. AddWhite[ih][jg][ji][kh]
  9849. 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]
  9850. ;
  9851. Black[jh]
  9852. Comment[If white were allowed to play at J12 now, the board would look exactly as it did before.]
  9853. ;
  9854. AddEmpty[jh]
  9855. AddWhite[ih]
  9856. 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.]
  9857. ;
  9858. AddEmpty[aa][hh][ig][ih][ii][jg][ji][kh][ph][qh][qj][rg][rh][ri][rj][rk][sg][sh][sj][sk]
  9859. 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.  
  9860.  
  9861.  
  9862. A liberty which is inside a group and completely surrounded is called an eye.  A group with two disconnected eyes cannot be captured.]
  9863. ;
  9864. AddBlack[ic][id][ie][jc][je][jj][jk][jl][kc][kd][ke][kj][kl][lc][le][lj][lk][ll][mc][md][me]
  9865. 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]
  9866. AddEmpty[aa][hb][hf][ii][im][mi][mm][nb][nf]
  9867. 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.
  9868.  
  9869. 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.]
  9870. ;
  9871. White[kk]
  9872. ;
  9873. AddWhite[aq][ar][bq][bs][cq][cr][cs]
  9874. AddBlack[ap][bp][cp][dp][dq][dr][ds]
  9875. 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]
  9876. 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.]
  9877. ;
  9878. 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.\)]
  9879. AddBlack[ap][bp][cp][cq][cr][cs]
  9880. AddWhite[ao][bo][co][do][dp][dq][dr][ds]
  9881. AddEmpty[aa][aq][ar][bq][br][bs]
  9882. ;
  9883. AddBlack[ao][bo][co][do][eo][fo][go][ho][hp][hq][hr][hs]
  9884. AddWhite[ap][bp][cp][cr][dp][dq][dr][ds][ep][fp][gp][gq][gr][gs]
  9885. 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.  ]
  9886. AddEmpty[aa][cq][cs]
  9887. ;
  9888. AddBlack[af][al][bf][bg][bk][bl][cg][ch][ci][cj][ck][ga][gb][gc][hc][ic][jc][kc][lc][ma][mb][mc]
  9889. AddWhite[ag][ai][ak][bh][bi][bj][ha][hb][ib][ja][jb][kb][la][lb]
  9890. 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]
  9891. 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!]
  9892. ;
  9893. 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.]
  9894. Black[ah]
  9895. ;
  9896. Black[aj]
  9897. ;
  9898. Comment[Here is another example of a DEAD group.  The white group at the bottom does NOT have two eyes.]
  9899. AddBlack[lp][lq][lr][ls][mp][np][op][oq][or][pp][qp][rp][sp][sq][sr]
  9900. AddWhite[mr][ms][nr][os][pq][pr][ps][qq][rq][rr][rs]
  9901. 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]
  9902. ;
  9903. AddWhite[ar][br][cr][cs]
  9904. AddBlack[aq][bq][cq][dq][dr][ds]
  9905. 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]
  9906. Comment[In this example, the white group is dead.  There is nothing white can do to prevent black from capturing it.]
  9907. ;
  9908. Black[bs]
  9909. ;
  9910. White[as]
  9911. ;
  9912. Black[bs]
  9913. 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.]
  9914. ;
  9915. AddWhite[ar][br][cr][dr][ds]
  9916. AddBlack[eq][er][es]
  9917. AddEmpty[aa][bs]
  9918. Comment[This case is more complicated.  If white plays first, then the group has two eyes and lives.]
  9919. ;
  9920. White[bs]
  9921. ;
  9922. Comment[On the other hand, if black plays first, the group is killed. ]
  9923. AddEmpty[aa][bs]
  9924. ;
  9925. Black[bs]
  9926. ;
  9927. White[cs]
  9928. ;
  9929. Black[as]
  9930. ;
  9931. Comment[In this case, the white group is alive, even if black plays first.]
  9932. AddWhite[ar][br][cr][dr][er][es]
  9933. AddBlack[aq][fq][fr][fs]
  9934. AddEmpty[aa][as][bs][en]
  9935. ;
  9936. Black[cs]
  9937. ;
  9938. White[bs]
  9939. ;
  9940. 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.\)]
  9941. AddBlack[ap][bp][cp][dp][dq][eq][er][es]
  9942. AddWhite[aq][bq][cq][cr][ds]
  9943. AddEmpty[aa][ar][bn][br][bs][cs]
  9944. ;
  9945. Black[bs]
  9946. ;
  9947. White[br]
  9948. ;
  9949. Black[as]
  9950. ;
  9951. White[cs]
  9952. ;
  9953. Black[ar]
  9954. ;
  9955. AddWhite[ao][bo][co][do][dp][dq][dr][ds]
  9956. AddBlack[ap][bp][cp][cq][cr][cs]
  9957. AddEmpty[aa][aq][ar][as][bq][bs][eq][er][es][fq][fr][fs]
  9958. 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.]
  9959. ;
  9960. Black[br]
  9961. ;
  9962. White[ar]
  9963. ;
  9964. Black[aq]
  9965. ;
  9966. White[bs]
  9967. ;
  9968. Black[as]
  9969. ;
  9970. AddEmpty[aa][aq][ar][as][br][es]
  9971. Comment[If, however, white plays first, white can kill the black group.]
  9972. ;
  9973. White[br]
  9974. ;
  9975. Black[bs]
  9976. ;
  9977. White[ar]
  9978. ;
  9979. Black[aq]
  9980. ;
  9981. White[as]
  9982. ;
  9983. Black[bq]
  9984. ;
  9985. White[ar]
  9986. ;
  9987. Black[br]
  9988. ;
  9989. White[as]
  9990. ;
  9991. 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]
  9992. 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]
  9993. AddEmpty[aa][ao][as][bo][co][do][dp][sh]
  9994. 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.]
  9995. ;
  9996. 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]
  9997. 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]
  9998. 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?]
  9999. 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]
  10000. ;
  10001. 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]
  10002. Comment[If there is debate over who owns a territory, or whether a group is alive, simply continue play until the players agree.]
  10003. ;
  10004. AddBlack[an][ap][bn][bo][bp][br][bs][cp][cs][dp][ds][ep][er][es][fp][gp][gq][gr][gs][hr][ir][is]
  10005. AddWhite[aq][ar][as][bq][cq][dq][eq][fq][fr][fs]
  10006. AddEmpty[ai][aj][ak][al][am][bi][bj][bk][bl][bm][cr][dr]
  10007. 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.
  10008.  
  10009. The reason is that neither black nor white can make a move in the region.  ]
  10010. (
  10011. ;
  10012. White[cr]
  10013. Comment[If white attempts to capture black by playing inside...]
  10014. ;
  10015. Black[dr]
  10016. Comment[Then black captures the white stones.]
  10017. )
  10018. (
  10019. ;
  10020. Comment[If black tries to capture white by moving inside...]
  10021. Black[cr]
  10022. ;
  10023. Comment[Then white captures black, and now the white group is alive.  ]
  10024. White[dr]
  10025. ;
  10026. 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.]
  10027. ;
  10028. 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]
  10029. 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?]
  10030. AddWhite[bh][bi][bj][bn][cj][cm][cn][dk][dl]
  10031. AddBlack[bf][bk][bl][bm][cf][cg][ch][ci][ck][di][dj]
  10032. ;
  10033. White[am]
  10034. ;
  10035. Black[bg]
  10036. ;
  10037. White[al]
  10038. ;
  10039. Black[ah]
  10040. ;
  10041. White[ak]
  10042. ;
  10043. Black[ai]
  10044. ;
  10045. White[cl]
  10046. ;
  10047. Black[ag]
  10048. ;
  10049. White[aj]
  10050. ;
  10051. 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.]
  10052. 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]
  10053. AddBlack[aq][bq][cq][cr][dq][eq][fq][gq][gr][gs]
  10054. AddWhite[ar][br][bs][dr][ds][er][fr][fs]
  10055. (
  10056. ;
  10057. Black[cs]
  10058. Comment[If black plays here, then the two white groups will die, since each has only one eye.]
  10059. )
  10060. (
  10061. ;
  10062. White[cs]
  10063. Comment[If white plays C1, then his stones are connected into one group which has two eyes.]
  10064. ;
  10065. AddEmpty[aa][aq][ar][bq][br][bs][cq][cr][cs][dq][dr][ds][eq][er][fq][fr][fs][gq][gr][gs]
  10066. 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.]
  10067. ;
  10068. Comment[In this situation, the black stones can be considered connected, even though they are not yet orthogonally connected directly.]
  10069. 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]
  10070. AddBlack[ai][ak][bi][bj][bk][cj][dj][ej][fk][gk][hj][hk][hl][ij][il][jj][jk][jl]
  10071. 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]
  10072. ;
  10073. Comment[If white threatens to disconnect the black stones...]
  10074. White[fj]
  10075. ;
  10076. Comment[...black always has a response which connects his stones.  ]
  10077. Black[ek]
  10078. ;
  10079. AddBlack[lm][lp][mm][mp][nm][np]
  10080. Comment[Here is another strong connection that cannot be cut.]
  10081. AddWhite[io][jo][ko][ln][lo][nn][no][on][pn][qn]
  10082. 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]
  10083. ;
  10084. Comment[If black tries to disconnect the white stones...]
  10085. Black[mo]
  10086. ;
  10087. Comment[...as with the diagonal connection, white always has a response which directly connects his stones. \(This is called a bamboo connection\)]
  10088. White[mn]
  10089. ;
  10090. Comment[There are several other weaker connections which can be cut.  ]
  10091. 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]
  10092. ;
  10093. 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.  
  10094.     The marked locations are the cutting points -- the moves white would make to disconnect black.]
  10095. Mark[fo][fb][fe][gh][fk]
  10096. 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]
  10097. 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]
  10098. ;
  10099. 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.]
  10100. AddBlack[bp][cp][dp][dq][dr][ph][pm][pn][po][pp][pq][qi][qq][qr][qs][ri][rj][rk][rs][si][sl]
  10101. AddWhite[bm][bo][co][do][eo][ep][eq][er][gr][oj][ok][ol][pl][ql][qn][rl][rn][ro][rp][rq][sq]
  10102. 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]
  10103. ;
  10104. White[br]
  10105. ;
  10106. Black[ar]
  10107. ;
  10108. White[cr]
  10109. ;
  10110. Black[ds]
  10111. ;
  10112. White[ap]
  10113. ;
  10114. Black[aq]
  10115. ;
  10116. White[ao]
  10117. ;
  10118. Black[bq]
  10119. ;
  10120. White[cs]
  10121. ;
  10122. Black[bs]
  10123. ;
  10124. Comment[We have reached a Ko situation.  Black may not retake the white stone at A1. 
  10125.  
  10126. Black may, however, attack the white formation on the right side of the board.]
  10127. White[as]
  10128. ;
  10129. 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.]
  10130. Black[qm]
  10131. (
  10132. ;
  10133. Name[On the right]
  10134. Comment[White will now respond on the right, connecting the white groups together.]
  10135. White[rm]
  10136. ;
  10137. Black[bs]
  10138. ;
  10139. 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.\)]
  10140. White[sm]
  10141. ;
  10142. Black[cq]
  10143. Comment[The black group lives.]
  10144. )
  10145. (
  10146. ;
  10147. Comment[White plays in the corner, planning to kill the group on the left.]
  10148. Name[In the corner]
  10149. ;
  10150. White[bs]
  10151. ;
  10152. Black[cq]
  10153. ;
  10154. Comment[The black stones are dead.]
  10155. White[bs]
  10156. ;
  10157. Comment[But black gets to cut off the white stones.]
  10158. Black[rm]
  10159. ;
  10160. Comment[Suppose black wants to capture the white stone.  ]
  10161. AddBlack[dm][em][fn]
  10162. AddWhite[en]
  10163. 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]
  10164. (
  10165. ;
  10166. Comment[If black plays here...]
  10167. Black[dn]
  10168. ;
  10169. Comment[...white escapes downward.  
  10170.  
  10171. This is not the correct approach.]
  10172. White[eo]
  10173. )
  10174. (
  10175. ;
  10176. Comment[Instead, black should play here.  This starts a pattern called the "ladder," a very common occurrence in go games.]
  10177. Black[eo]
  10178. ;
  10179. Comment[The only direction white can go is leftwards.  However, observe the sequence that follows. ]
  10180. White[dn]
  10181. ;
  10182. Black[cn]
  10183. ;
  10184. White[do]
  10185. ;
  10186. Black[dp]
  10187. ;
  10188. White[co]
  10189. ;
  10190. Black[bo]
  10191. ;
  10192. White[cp]
  10193. ;
  10194. Black[cq]
  10195. ;
  10196. White[bp]
  10197. ;
  10198. Black[ap]
  10199. ;
  10200. White[bq]
  10201. ;
  10202. Black[br]
  10203. ;
  10204. White[aq]
  10205. ;
  10206. Comment[Each of the moves is forced, and white is unable to save the stones.  
  10207.  
  10208.  
  10209. White must be able to recognize this, so he can avoid playing this sequence and losing such a large group of stones.]
  10210. Black[ar]
  10211. ;
  10212. Comment[The outcome is very different if white has a stone in the path of the ladder.]
  10213. AddBlack[fn]
  10214. AddWhite[bo][en]
  10215. AddEmpty[aa][ap][ar][br][cn][co][cq][dn][dp][eo]
  10216. ;
  10217. Black[eo]
  10218. ;
  10219. White[dn]
  10220. ;
  10221. Black[cn]
  10222. ;
  10223. White[do]
  10224. ;
  10225. Black[dp]
  10226. ;
  10227. White[co]
  10228. ;
  10229. Black[cm]
  10230. ;
  10231. White[ep]
  10232. ;
  10233. Black[fo]
  10234. ;
  10235. Comment[Black fails to capture white in this case.]
  10236. White[dq]
  10237. ;
  10238. Comment[In this case, white wishes to capture the black stone.  ]
  10239. AddWhite[jh][ji][jj][kj][lj]
  10240. AddBlack[ki]
  10241. AddEmpty[aa][bo][cm][cn][co][dm][dn][do][dp][dq][em][en][eo][ep][fn][fo][iq]
  10242. ;
  10243. Comment[To do so, white plays here.]
  10244. White[lh]
  10245. ;
  10246. Black[li]
  10247. ;
  10248. White[mi]
  10249. ;
  10250. Black[kh]
  10251. ;
  10252. White[kg]
  10253. ;
  10254. AddEmpty[aa][jh][ji][jj][kg][kj][lh][lj][mi]
  10255. 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.]
  10256. ;
  10257. 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]
  10258. 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.]
  10259. ;
  10260. 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]
  10261. 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.]
  10262. Black[pp]
  10263. ;
  10264. White[qq]
  10265. 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.]
  10266. ;
  10267. AddBlack[qq]
  10268. AddEmpty[aa][pp]
  10269. Comment[Opening at the 3,3 point insures ownership of the corner but has less potential for extension into the center.]
  10270. ;
  10271. AddBlack[de][pq]
  10272. AddEmpty[aa][qq]
  10273. Comment[Other good openings are the 5,4 point and the 3,4 point.]
  10274. ;
  10275. Comment[From either of these openings, black can make a corner enclosure so get corner territory.]
  10276. AddBlack[dc][qo]
  10277. ;
  10278. Comment[And then extend along the side, staking out side territory.]
  10279. AddBlack[ic][kq]
  10280. ;
  10281. AddEmpty[dc][de][ic][kq][pq][qo]
  10282. AddBlack[dd][dj][dp][jj][pd][pj][pp]
  10283. Comment[Go players use a handicap system to balance games between players of 
  10284. different skill.  The weaker player starts by placing from two to nine stones 
  10285. on the board in a special configuration on the handicap points.  
  10286.     
  10287.  
  10288. This is a seven stone handicap.]
  10289. ;
  10290. AddEmpty[aa][dd][dj][dp][jj][pd][pj][pp]
  10291. Comment[Playing strength of amateurs is measured on a scale where one unit 
  10292. corresponds to a handicap stone.  A total beginner is 35 kyu, and will very 
  10293. quickly improve to 20 kyu.  A player will reach 10 kyu after playing about 
  10294. 100 games.  Ranks worse than 10 kyu are unreliable because playing is too 
  10295. uneven and players progress too quickly to get a stable rating.]
  10296. ;
  10297. Comment[Beyond the kyu ranks are the amateur dan ranks which go from 1 dan to 6 dan, the highest amateur rank.
  10298.  
  10299.  
  10300. 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.]
  10301. ;
  10302. 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. ]
  10303. ;
  10304. 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.\)]
  10305. ;
  10306. 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.]
  10307. ;
  10308. 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.
  10309.  
  10310. Computer go programs are presently very weak -- they are ranked around 10 kyu]
  10311. )
  10312. )
  10313. )
  10314. )
  10315. )
  10316. SHAR_EOF
  10317. fi
  10318. if test -f 'Prop.lst'
  10319. then
  10320.     echo shar: "will not over-write existing file 'Prop.lst'"
  10321. else
  10322. cat << \SHAR_EOF > 'Prop.lst'
  10323.                              Smart-Go Properties 
  10324.  
  10325. mgt
  10326. supports
  10327.  
  10328. x       "B" : Black move                [move]
  10329. x       "W" : White move                [move]
  10330. x       "C" : Comment                   [Text]
  10331. x       "N" : Node Name                 [Text]
  10332.         "V" : Node value                [number]
  10333.         "CH": Check mark                [triple]
  10334.         "GB": good for black            [triple]
  10335.         "GW": good for white            [triple]
  10336.         "TE": good move (tesuji)        [triple]
  10337.         "BM": bad move                  [triple]
  10338.         "BL": time left for Black       [real]
  10339.         "WL": time left for White       [real]
  10340.         "FG": figure                    [none]
  10341. x       "AB": add black stones          [point list]
  10342. x       "AW": add white stones          [point list]
  10343. x       "AE": add empty stones          [point list]
  10344. x       "PL": player to play first      [color]
  10345. x       "GN": game name                 [text]
  10346. x       "GC": game comment              [text]
  10347. x       "EV": event (tournament)        [text]
  10348. x       "RO": round                     [text]
  10349. x       "DT": date                      [text]
  10350. x       "PC": place                     [text]
  10351. x       "PB": black player name         [text]
  10352. x       "PW": white player name         [text]
  10353. x       "RE": result, outcome           [text]
  10354. x       "US": user (who entered game)   [text]
  10355. x       "TM": time limit per player     [text]
  10356. x       "SO": source (book, journal...) [text]
  10357. x       "GM": game                      [number] (Go=1)
  10358. x       "SZ": board size                [number]
  10359.         "VW": partial view              [point list]
  10360.         "BS": black species             [number] (human=0, modem=-1, computer>0)
  10361.         "WS": white species             [number]
  10362.         "EL": evaluation of computer mv [number]
  10363.         "EX": expected next move        [move, game-specific]
  10364.         "SL": selected points           [point list, game-specific]
  10365. x       "M" : marked points             [point list, game-specific]
  10366. x       "L" : letters on points         [point list, game-specific]
  10367. x       "BR": Black's rank              [text]
  10368. x       "WR": White's rank              [text]
  10369. x       "HA": handicap                  [number]
  10370. x       "KM": komi                      [real]
  10371.         "TB": Black's territory         [point list]
  10372.         "TW": White's territory         [point list]
  10373.         "SC": secure stones             [point list]
  10374.         "RG": region of the board       [point list]
  10375.  
  10376. SHAR_EOF
  10377. fi
  10378. if test -f 'README.IBM'
  10379. then
  10380.     echo shar: "will not over-write existing file 'README.IBM'"
  10381. else
  10382. cat << \SHAR_EOF > 'README.IBM'
  10383.                             The IBM Implementation
  10384.  
  10385. The IBM PC implementation has several features which are absent from the 
  10386. UNIX version.  
  10387.  
  10388.                              Keyboard Extensions
  10389.  
  10390. The cursor keys work in the editor as cursor keys.
  10391.      
  10392. When not in the editor, they have the following functions:
  10393.     right, left: down tree, up tree (like > and < respectively)
  10394.     up, down:    last, next variation branch
  10395.     pgup, pgdn:  last, next comment
  10396.  
  10397.  
  10398.                               Display Extensions
  10399.  
  10400. There are three display modes for the IBM mgt:
  10401.     graphics mode, nographics mode, and nocolor mode
  10402.  
  10403. Graphics mode is the default on VGA or EGA systems.  The board is displayed 
  10404. using special graphics characters.  The _ASCCHAR specification is ignored.
  10405.  
  10406. In nographics mode, color is used to obtain good contrast between the board 
  10407. and the stones.  The "black stone" character is used for both white and 
  10408. black stones with different colors.  Similarly, the "black territory" 
  10409. marker is used for both white and black territory.  The "white stone" 
  10410. character and the "white territory" character are ignored.  
  10411.  
  10412. Nocolor mode is the pure text display.  The default uses IBM graphics
  10413. characters for the borders.  
  10414.  
  10415. In both nographics mode and nocolor mode, ascii 3 (a heart symbol) is used 
  10416. the default for the black stone character.
  10417.  
  10418. To force nographics mode, put _ASCNOGRAPH in your MGT environment string.  
  10419. To force nocolor mode, put _ASCNOCOLOR in the environment string.
  10420.  
  10421. In either graphics or nographics modes, the display colors can be set 
  10422. through these environment strings:
  10423.   _ASCBCOL:   black stone color
  10424.   _ASCWCOL:   white stone color
  10425.   _ASCDAME:   dame color
  10426.   _ASCBOARD:  board color
  10427.   _ASCBG:     background
  10428.   _ASCFG:     foreground
  10429.   _ASCMARK:   mark color
  10430.   _ASCLET:    letter color
  10431.   _ASCMENUFG: menu foreground
  10432.   _ASCMENUBG: menu background
  10433.  
  10434. The colors are:
  10435.     0   black         8   dark gray    
  10436.     1   blue          9   light blue   
  10437.     2   green         10  light green  
  10438.     3   cyan          11  light cyan   
  10439.     4   red           12  light red    
  10440.     5   magenta       13  light magenta
  10441.     6   brown         14  yellow       
  10442.     7   light gray    15  white        
  10443.  
  10444. To choose the defaults, you would execute the command:
  10445.  
  10446. set MGT=_ASCBCOL:0 _ASCWCOL:7 _ASCDAME:1 _ASCBOARD:6 _ASCBG:0 _ASCFG:0
  10447.         _ASCMARK:9 _ASCLET:1 _ASCMENUFG:2 _ASCMENUBG:0
  10448.  
  10449. (You don't need to do this if you like the defaults.)
  10450.  
  10451. The _ASCINV environment item will swap the foreground and background, and 
  10452. set the menu background to the background.  This is equivalent to pressing 
  10453. '&' from within mgt.
  10454.  
  10455. If you run mgt in graphics mode with a VGA, color 6 is changed to a brown 
  10456. shade defined by red, green and blue components: 
  10457.         _RED:39 _BLUE:5 _GREEN:33
  10458. This color is meant to be used for the board.  Other colors for color 6 can be 
  10459. selected by specifying different values for red, green and blue in the 
  10460. environment.  The range is 0-63.  
  10461.  
  10462. One person thought _RED:40 _GREEN:30 _BLUE:14 with the background
  10463. inverted looked better than the defaults.
  10464.  
  10465. A CGA user suggests the following combination:
  10466.                  _ASCBOARD:5 _ASCMARK:4 _ASCLET:2   
  10467.  
  10468.  
  10469.                                 Mouse Support
  10470.  
  10471. The mouse cursor is an arrow in EGA or VGA modes.  If you don't want the 
  10472. arrow, put _ASCMOUSENORM in the environment variable.  
  10473.  
  10474. The mouse can be used to click on menus, or to click on various parts of 
  10475. the board. 
  10476.  
  10477.  
  10478.  
  10479. The top line contains various mode listings.  
  10480.  
  10481.     help quit stone walk move
  10482.  
  10483. Clicking on help or quit gets help or quits.  
  10484.  
  10485. The third word indicates the mode for placing items on the board.  In stone 
  10486. mode, the left mouse button plays a stone on the board, and the right mouse 
  10487. button sets a stone on the board.  (Equivalent to space, and either z or x 
  10488. respectively.)  The color of the stone set is determined by the player 
  10489. indicator in the lower right corner of the screen.  Clicking on the word 
  10490. "stone" on the top line will change it to "mark".  In this mode, the left 
  10491. mouse button sets or unsets letters on the board and the right mouse button 
  10492. sets and unsets marks.  
  10493.  
  10494. The fourth item on the top line is either "walk" or "branch" to indicate the 
  10495. type of game tree traversal.  In walk mode, clicking with the left button 
  10496. anywhere on the variation window moves down the tree (like the > key).  In 
  10497. branch mode, clicking on a specific variation visits that variation (like 
  10498. pressing capital letters).  In branch mode clicking on blank parts of the 
  10499. variation window does nothing.  In either of these modes, right clicking moves 
  10500. back up the tree.  
  10501.  
  10502. The last mode indicator on the top line identifies the menu choice.  
  10503. There are four different menus you can choose:
  10504.  
  10505. move:  start end var comment
  10506.  
  10507. This is the default menu.  Clicking on start or end moves to the start of the 
  10508. game record or the end of the current variation (like the b and e keys).  
  10509. Left clicking on var or comment goes to the next variation branch or the next 
  10510. comment.  Right clicking on either one goes to the previous variation branch 
  10511. or comment.  
  10512.  
  10513. play: score pass player
  10514.  
  10515. These menu items score the game, pass a move (like p key) or set the player 
  10516. (like the o key), actually changing the Smart-Go record to specify the current 
  10517. player.  
  10518.  
  10519. edit: info cut paste delnode addvar
  10520.  
  10521. These items invoke the info, cut, paste, delete node, and add variation 
  10522. commands.  
  10523.  
  10524. file: save load next prev
  10525.  
  10526. These save the game record, load a file, move to the next, or the previous 
  10527. file.  Some loading commands are available directly from the screen.
  10528. If you loaded mgt with 2 or more files, then left clicking on the filename at 
  10529. the upper right will move to the next file, and right clicking will move to 
  10530. the previous file.  If you specified only one file, then clicking on the 
  10531. filename will load a new file (by name).  
  10532.  
  10533.  
  10534. To scroll the comment window or variation windows with the mouse, click on the 
  10535. '+' or '-' character.  
  10536.  
  10537. To edit a comment, click on the comment window.  To move to a node by number, 
  10538. click on the word "node" above the variation window, and to set the node name, 
  10539. click on the node name above the variation window.
  10540.  
  10541. To select the stone color (like the 't' key) click on the stone that is 
  10542. displayed on the lower right corner of the screen.
  10543.  
  10544. At any (y/n) query, press the left button once to get a 'y' and a second time 
  10545. to get a return.  Pressing the right button twice gets a 'n' and return.  
  10546. Pressing one button and then the other gets either 'y' or 'n', and then a 
  10547. backspace to remove the character that is there.  
  10548.  
  10549. When scoring a game, press right button to score, left button to kill, or
  10550. click on the words at the bottom of the screen to undo, quit, or score.
  10551.  
  10552. Click on the word "tutor" to leave tutor mode, and click on "read" or "edit" 
  10553. to enter tutor mode.  
  10554.  
  10555. Click on the word "short" or "long" to toggle the save format for Smart-Go 
  10556. files between short and long.
  10557.  
  10558. SHAR_EOF
  10559. fi
  10560. exit 0
  10561. #    End of shell archive
  10562.