mgt-2.31/ 40755 1750 1750 0 6432324043 7770 5ustar memmemmgt-2.31/ascii.c100640 1750 1750 74525 6176731446 11370 0ustar memmem/* ascii.c test version 9/2/92 wclrtoeol */ /* "mgt" Copyright (c) 1991 Shodan */ #include #include "mgt.h" #define TOP 2 #define LEFT 4 #define RIGHT 79 #define STATUS_X 45 #define STATUS_Y 0 #define STATUS_WIDE (RIGHT-STATUS_X) #define COMMENT_X 46 #define COMMENT_Y 2 #define COMMENT_WIDE (RIGHT-COMMENT_X) #define COMMENT_HIGH (14-COMMENT_Y) #define TREE_X COMMENT_X #define TREE_Y 15 #define TREEWIDE (RIGHT-TREE_X) #define TREEHIGH 6 #define COMMAND_X TREE_X #define COMMAND_Y (TREE_Y+TREEHIGH) #define WINLEFT COMMENT_X #define WINRIGHT (RIGHT-1) #define WINTOP 2 #define WINBOT 13 #define WINHIGH (WINBOT-WINTOP) #define WINWIDE (WINRIGHT-WINLEFT) #define SCRHIGH 120 #define PGOFFSET 3 #define CTRLC ('C'-64) #define CTRLL ('L'-64) #define ESC 27 #define EDHELP "%s - write %s %s - keep old %s" #define EDUP 0 #define EDDOWN 1 #define EDPUP 2 #define EDPDOWN 3 #define EDLEFT 4 #define EDRIGHT 5 #define EDBOL 6 #define EDEOL 7 #define EDBOC 8 #define EDEOC 9 #define EDDEL 10 #define EDDEOL 11 #define EDTINS 12 #define EDSAVE 13 #define EDABORT 14 #define MAXEDCMDS 14 #define C_COMMENTSCROLLDOWN C_LASTCOMMAND #define C_COMMENTSCROLLUP ((command) ((int)C_LASTCOMMAND+1)) #define C_TREESCROLLDOWN ((command) ((int)C_LASTCOMMAND+2)) #define C_TREESCROLLUP ((command) ((int)C_LASTCOMMAND+3)) #define C_VIDEO ((command) ((int)C_LASTCOMMAND+4)) #define C_LASTOFS 5 enum { CHAR_BLACK, CHAR_WHITE, CHAR_DAME, CHAR_BLACKTERR, CHAR_WHITETERR, CHAR_NOTHING, CHAR_HANDICAP, CHAR_VERT, CHAR_HORIZ, CHAR_UPLEFT, CHAR_UPRIGHT, CHAR_DOWNLEFT, CHAR_DOWNRIGHT, ASC_NUMCHARS }; static boolean commentExists; static int commentLine; static int treeLine; static int inverseFlag = 0; static char boardPiece(); static int getLine(); static void drawPiece(); static void printstatus(); static void setCursor(); char keys[] = "q><.,eb}{][gwzxv!lm#^cdnspotrfLWTFI012346789kiju&"; char edcmds[] = "PNpnBFAE<>DKIzW"; char emacscmds[] = "PNpnBFAE<>DKIzW"; char vicmds[] = "kj\002\006hl0$HLxDRwq"; int edvi = 0; char xAxisChars[] = "ABCDEFGHJKLMNOPQRSTUVWXYZ"; char helpMsg[] = "? for help"; static void fixedkeys() { char *ptr; if (!edvi) for (ptr = edcmds; *ptr; ptr++) if (*ptr >= 'A' && *ptr <= 'Z') *ptr -= 64; else *ptr |= 128; } char *dispedkey(key, keystr) char key; char *keystr; { if (key & 128) { keystr[0] = ']'; keystr[1] = key & 127; keystr[2] = 0; } else if (key < ' ') { keystr[0] = '^'; keystr[1] = key + 64; keystr[2] = 0; } else { keystr[0] = key; keystr[1] = 0; } return keystr; } static void fixkeys() { char *keyptr; for (keyptr = keys; *keyptr; keyptr++) if (*keyptr >= 'A' && *keyptr <= 'Z') *keyptr -= 64; } #ifdef MGT_IBM #include "asc_ibm.inc" #endif #if (MGT_UNIX || vms) #include "asc_unix.inc" #endif static void notifyClearAscii() { move(23, 1); clrtoeol(); } static void notifyMessageAscii(s) char *s; { mvaddstr(23, 1, s); refresh(); } static void notifyErrorAscii(s) char *s; { mvaddstr(23, 1, s); printw(" Hit a key."); refresh(); getKey(); notifyClearAscii(); } static void clearScreenAscii() { clear(); } static void printstatus(mesg) char *mesg; { int i; move(STATUS_Y, STATUS_X); for (i = 0; i < STATUS_WIDE && mesg[i]; i++) addch(mesg[i]); } static int getLine(query, dst, maxLen) /* char *, char *, int */ char *query, *dst; int maxLen; { int qLen, dLen; char c; mvaddstr(23, 1, query); clrtoeol(); dLen = 0; qLen = strlen(query); do { move(23, qLen + 1 + dLen); refresh(); c = getKeyLine(); if (isprint(c) && dLen < maxLen) { move(23, qLen + dLen + 1); refresh(); addch(c); dst[dLen++] = c; } else if (dLen && (c == '\b' || c == '\177')) { dLen--; move(23, qLen + dLen + 1); addch(' '); } } while (c != '\n' && c != '\r'); dst[dLen] = 0; move(23, 1); clrtoeol(); return dLen; } static int askYNAscii(query, def) char *query; int def; { static char *yn[] = {" (y/N)? ", " (Y/n)? "}; char line[80]; char buf[3]; strcpy(line, query); strcat(line, yn[def]); if (getLine(line, buf, 2)) { if (*buf == 'Y' || *buf == 'y') return 1; if (*buf == 'N' || *buf == 'n') return 0; } return def;; } static void setCursor(x, y) int x, y; { move(TOP + y, LEFT + 2 * x); } static void printNStr(s, n) char *s; int n; { int i; for (i = 0; i < n && s[i]; i++) addch(s[i]); } static void drawTreeAscii0(n) nodep n; { property *p; move(TREE_Y, TREE_X + 1); printw(" Node #%d: ", n->nodeNum); if (p = getprop(n, t_Name)) { int num, width; width = TREEWIDE - 10; num = n->nodeNum; do { num /= 10; width--; } while (num); printNStr(p->data.comment, width); } clrtoeol(); { int temp; if (treeLine < 0) treeLine = 0; else { temp = treeCountSiblings(n) - TREEHIGH + 1; temp = MAX(temp, 0); treeLine = treeLine > temp ? temp : treeLine; } } { nodep ch; int index; index = 0; ch = nthChild(n, treeLine); while (ch && index < TREEHIGH - 1) { move(index + TREE_Y + 1, TREE_X); printw("%c:", 'A' + index + treeLine); clrtoeol(); if (p = getprop(ch, t_Name)) printNStr(p->data.comment, 80 - (TREE_X + 3)); ch = ch->nextSibling; index++; } while (index < TREEHIGH - 1) { move(index++ + TREE_Y + 1, TREE_X); clrtoeol(); } move(TREE_Y + TREEHIGH - 1, TREE_X - 1); addch(ch ? '+' : ' '); move(TREE_Y + 1, TREE_X - 1); addch(treeLine ? '-' : ' '); } refresh(); } /* draw the tree children when node currently is at n */ static void drawTreeAscii(n) nodep n; { treeLine = 0; drawTreeAscii0(n); } static void closeAscii() { endwin(); } static void refreshAscii() { refresh(); } static char boardPiece(x, y) int x, y; { return (((boardsize == 19 && x == 9) || (boardsize >= 10 && (x == 3 || x == boardsize - 4)) || (boardsize > 6 && boardsize < 10 && (x == 2 || x == boardsize - 3))) && ((boardsize == 19 && y == 9) || (boardsize >= 10 && (y == 3 || y == boardsize - 4)) || (boardsize > 6 && boardsize < 10 && (y == 2 || y == boardsize - 3))) ) ? chars[(int) CHAR_HANDICAP] : chars[(int) CHAR_NOTHING]; } static void plotPieceAscii(b, i, j) pBoard b; int i, j; { piece p; char c; p = boardGet(b, i, j); switch (p) { case P_NOTHING: c = boardPiece(i, j); break; case P_BLACK: c = chars[(int) CHAR_BLACK]; break; case P_WHITE: c = chars[(int) CHAR_WHITE]; break; case P_DAME: c = chars[(int) CHAR_DAME]; break; case P_BLACKTERR: c = chars[(int) CHAR_BLACKTERR]; break; case P_WHITETERR: c = chars[(int) CHAR_WHITETERR]; break; } drawPiece(i, j, c); } static char *savetype[] = {"long ", "short"}; static void highlightAscii(x, y, movenum, turn) int x, y, movenum, turn; { extern int madechanges; if (turn != -1){ move(23, 1); printw("%s #%d ", turn ? "White" : "Black", movenum); if (x == PASSVAL && y == PASSVAL) printw("Pass "); else printw("at %c%d ", xAxisChars[x], boardsize - y); } else { move(23, 1); clrtoeol(); } drawPrisoners(); move(COMMAND_Y, COMMAND_X + 15); if (tutor) printw("tutor"); else if (madechanges) printw("edit "); else printw("read "); printw(" %s", savetype[saveShort ? 1 : 0]); refresh(); } static void showCommentAscii(i) /* display from line i onward */ int i; { short line; /* line = MIN(commentLines() - i, COMMENT_HIGH); / */ line = COMMENT_HIGH; move(COMMENT_Y, COMMENT_X - 1); addch(i ? '-' : ' '); move(COMMENT_Y + COMMENT_HIGH - 1, COMMENT_X - 1); addch(commentLines() - i > COMMENT_HIGH ? '+' : ' '); while (line--) { mvaddstr(line + COMMENT_Y, COMMENT_X, commentGet(line + i)); clrtoeol(); } refresh(); } static void clearCommentAscii() { int line; commentExists = false; for (line = COMMENT_Y; line < COMMENT_Y + COMMENT_HIGH; line++) move(line, COMMENT_X), clrtoeol(); move(COMMENT_Y, COMMENT_X - 1); addch(' '); move(COMMENT_Y + COMMENT_HIGH - 1, COMMENT_X - 1); addch(' '); refresh(); } static void displayCommentAscii(s) char *s; { commentExists = true; commentLine = 0; formatComment(s, COMMENT_WIDE); showCommentAscii(0); refresh(); } static command charToCommand(c) char c; { int i; if ((c == ESC) || (c == CTRLC)) return C_QUIT; for (i = (int) C_LASTCOMMAND + C_LASTOFS; i--;) { if (c == keys[i]) break; } return (command) i; /* -1 = not found */ } static int getPointAscii() { char c; setCursor(xcur, ycur); refresh(); while (1) { c = getKeyScore(); if (c == 'u') return (int) C_UNDO; if ((c == ESC) || (c == keys[(int) C_QUIT])) return (int) C_QUIT; if (c == 014) return (int) C_REDRAW; if ((c == '\r') || (c == '\n')) return (int) C_SCORE; if ((c == ' ') || (c == keys[(int) C_MOVE])) return (int) C_MOVE; switch (charToCommand(c)) { case C_CURLEFT: xcur = (xcur - 1 + boardsize) % boardsize; setCursor(xcur, ycur); refresh(); break; case C_CURRIGHT: xcur = (xcur + 1) % boardsize; setCursor(xcur, ycur); refresh(); break; case C_CURUP: ycur = (ycur - 1 + boardsize) % boardsize; setCursor(xcur, ycur); refresh(); break; case C_CURDOWN: ycur = (ycur + 1) % boardsize; setCursor(xcur, ycur); refresh(); break; case C_UPLEFT: ycur = (ycur - 1 + boardsize) % boardsize; xcur = (xcur - 1 + boardsize) % boardsize; setCursor(xcur, ycur); refresh(); break; case C_UPRIGHT: xcur = (xcur + 1) % boardsize; ycur = (ycur - 1 + boardsize) % boardsize; setCursor(xcur, ycur); refresh(); break; case C_DOWNLEFT: xcur = (xcur - 1 + boardsize) % boardsize; ycur = (ycur + 1) % boardsize; setCursor(xcur, ycur); refresh(); break; case C_DOWNRIGHT: xcur = (xcur + 1) % boardsize; ycur = (ycur + 1) % boardsize; setCursor(xcur, ycur); refresh(); break; } } } static char *edhelp[] = { " Comment Editor Help", "", " Cursor control ('^' control, ']' /):", " %s: Previous line %s: Next line", " %s: Previous page %s: Next page", " %s: Back one character %s: Forward one character", " %s: Beginning of line %s: End of line", " %s: Beginning of comment %s: End of comment", " %s: Delete one character %s: Delete to end of line", " Press %s to toggle insert mode", " Press %s to exit and write your comment", " Press %s to exit and keep the old comment", "", " (Warning: comments longer than 120 lines", " will be truncated if edited)", "", " Other Notes", "", " When saving a file, * stands for the current file", " (printed in the upper right corner)", "", " Hit any key to return" }; #define HALFWAY (((int)C_DOWNLEFT)/2) char *fixkey(key, keystr) char key; char *keystr; { if (key == keys[(int) C_QUIT]) printw("ESC or "); if (key == keys[(int) C_MOVE]) printw("Space or "); if (key < ' ') { keystr[0] = '^'; keystr[1] = key + 64; keystr[2] = 0; } else { keystr[0] = key; keystr[1] = 0; } return keystr; } static void helpAscii() { int i; extern char *helpStr[]; char keystr[3]; char kstr[3]; char ch; /* don't put anything here */ preserveScreen(); clear(); move(0, 33); printw("MGT Version %s", VERSION); move(1, 12); printw("Written by Greg Hale Enhancements by Adrian Mariano"); move(2, 11); printw("(hale@scam.Berkely.edu) (adrian@bsdserver.ucsf.edu)"); for (i = 0; i < HALFWAY; i++) { move(i + 3, 8); printw("%s: %s", fixkey(keys[i], keystr), helpStr[i]); move(i + 3, 46); printw("%s: %s", fixkey(keys[i + HALFWAY], keystr), helpStr[i + HALFWAY]); } move(21, 8); printw("%s", fixkey(keys[C_TREESCROLLUP], keystr)); printw(", %s: Scroll tree window", fixkey(keys[C_TREESCROLLDOWN], keystr)); move(21, 46); printw("%s", fixkey(keys[C_COMMENTSCROLLUP], keystr)); printw(", %s: Scroll comment window", fixkey(keys[C_COMMENTSCROLLDOWN], keystr)); move(22, 8); printw("Uppercase letters visit variations"); move(22, 46); for (i = (int) C_DOWNLEFT; i <= (int) C_UPRIGHT; i++) addch(keys[i]); printw(": Cursor movement"); move(23, 21); printw("Hit return to return, any key to continue"); refresh(); ch = getKey(); if (ch != '\r' && ch != '\n') { clear(); for (i = 0; i < 3; i++) { move(i, 10); printw(edhelp[i]); } for (i = 0; i < 12; i += 2) { move((i / 2 + 3), 10); printw(edhelp[(i / 2 + 3)], dispedkey(edcmds[i], kstr), dispedkey(edcmds[i + 1], keystr)); } move(9, 10); printw(edhelp[9], dispedkey(edcmds[EDTINS], kstr)); move(10, 10); printw(edhelp[10], dispedkey(edcmds[EDSAVE], kstr)); move(11, 10); printw(edhelp[11], dispedkey(edcmds[EDABORT], kstr)); for (i = 12; i < sizeof(edhelp) / sizeof(char *); i++) mvaddstr(i, 10, edhelp[i]); refresh(); ch = getKey(); if (ch != '\r' && ch != '\n') specialHelp(); } restoreScreen(); } static int idleAscii(curnode) nodep curnode; { char c; command r; command com; highlightLast(); setCursor(xcur, ycur); refresh(); c = getKeyIdle(); if (r = specialKeysIdle(c)) return (int) r; r = C_NOTHING; if (c >= 'A' && c <= 'Z') { r = (command) ((char) C_CHOSECHILD + (c - 'A')); } else switch (c) { case ' ': return (int) C_MOVE; case '?': helpAscii(); return (int) C_NOTHING; default: com = charToCommand(c); switch (com) { case C_QUIT: { char buf[5]; if (c != ESC) { getLine("Quit (y/N)?", buf, 1); if (buf[0] == 'y') r = C_QUIT; } else r = C_QUIT; } break; case C_VIDEO: inverseFlag = !inverseFlag; return (int) C_REDRAW; case C_COMMENTSCROLLDOWN: if (commentExists) { if (commentLine < commentLines() - COMMENT_HIGH) commentLine += COMMENT_HIGH - PGOFFSET; showCommentAscii(commentLine); } break; case C_COMMENTSCROLLUP: if (commentExists && commentLine) { commentLine -= COMMENT_HIGH - PGOFFSET; showCommentAscii(commentLine); } break; case C_TREESCROLLDOWN: treeLine++; drawTreeAscii0(curnode); break; case C_TREESCROLLUP: treeLine--; drawTreeAscii0(curnode); break; default: r = (command) com; } } return (int) r; } #define MATCH(string,action) if (!strncmp((*env), (string), strlen(string))){ \ (*env) += strlen(string);\ action;\ } else static void readEnvAscii(env) char **env; { MATCH("ASCCOM:", strncpy(keys, *env, (int) C_LASTCOMMAND + C_LASTOFS)) MATCH("ASCCHAR:", strncpy(chars, *env, (int) ASC_NUMCHARS)) MATCH("ASCED:", strncpy(edcmds, *env, MAXEDCMDS + 1)) MATCH("ASCINV", inverseFlag = 1) MATCH("ASCEDVI", (edvi = 1, strncpy(edcmds, vicmds, MAXEDCMDS + 1))) MATCH("ASCEDEMACS", (edvi = 0, strncpy(edcmds, emacscmds, MAXEDCMDS + 1))) #ifdef MGT_IBM MATCH("ASCARROW:", cursorkey = (0 == strnicmp(*env, "cursor", 6)) + 2 * (0 == strnicmp(*env, "mode", 4))) MATCH("ASCNOGRAPH", graphics = 0) MATCH("ASCMOUSENORM", graphicalCursor = 0) MATCH("ASCNOCOLOR", (usecolor = 0, graphics = 0)) MATCH("ASCBCOL:", blackstone = atoi(*env)) MATCH("ASCWCOL:", whitestone = atoi(*env)) MATCH("ASCDAME:", damecolor = atoi(*env)) MATCH("ASCBOARD:", boardcolor = atoi(*env)) MATCH("ASCBG:", background = atoi(*env)) MATCH("ASCFG:", foreground = atoi(*env)) MATCH("ASCMARK:", markcolor = atoi(*env)) MATCH("ASCLET:", lettercolor = atoi(*env)) MATCH("ASCMENUBG:", menubg = atoi(*env)) MATCH("ASCMENUFG:", menufg = atoi(*env)) MATCH("RED:", bred = atoi(*env)) MATCH("GREEN:", bgreen = atoi(*env)) MATCH("BLUE:", bblue = atoi(*env)) #endif ; } char screen[SCRHIGH + 1][WINWIDE + 1]; int yoffset, cmplus, cmminus; #define inwin(Y) ((Y <= (WINHIGH + yoffset)) && (Y >= yoffset)) static void showcommentindicator() { int rfr; rfr = 0; mainwin(); if (!((yoffset > 0) == cmminus)) { cmminus = !cmminus; move(COMMENT_Y, COMMENT_X - 1); addch(cmminus ? '-' : ' '); rfr = 1; } if (!((screen[yoffset + WINHIGH + 1][0] > 0) == cmplus)) { cmplus = !cmplus; move(COMMENT_Y + COMMENT_HIGH - 1, COMMENT_X - 1); addch(cmplus ? '+' : ' '); rfr = 1; } if (rfr) refresh(); unmainwin(); } static void adjustwin(win, yloc) WINDOW *win; int yloc; { int x, y; if ((yloc < yoffset) || (yloc > (yoffset + WINHIGH))) { if (yloc < yoffset) yoffset = yloc - WINHIGH + PGOFFSET; if (yloc > (yoffset + WINHIGH)) yoffset = yloc - PGOFFSET; if (yoffset < 0) yoffset = 0; if (yoffset > (SCRHIGH - WINHIGH)) yoffset = (SCRHIGH - WINHIGH); for (; yoffset > 0 && !screen[yoffset + WINHIGH][0]; yoffset--); for (y = yoffset; y <= (yoffset + WINHIGH) && screen[y][0]; y++) { for (x = 0; x <= WINWIDE && screen[y][x]; x++) { wmove(win, y - yoffset, x); waddch(win, screen[y][x] < ' ' ? ' ' : screen[y][x]); } if (x <= WINWIDE) { wmove(win, y - yoffset, x); wclrtoeol(win); } } if (y <= (yoffset + WINHIGH)) { wmove(win, y - yoffset, 0); wclrtobot(win); } } showcommentindicator(); } static void fixnewline(win, xloc, yloc) WINDOW *win; int xloc, yloc; { if (xloc < WINWIDE && screen[yloc][xloc] == '\n' && screen[yloc][xloc + 1]) { int myx, myy; for (myy = SCRHIGH - 1; myy > yloc && !screen[myy][0]; myy--); for (; myy > yloc; myy--) for (myx = 0; myx <= WINWIDE && (screen[myy + 1][myx] || screen[myy][myx]); myx++) { screen[myy + 1][myx] = screen[myy][myx]; if (inwin((myy + 1))) { wmove(win, myy - yoffset + 1, myx); waddch(win, screen[myy][myx] >= ' ' ? screen[myy][myx] : ' '); } } for (myx = xloc + 1; myx <= WINWIDE && screen[myy][myx]; myx++) { screen[myy + 1][myx - xloc - 1] = screen[myy][myx]; if (inwin(myy)) { wmove(win, myy - yoffset, myx); waddch(win, ' '); } if (inwin((myy + 1))) { wmove(win, myy - yoffset + 1, myx - xloc - 1); waddch(win, screen[myy][myx] >= ' ' ? screen[myy][myx] : ' '); } screen[myy][myx] = 0; } for (myx = myx - xloc - 1; myx <= WINWIDE && screen[myy + 1][myx]; myx++) { screen[myy + 1][myx] = 0; if (inwin((myy + 1))) { wmove(win, myy - yoffset + 1, myx); waddch(win, ' '); } } wrefresh(win); } } static void deletechar(win, x, y, x1, y1) WINDOW *win; int x, y, x1, y1; { char c; c = ' '; while (c && !(c == '\n') && x1 <= WINWIDE && y1 <= SCRHIGH) { c = screen[y1][x1]; screen[y][x] = c; if (inwin(y)) { wmove(win, y - yoffset, x); waddch(win, c < ' ' ? ' ' : c); } screen[y1][x1] = 0; if (x < WINWIDE) x++; else { x = 0; y++; } if (x1 < WINWIDE) x1++; else { x1 = 0; y1++; } } for (; x <= WINWIDE; x++) { screen[y][x] = 0; if (inwin(y)) { wmove(win, y - yoffset, x); waddch(win, ' '); } } if (!(y == y1)) { y++; y1++; for (; y1 <= SCRHIGH && screen[y1][0]; y++, y1++) for (x = 0; x <= WINWIDE; x++) { screen[y][x] = screen[y1][x]; if (inwin(y)) { wmove(win, y - yoffset, x); waddch(win, screen[y][x] < ' ' ? ' ' : screen[y][x]); } } for (x = 0; x <= WINWIDE; x++) { screen[y1 - 1][x] = 0; if (inwin(y1 - 1)) { wmove(win, y1 - 1 - yoffset, x); waddch(win, ' '); } } } } static void insertchar(win, c, x, y, mflag) WINDOW *win; char c; int x, y; char mflag; { int xend = -1, yend; char k, nlflag; nlflag = 0; while (c && x <= WINWIDE && y <= SCRHIGH) { k = screen[y][x]; screen[y][x] = c; if (inwin(y) && !nlflag) { wmove(win, y - yoffset, x); waddch(win, c >= ' ' ? c : ' '); } if (c == '\n') nlflag = 1; if (x < WINWIDE) x++; else { x = 0; y++; } c = k; if (xend == -1) { xend = x; yend = y; } } for (y = 0; y <= SCRHIGH; y++) for (x = 0; x <= WINWIDE; x++) if (screen[y][x] == '\n') fixnewline(win, x, y); if (mflag) { adjustwin(win, (yend + 1)); wmove(win, yend - yoffset + 1, 0); } else { adjustwin(win, yend); wmove(win, yend - yoffset, xend); } } static void edit(inp, out, mesg) char *inp, **out, *mesg; { int x, y, x1, y1, insert, cmdmode; char c; char str[(SCRHIGH + 1) * (WINWIDE + 1) + 1]; char *s; WINDOW *win; char edithelp[80]; char kstr[10]; char keystr[10]; dispedkey(edcmds[EDSAVE], keystr); if (keystr[0] == ']') sprintf(keystr, "ESC-%c", edcmds[EDSAVE] & 127); dispedkey(edcmds[EDABORT], kstr); if (keystr[0] == ']') sprintf(kstr, "ESC-%c", edcmds[EDABORT] & 127); sprintf(edithelp, EDHELP, keystr, mesg, kstr, mesg); notifyMessageAscii(edithelp); openwin(); cmplus = 0; cmminus = 0; insert = 1; cmdmode = 0; yoffset = 1; for (y = 0; y < SCRHIGH + 1; y++) for (x = 0; x < WINWIDE + 1; x++) { screen[y][x] = 0; } if (inp) { for (s = inp, x = y = 0; *s && (x <= WINWIDE) && (y <= SCRHIGH); s++) { c = screen[y][x] = *s; if (*s == '\n') { x = 0; y++; } else if (x < WINWIDE) x++; else { x = 0; y++; } } if (!(c == '\n') && !(x == WINWIDE && y == SCRHIGH)) screen[y][x] = '\n'; /* removed when comment is saved */ } adjustwin(win, 0); wmove(win, 0, 0); wrefresh(win); if (!screen[0][0]) screen[0][0] = '\n'; do { fixcursor(); c = getKeyEdit(); x = xpos(win); y = ypos(win) + yoffset; if (((edvi && !cmdmode) || !edvi) && (c >= ' ') && (c < 127)) { if (insert) insertchar(win, c, x, y, 0); else { if (screen[y][x] == '\n') insertchar(win, c, x, y, 0); else { screen[y][x] = c; waddch(win, c); } } wrefresh(win); } if (c == CTRLL) { doredraw(); wmove(win, y - yoffset, x); wrefresh(win); } if (!edvi && (c == edcmds[EDTINS])) /* toggle insert mode */ insert = !insert; if (edvi && cmdmode && (c == edcmds[EDTINS])) /* toggle cmdmode */ cmdmode = !cmdmode; if (edvi && !cmdmode && (c == ESC)) { /* toggle cmdmode */ cmdmode = !cmdmode; c = ' '; /* get rid of the ESC */ } if (((edvi && cmdmode) || !edvi) && (c == edcmds[EDDEOL])) { /* delete to end of line */ x1 = x; y1 = y; wmove(win, y - yoffset, x); wclrtoeol(win); for (; x <= WINWIDE; x++) screen[y][x] = 0; screen[y1][x1] = '\n'; adjustwin(win, y1); wmove(win, y1 - yoffset, x1); wrefresh(win); } if (((edvi && !cmdmode) || !edvi) && ((c == '\n') || (c == '\r'))) { /* newline, return */ if (y < SCRHIGH) insertchar(win, '\n', x, y, 1); else { int xsave; xsave = x; screen[y][x] = '\n'; waddch(win, ' '); for (x++; x <= WINWIDE; x++) { screen[y][x] = 0; waddch(win, ' '); } adjustwin(win, y); wmove(win, y - yoffset, xsave); } wrefresh(win); } if (((edvi && cmdmode) || !edvi) && (c == edcmds[EDDEL])) { /* Delete a character */ y1 = y; x1 = x; if (x1 < WINWIDE) { x1++; if (!screen[y1][x1]) { x1 = 0; y1++; } } else { x1 = 0; y1++; } deletechar(win, x, y, x1, y1); adjustwin(win, y); wmove(win, y - yoffset, x); wrefresh(win); } if (((edvi && cmdmode) || !edvi) && (c == '\b' || c == '\177') && (y || x)) { /* backspace */ y1 = y; x1 = x; if (x) x--; else { y--; for (x = WINWIDE; !screen[y][x]; x--); } deletechar(win, x, y, x1, y1); adjustwin(win, y); wmove(win, y - yoffset, x); wrefresh(win); } if (((edvi && cmdmode) || !edvi) && (c == edcmds[EDUP]) && (y)) { /* cursor up */ y--; for (; x > 0 && !screen[y][x]; x--); adjustwin(win, y); wmove(win, y - yoffset, x); wrefresh(win); } if (((edvi && cmdmode) || !edvi) && (c == edcmds[EDPUP])) { /* page up */ y = yoffset - 1; if (y < 0) y = 0; for (; x > 0 && !screen[y][x]; x--); adjustwin(win, y); wmove(win, y - yoffset, x); wrefresh(win); } if (((edvi && cmdmode) || !edvi) && (c == edcmds[EDBOC])) { /* beginning of comment */ y = x = 0; adjustwin(win, y); wmove(win, 0, 0); wrefresh(win); } if (((edvi && cmdmode) || !edvi) && (c == edcmds[EDDOWN]) && (y < SCRHIGH)) { /* cursor down */ y++; for (; x > 0 && !screen[y][x]; x--); if (!screen[y][x]) screen[y][x] = '\n'; adjustwin(win, y); wmove(win, y - yoffset, x); wrefresh(win); } if (((edvi && cmdmode) || !edvi) && (c == edcmds[EDPDOWN])) { /* page down */ y = yoffset + WINHIGH + 1; if (y > SCRHIGH) y = SCRHIGH; for (; y > 0 && !screen[y][0]; y--); for (; x > 0 && !screen[y][x]; x--); adjustwin(win, y); wmove(win, y - yoffset, x); wrefresh(win); } if (((edvi && cmdmode) || !edvi) && (c == edcmds[EDEOC])) { /* end of comment */ for (y = SCRHIGH; y > 0 && !screen[y][0]; y--); for (x = WINWIDE; x > 0 && !screen[y][x]; x--); adjustwin(win, y); wmove(win, y - yoffset, x); wrefresh(win); } if (((edvi && cmdmode) || !edvi) && (c == edcmds[EDLEFT]) && (y || x)) { /* cursor left */ if (x) x--; else { y--; x = WINWIDE; for (; x > 0 && !screen[y][x]; x--); } adjustwin(win, y); wmove(win, y - yoffset, x); wrefresh(win); } if (((edvi && cmdmode) || !edvi) && (c == edcmds[EDRIGHT]) && !((x == WINWIDE) && (y == SCRHIGH))) { /* cursor right */ if (x < WINWIDE) { x++; if (!screen[y][x]) { y++; x = 0; } } else { y++; x = 0; } for (; x > 0 && !screen[y][x]; x--); if (!screen[y][x]) screen[y][x] = '\n'; adjustwin(win, y); wmove(win, y - yoffset, x); wrefresh(win); } if (((edvi && cmdmode) || !edvi) && (c == edcmds[EDEOL])) { /* cursor to end of line */ for (x = WINWIDE; x > 0 && !screen[y][x]; x--); if (x < WINWIDE && screen[y][x] && screen[y][x] != '\n') x++; wmove(win, y - yoffset, x); wrefresh(win); } if (((edvi && cmdmode) || !edvi) && (c == edcmds[EDBOL])) { /* cursor to beginning * of line */ wmove(win, y - yoffset, 0); wrefresh(win); } } while ((((edvi && cmdmode) || !edvi) && (c != edcmds[EDSAVE]) && (c != edcmds[EDABORT]) && (c != ESC)) || (edvi && !cmdmode)); closewin(); notifyClearAscii(); if (c == edcmds[EDABORT]) *out = inp; else { for (y = SCRHIGH; y >= 0; y--) for (x = WINWIDE; x >= 0; x--) if ((screen[y][x] == 0) || (screen[y][x] == '\n')) screen[y][x] = 0; else y = x = 0; strcpy(str, ""); s = str; for (y = 0; y <= SCRHIGH; y++) for (x = 0; x <= WINWIDE && screen[y][x]; x++, s++) *s = screen[y][x]; *s = 0; if (inp) free(inp); *out = dupStr(str); } } static char *names[] = { " Size ", " Handicap ", " Komi ", " playerBlack ", " bLackrank ", " playerWhite ", " whIterank ", " Gamename ", " Event ", " rouNd ", " Date ", " Place ", " Time ", " Result ", " gameComment ", " sOurce ", " User " }; getInfoToChange() { static char convert[] = "SHBLWIGENDPTRCOUK"; static flag = 0; static char savearea[28][17]; static WINDOW *wi; static char didhelp = 0; char ch; int con; if (flag == 1) { flag = 0; return t_BlackRank; } if (flag == 2) { flag = 0; return t_WhiteRank; } notifyClearAscii(); notifyMessageAscii("Press capital letter to edit info field (? for list) or return to exit"); while (1) { ch = getKey(); if (ch == 'W') flag = 2; if (ch == 'B') flag = 1; if (ch == '?') { saveRegion(16, 3, 13, 17); for (ch = 0; ch < 17; ch++) mvaddstr(ch + 3, 16, names[ch]); refresh(); didhelp = 1; } if (ch == keys[C_COMMENTSCROLLDOWN]) { if (commentLine < commentLines() - COMMENT_HIGH) commentLine += COMMENT_HIGH - 1; showCommentAscii(commentLine); } else if (ch == keys[C_COMMENTSCROLLUP]) if (commentLine) { commentLine -= COMMENT_HIGH - 1; showCommentAscii(commentLine); } for (con = strlen(convert); con--;) if (ch == convert[con]) { notifyClearAscii(); return (int) t_Size + con; } if (ch == '\n' || ch == '\r' || ch == ESC) { notifyClearAscii(); if (didhelp) { restoreRegion(16, 3, 13, 17); didhelp = 0; } return (int) t_EOF; } } } static char *editName[] = {"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: "}; static void editInfo(in, out, prop) char *in, **out; Token prop; { if (prop == t_Size || prop == t_Handicap || prop == t_BlackRank || prop == t_WhiteRank || prop == t_Komi) { if (in) free(in); *out = (char *) malloc(21); getLine(editName[prop - FIRSTINFO + 2], *out, 20); } else edit(in, out, editName[prop - FIRSTINFO + 2]); } static void commentEdit(in, out) char *in, **out; { edit(in, out, "comment"); } interface asciiInterface = { (char *) 0, (char *) 0, (char *) 0, (pfi) initAscii, (pfi) closeAscii, (pfi) refreshAscii, (pfi) plotPieceAscii, (pfi) displayCommentAscii, (pfi) clearCommentAscii, (pfi) initBoardAscii, (pfi) clearScreenAscii, idleAscii, (pfi) drawTreeAscii, (pfi) highlightAscii, (pfi) readEnvAscii, (pfi) notifyMessageAscii, (pfi) notifyClearAscii, getLine, (pfi) setCursor, (pfi) plotMarkAscii, (pfi) drawPiece, getPointAscii, (pfi) commentEdit, askYNAscii, (pfi) notifyErrorAscii, (pfi) displayCommentAscii, getInfoToChange, (pfi) editInfo }; mgt-2.31/build.c100640 1750 1750 6705 6176731447 11353 0ustar memmem/* "mgt" Copyright (c) 1991 Shodan */ #include "mgt.h" int lastMoveX, lastMoveY, moveNum, lastTurn; coordList *lastletters = 0, *lastmarks; coordList *marks = 0; coordList *letters = 0; FUNCTION void clearLast() { lastMoveX = lastMoveY = -1; lastTurn = -1; moveNum = 0; curPlayer = t_Black; } FUNCTION void highlightLast() { (*io->highlightLast) (lastMoveX, lastMoveY, moveNum, lastTurn); } static void setLastMovePos(p) property *p; { Token player; if (p->t==t_Pass) player=p->data.player; else player=p->t; if (player==t_White){ lastTurn=1; curPlayer=t_Black;} else if (player==t_Black) {lastTurn=0;curPlayer=t_White;} else lastTurn= -1; if (p->t==t_Pass) lastMoveX = lastMoveY = PASSVAL; else if (p->data.stones) { lastMoveX = p->data.stones->x; lastMoveY = p->data.stones->y; } else lastMoveX = lastMoveY = -1; } FUNCTION void doPlace(p, b, t) property *p; pBoard b; piece t; { coordList *list; list = p->data.stones; while (list) { placeStone(b, list->x, list->y, t); list = list->next; } if (p->t == t_Black || p->t == t_White){ moveNum++; setLastMovePos(p); } } FUNCTION void doProps(p, b) property *p; pBoard b; { letters = NULL; marks = NULL; lastTurn= -1; while (p) { switch (p->t) { case t_White: BUG("t_White "); doPlace(p, b, P_WHITE); break; case t_Black: BUG("t_Black "); doPlace(p, b, P_BLACK); break; case t_AddWhite: BUG("t_AddWhite "); doPlace(p, b, P_WHITE); break; case t_AddBlack: BUG("t_AddBlack "); doPlace(p, b, P_BLACK); break; case t_AddEmpty: BUG("t_AddEmpty "); doPlace(p, b, P_NOTHING); break; case t_Comment: break; case t_Pass: moveNum++; setLastMovePos(p); break; case t_Mark: marks = p->data.stones; break; case t_Letter: letters = p->data.stones; BUG("t_Letter "); break; default: BUG("default "); } p = p->next; } } FUNCTION void doPropComment(n) nodep n; { property *p; if (p = getprop(n, t_Comment)) (*io->displayComment) (p->data.comment); } FUNCTION void buildTree0(n, b) nodep n; pBoard b; { BUG("parent >"); if (n) { buildTree0(n->parent, b); BUG("\nprops:"); doProps(n->p, b); } } FUNCTION void buildTree(n, b) nodep n; pBoard b; { prisoners[0] = 0; prisoners[1] = 0; boardClear(b); (*io->clearComment) (); BUG("buildTree:\n"); clearLast(); buildTree0(n, b); doPropComment(n); } FUNCTION void setPiece(b, i, j, p) pBoard b; int i, j; piece p; { boardSet(b, i, j, p); (*io->plotPiece) (b, i, j); } FUNCTION void updateBoard(dst, new) pBoard dst, new; /* update dst to look like new */ { int i, j; coordList *cl; for (cl = lastmarks; cl; cl = cl->next) (*io->plotPiece) (new, cl->x, cl->y); for (cl = lastletters; cl; cl = cl->next) (*io->plotPiece) (new, cl->x, cl->y); lastmarks = marks; lastletters = letters; for (i = boardsize; i--;) for (j = boardsize; j--;) { if (boardGet(new, i, j) != boardGet(dst, i, j)) { setPiece(dst, i, j, boardGet(new, i, j)); } } if (marks) { for (cl = marks; cl; cl = cl->next) (*io->plotMark) (new, cl->x, cl->y); marks = NULL; } if (letters) { for (i = 0, cl = letters; cl; cl = cl->next, i++) (*io->plotLetter) (cl->x, cl->y, (i % 26) + 'a'); letters = NULL; } } mgt-2.31/comment.c100640 1750 1750 3373 6176731447 11714 0ustar memmem/* "mgt" Copyright (c) 1991 Shodan */ #include "mgt.h" #include #include #define NEWBLOCK 20 typedef char clinetype[MAXCOMMENTWIDTH]; static int nlines = 0; int clines = 0; clinetype *cbuf = 0; char *empty = ""; FUNCTION char *commentGet(line) /* int */ int line; { if (cbuf && line < clines) return cbuf[line]; else return empty; } FUNCTION int commentLines() { return clines; } FUNCTION void formatComment(comment, width) char *comment; int width; { char *partstart, *dest, c; int len, partlen, wordlen; clines = 0; width = MIN(width, MAXCOMMENTWIDTH - 1); wordlen = partlen = len = 0; dest = *cbuf; if (*comment == '\n') comment++; partstart = comment; do { if (clines >= nlines) { nlines += NEWBLOCK; cbuf = (clinetype *) (cbuf ? realloc(cbuf, nlines * sizeof(clinetype)) : malloc(nlines * sizeof(clinetype))); if (!cbuf) barf("Memory allocation failure (formatComment)"); dest = cbuf[clines]; } c = *(comment++); len++; partlen++; wordlen++; if (c == ' ') wordlen = 0; else if (c == '\n' && *(comment - 2) == ' ' && *comment != '\n') { partlen--; len--; strncpy(dest, partstart, partlen); dest += partlen; partstart = comment; wordlen = partlen = 0; } else if (c == '\n' || !c) { strncpy(dest, partstart, partlen - 1); *(dest + partlen - 1) = 0; len = partlen = wordlen = 0; dest = cbuf[++clines]; partstart = comment; } if (len == width) { if (len == wordlen) wordlen = 0; else len = partlen - wordlen; strncpy(dest, partstart, len); partstart += len; *(dest + len) = 0; len = partlen = wordlen; dest = cbuf[++clines]; } } while (c); } mgt-2.31/doit.c100640 1750 1750 51530 6176731451 11222 0ustar memmem/* "mgt" Copyright (c) 1991 Shodan */ #include "mgt.h" int xcur, ycur; Token curPlayer; int change; int madechanges; int searchNodeNum; int ispl = 0; FUNCTION int okChange() { if (tutor) { (*io->notifyError) ("Can't edit in tutor mode."); return 0; } if ((!change) && ((*io->askYN) ("Modify tree", 0))) change = 1; if (change) madechanges = 1; return change; } FUNCTION int okExit(root) nodep root; { if (mailFlag) { if (madechanges) { if (!(*io->askYN) ("Save", 1)) { retVal = 1; return 1; } if (writeTree(saveName, root)) return 0; return 1; } retVal = 1; return 1; } if (madechanges) { if ((*io->askYN) ("Unsaved changes. Exit without saving", 0)) return 1; return 0; } return 1; } FUNCTION nodep search(n) /* return 0 on failure */ nodep n; { nodep s; if (!n || n->nodeNum == searchNodeNum) return n; s = search(child(n)); if (s && s->nodeNum == searchNodeNum) return s; s = search(nextSibling(n)); if (s && s->nodeNum == searchNodeNum) return s; return (nodep) 0; } FUNCTION void step(n, b) nodep n; pBoard b; { board temp; buildTree(n, &temp); updateBoard(b, &temp); (*io->drawTree) (n); (*io->refreshIO) (); highlightLast(); } FUNCTION void stepDown(n, b) nodep n; pBoard b; { board temp; (*io->clearComment) (); copyBoard(b, &temp); doProps(n->p, &temp); doPropComment(n); updateBoard(b, &temp); (*io->drawTree) (n); (*io->refreshIO) (); highlightLast(); } static char *color[] = { "Black", "White" }; int adjust(val, halfk, ksign) int val, halfk, ksign; { if (!halfk) return val; if (val * ksign >= 0) return val; return val + ksign; } FUNCTION void doScore(b, curNode) pBoard b; nodep curNode; { int savepris[2], lastpris[2]; char out[200]; command c; property *p; board new, old, last; int score[2], scored; char komicopy[10]; int intkomi, halfkomi, kptr, komisign, winner, diff; winner = -1; scored = 0; lastpris[1] = savepris[1] = prisoners[1]; lastpris[0] = savepris[0] = prisoners[0]; copyBoard(b, &old); copyBoard(b, &last); copyBoard(b, &new); (*io->notifyClear) (); (*io->notifyMessage) ("return score, space kill, u undo, q quit"); do { c = (command) (*io->getPoint) (); if (c == C_MOVE && (new.b[xcur][ycur] == P_WHITE || new.b[xcur][ycur] == P_BLACK) ) { if (scored) { scored = 0; copyBoard(&last, &new); prisoners[1] = lastpris[1]; prisoners[0] = lastpris[0]; } copyBoard(&new, &last); lastpris[1] = prisoners[1]; lastpris[0] = prisoners[0]; removeStones(&new, xcur, ycur); updateBoard(b, &new); } if (c == C_UNDO) { copyBoard(&last, &new); prisoners[1] = lastpris[1]; prisoners[0] = lastpris[0]; updateBoard(b, &new); } if (c == C_SCORE && !scored) { copyBoard(&new, &last); lastpris[1] = prisoners[1]; lastpris[0] = prisoners[0]; scoreBoard(&new, score); updateBoard(b, &new); if (info[t_Komi - FIRSTINFO]) { halfkomi = 0; for (kptr = 0; info[t_Komi - FIRSTINFO][kptr]; kptr++) { if (info[t_Komi - FIRSTINFO][kptr] == '.') { kptr++; if (info[t_Komi - FIRSTINFO][kptr] >= '1' && info[t_Komi - FIRSTINFO][kptr] <= '9') halfkomi = 1; break; } komicopy[kptr] = info[t_Komi - FIRSTINFO][kptr]; } komicopy[kptr] = 0; intkomi = atoi(komicopy); komisign = 0; if (komicopy[0] == '-' || intkomi < 0) komisign = -1; else if (intkomi > 0 || halfkomi) komisign = 1; sprintf(komicopy, "+ %s ", info[t_Komi - FIRSTINFO]); } else { komisign = intkomi = halfkomi = 0; strcpy(komicopy, ""); } diff = score[1] + prisoners[0] - score[0] - prisoners[1] + intkomi; if (!diff) { if (halfkomi) { if (komisign > 0) winner = 1; else if (komisign < 0) winner = 0; } else winner = 2; } else winner = diff > 0 ? 1 : 0; diff = adjust(diff, halfkomi, komisign); sprintf(out, "Black: %d + %d = %d\n\nWhite: %d + %d %s= %s%d%s\n\n", score[0], prisoners[1], score[0] + prisoners[1], score[1], prisoners[0], komicopy, (!diff) && halfkomi && (komisign == -1) ? "-" : "", adjust(score[1] + prisoners[0] + intkomi, halfkomi, komisign), halfkomi ? ".5" : ""); if (winner == 2) sprintf(out + strlen(out), "Tie game."); else sprintf(out + strlen(out), "%s wins by %d%s", color[winner], abs(diff), halfkomi ? ".5" : ""); (*io->clearComment) (); (*io->displayComment) (out); scored = 1; } } while (c != C_QUIT); if (scored && (*io->askYN) ("Keep comment", 1) && okChange()) replaceComment(curNode, out); else { (*io->clearComment) (); if (p = getprop(curNode, t_Comment)) (*io->displayComment) (p->data.comment); } prisoners[0] = savepris[0]; prisoners[1] = savepris[1]; (*io->notifyClear) (); updateBoard(b, &old); } static void initBoard(b) pBoard b; { extern coordList *lastmarks, *lastletters; boardClear(b); (*io->initializeBoard) (); lastletters = lastmarks = 0; } FUNCTION nodep loadFile(filename, root, b) char *filename; nodep root; board *b; { openfile(filename); if (input) { madechanges = change = 0; freeNode(root); initNodes(); readInit(); root = parse(0); fclose(input); if (!root) root = newNode(); initBoard(b); (*io->setCursor) (xcur, ycur); (*io->refreshIO) (); xcur = ycur = 0; } else (*io->notifyError) ("Unable to load file."); return root; } FUNCTION nodep makeTutor(nod, tok, x, y) nodep nod; Token tok; int x, y; { property *prop; if (!nod->child) return 0; nod = nod->child; while (!((prop = getprop(nod, tok)) && getCoord(x, y, prop->data.stones))) { if (!nod->nextSibling) return 0; nod = nod->nextSibling; } return nod; } static char *infotitle[] = { "Game name: ", "Event: ", "rouNd: ", "Date: ", "Place: ", "Time limit: ", "Result: ", "Comment: ", "sOurce: ", "User: ", "Komi: " }; static void showinfo() { char infoarray[4000]; char *infostr; int p; infostr = infoarray; sprintf(infostr, "Size: %d", boardsize); while (*infostr) infostr++; if (info[(int) t_Komi - FIRSTINFO]) { sprintf(infostr, " Komi: %s", info[(int) t_Komi - FIRSTINFO]); while (*infostr) infostr++; } if (handicap) { sprintf(infostr, " Handicap: %d", handicap); while (*infostr) infostr++; } *infostr = '\n'; infostr++; if (info[0] || info[1]) { sprintf(infostr, "Black: %s%s%s\n", info[0] ? info[0] : "", info[0] && info[1] ? ", " : "", info[1] ? info[1] : ""); while (*infostr) infostr++; } if (info[2] || info[3]) { sprintf(infostr, "White: %s%s%s\n", info[2] ? info[2] : "", info[2] && info[3] ? ", " : "", info[3] ? info[3] : ""); while (*infostr) infostr++; } for (p = 0; p <= LASTINFO - FIRSTINFO - 4; p++) { if (info[p + 4]) { sprintf(infostr, "%s%s\n", infotitle[p], info[p + 4]); while (*infostr) infostr++; } } *infostr = 0; (*io->displayInfo) (infoarray); } #define BUFFERSIZE 50 static int doinfo() { Token change; int sizechanged, value; char buffer[BUFFERSIZE + 1]; char *current; sizechanged = 0; do { showinfo(); change = (Token) (*io->getInfoToChange) (); if (change == t_EOF) break; if (!okChange()) continue; if (change == t_Size) { sprintf(buffer, "%d", boardsize); current = dupStr(buffer); (*io->editInfo) (current, ¤t, t_Size); if (current) { value = atoi(current); if (value > 1 && value < 20) { if (value != boardsize) sizechanged = 1; boardsize = value; } free(current); } } else if (change == t_Handicap) { sprintf(buffer, "%d", handicap); current = dupStr(buffer); (*io->editInfo) (current, ¤t, t_Handicap); if (current) { handicap = atoi(current); free(current); } } else { (*io->editInfo) (info[(int) change - FIRSTINFO], &info[(int) change - FIRSTINFO], change); if (!strlen(info[(int) change - FIRSTINFO])) { free(info[(int) change - FIRSTINFO]); info[(int) change - FIRSTINFO] = 0; } } } while (1); return sizechanged; } static void savescreen(bord) board *bord; { char fname[75]; int i, j; FILE *out; extern coordList *lastletters; coordList *let; char local[19][19]; if ((*io->queryStr) ("Save screen: ", fname, 74)) { if (out = fopen(fname, "a+t")) { fprintf(out, "%s to play.\n\n", curPlayer == t_Black ? "Black" : "White"); fputs(" ", out); for (i = 0; i < boardsize; i++) { fputc(' ', out); fputc(i + 'A' + ((i + 'A' >= 'I') ? 1 : 0), out); } fputc('\n', out); for (j = 0; j < boardsize; j++) for (i = 0; i < boardsize; i++) { local[i][j] = ' '; switch (bord->b[i][j]) { case P_WHITE: local[i][j] = 'O'; break; case P_BLACK: local[i][j] = '#'; break; case P_NOTHING: default: local[i][j] = '.'; break; } } let = lastletters; i = 0; while (let) { local[let->x][let->y] = i + 'a'; i++; i %= 26; let = let->next; } for (j = 0; j < boardsize; j++) { fprintf(out, "%2d ", boardsize - j); for (i = 0; i < boardsize; i++) { fputc(local[i][j], out); fputc(' ', out); } fprintf(out, "%2d", boardsize - j); if ( (j == boardsize / 2) && (prisoners[0] || prisoners[1])) fprintf(out, " Captured #: %d Captured O: %d", prisoners[0], prisoners[1]); fputc('\n', out); } fputs(" ", out); for (i = 0; i < boardsize; i++) { fputc(' ', out); fputc(i + 'A' + ((i + 'A' >= 'I') ? 1 : 0), out); } fputs("\n\n", out); for (i = 0; i < commentLines(); i++) { fputs(commentGet(i), out); putc('\n', out); } fclose(out); } else (*io->notifyError) ("Unable to open file."); } } FUNCTION void doit() { int quitflg, i; nodep root, curNode; board theBoard; extern coordList *lastletters, *lastmarks; curPlayer = t_Black; xcur = ycur = quitflg = 0; root = 0; madechanges = 0; change = 1; if (input != stdin) { root = parse(0); fclose(input); change = 0; } if (!root) root = newNode(); curNode = root; initBoard(&theBoard); (*io->setCursor) (xcur, ycur); (*io->refreshIO) (); if (mailFlag) { while (curNode->child) curNode = treeDown(curNode); change = 1; } step(curNode, &theBoard); while (!quitflg) { nodep tNode; command c; property *prop; if (prop = getprop(curNode, t_Player)) { curPlayer = prop->data.player; ispl = 1; } else ispl = 0; c = (command) (*io->idle) (curNode); if ((int) c >= (int) C_CHOSECHILD && (int) c < (int) C_NEXTCMD) { nodep new; new = nthChild(curNode, (int) c - (int) C_CHOSECHILD); if (new) { curNode = nthChild(curNode, (int) c - (int) C_CHOSECHILD); step(curNode, &theBoard); } } else switch (c) { case C_LOAD: if (okExit(root)) { char filename[50]; if ((*io->queryStr) ("Load file? ", filename, 48)) { root = curNode = loadFile(filename, root, &theBoard); step(curNode, &theBoard); } } break; case C_BACKFILE: if (currentfile > 0 && okExit(root)) { currentfile--; root = curNode = loadFile(files[currentfile], root, &theBoard); step(curNode, &theBoard); } else (*io->notifyError) ("No previous file."); break; case C_NEXTFILE: if (currentfile + 1 < filecount && okExit(root)) { currentfile++; root = curNode = loadFile(files[currentfile], root, &theBoard); step(curNode, &theBoard); } else (*io->notifyError) ("No next file."); break; case C_INFO: if (doinfo()) initBoard(&theBoard); step(curNode, &theBoard); if (xcur >= boardsize) xcur = boardsize - 1; if (ycur >= boardsize) ycur = boardsize - 1; break; case C_SAVESCREEN: savescreen(&theBoard); break; case C_REDRAW: { int savex, savey; savex = xcur; savey = ycur; initBoard(&theBoard); (*io->refreshIO) (); step(curNode, &theBoard); xcur = savex; ycur = savey; break; } case C_NOTHING: break; case C_TOPLAY: if (okChange()) addPlayer(curNode, (curPlayer == t_Black) ? t_White : t_Black); break; case C_PASSMOVE:if (okChange()){ int mod_cur_node; mod_cur_node = passMove(curNode, curPlayer); if (mod_cur_node) step(curNode, &theBoard); else { curNode = treeDown(curNode); stepDown(curNode, &theBoard); } } break; case C_TOGGLESTONE: curPlayer = (curPlayer == t_Black) ? t_White : t_Black; break; case C_TUTORSWAP: tutor = !tutor; break; case C_MOVE: if (tutor) { nodep save; save = curNode; if (curNode = makeTutor(curNode, curPlayer, xcur, ycur)) { step(curNode, &theBoard); } else { (*io->notifyError) ("Wrong move."); curNode = save;; } } else { if (okChange() && legal(&theBoard, curNode, curPlayer, xcur, ycur)) { int mod_cur_node; mod_cur_node = makeMove(curNode, curPlayer, xcur, ycur); if (mod_cur_node) step(curNode, &theBoard); else { curNode = treeDown(curNode); stepDown(curNode, &theBoard); } } } break; case C_ADDVAR: if (okChange()) { makeVariation(curNode); step(curNode, &theBoard); } break; case C_DELNODE: if (okChange()) { deleteNode(&curNode); step(curNode, &theBoard); } break; case C_PASTE: if (okChange()) if (pasteTree(curNode)) step(curNode, &theBoard); else (*io->notifyError) ("Nothing to paste."); break; case C_TREECUT: if (okChange()) { nodep prevNode; int savex, savey; savex = xcur; savey = ycur; prevNode = curNode->parent; cutTree(curNode); curNode = prevNode; if (!curNode) { initNodes(); root = curNode = newNode(); } step(curNode, &theBoard); xcur = savex; ycur = savey; break; } case C_ADDBLACK: if (okChange()) { coordList *cl; property *prop; if (boardGet(&theBoard, xcur, ycur) == P_BLACK) { addStone(curNode, t_AddEmpty, xcur, ycur); setPiece(&theBoard, xcur, ycur, P_NOTHING); } else { addStone(curNode, t_AddBlack, xcur, ycur); setPiece(&theBoard, xcur, ycur, P_BLACK); } if (prop = getprop(curNode, t_Letter)) lastletters = prop->data.stones; for (i = 0, cl = lastletters; cl; i++, cl = cl->next) (*io->plotLetter) (cl->x, cl->y, i % 26 + 'a'); } break; case C_ADDWHITE: if (okChange()) { coordList *cl; property *prop; if (boardGet(&theBoard, xcur, ycur) == P_WHITE) { addStone(curNode, t_AddEmpty, xcur, ycur); setPiece(&theBoard, xcur, ycur, P_NOTHING); } else { addStone(curNode, t_AddWhite, xcur, ycur); setPiece(&theBoard, xcur, ycur, P_WHITE); } if (prop = getprop(curNode, t_Letter)) lastletters = prop->data.stones; for (i = 0, cl = lastletters; cl; i++, cl = cl->next) (*io->plotLetter) (cl->x, cl->y, i % 26 + 'a'); } break; case C_ADDLETTER: if (okChange()) { int sx, sy; for (; lastletters; lastletters = lastletters->next) (*io->plotPiece) (&theBoard, lastletters->x, lastletters->y); lastletters = 0; sx = xcur; sy = ycur; if (addMark(curNode, t_Letter, xcur, ycur)) (*io->plotPiece) (&theBoard, xcur, ycur); stepDown(curNode, &theBoard); xcur = sx; ycur = sy; } break; case C_ADDMARK: if (okChange()) { int sx, sy; for (; lastmarks; lastmarks = lastmarks->next) (*io->plotPiece) (&theBoard, lastmarks->x, lastmarks->y); lastmarks = 0; sx = xcur; sy = ycur; if (addMark(curNode, t_Mark, xcur, ycur)) (*io->plotPiece) (&theBoard, xcur, ycur); stepDown(curNode, &theBoard); xcur = sx; ycur = sy; } break; case C_EDCOMMENT: if (okChange()) { edComment(curNode); step(curNode, &theBoard); } break; case C_ADDNAME: if (okChange()) { makeName(curNode); step(curNode, &theBoard); } break; case C_DOWN: tNode = treeDown(curNode); if (tNode != curNode) { curNode = tNode; stepDown(curNode, &theBoard); } break; case C_UP: curNode = treeUp(curNode); step(curNode, &theBoard); break; case C_WALKDOWN: tNode = treeNext(curNode); if (tNode->parent == curNode) { stepDown(tNode, &theBoard); } else { step(tNode, &theBoard); } curNode = tNode; break; case C_WALKUP: curNode = treeLast(curNode); step(curNode, &theBoard); break; case C_SEARCHCOMMENT: { nodep tBegin; tBegin = curNode; tNode = curNode; do { tNode = treeNext(tNode); } while (tNode != tBegin && !getprop(tNode, t_Comment)); if (tNode != curNode) { if (tNode->parent == curNode) { stepDown(tNode, &theBoard); } else { step(tNode, &theBoard); } curNode = tNode; } } break; case C_SEARCHBACKCOMMENT: tNode = curNode; curNode = curNode; do { curNode = treeLast(curNode); } while (curNode != tNode && !getprop(curNode, t_Comment)); step(curNode, &theBoard); break; case C_UPFORK: while (curNode->parent) { curNode = curNode->parent; if (treeCountSiblings(curNode) > 1) break; } step(curNode, &theBoard); break; case C_DOWNFORK: { while (curNode->child) { curNode = treeDown(curNode); if (treeCountSiblings(curNode) > 1) break; } step(curNode, &theBoard); } break; case C_END: while (curNode->child) { curNode = treeDown(curNode); } step(curNode, &theBoard); break; case C_BEGINNING: curNode = root; step(curNode, &theBoard); break; case C_SCORE: doScore(&theBoard, curNode); break; case C_GOTO: { char buf[7]; nodep new; if ((*io->queryStr) ("Move to node # ?", buf, 5)) { searchNodeNum = atoi(buf); if (searchNodeNum == 0 && strcmp(buf, "0")) searchNodeNum = -1; if (searchNodeNum >= 0) { if (new = search(root)) { curNode = new; step(curNode, &theBoard); (*io->notifyClear) (); } else { (*io->notifyClear) (); (*io->notifyError) ("Node not found."); } } } } break; case C_QUIT: if (okExit(root)) quitflg++; break; case C_WRITE: { char filename[50]; if ((*io->queryStr) ("Save name? ", filename, 48)) { if (!strcmp("*", filename)) { if (!writeTree(name_buf, root)) madechanges = 0; } else { if (!writeTree(filename, root)) madechanges = 0; } } } break; case C_SAVESHORT: saveShort = !saveShort; break; case C_CURLEFT: xcur = (xcur - 1 + boardsize) % boardsize; (*io->setCursor) (xcur, ycur); (*io->refreshIO) (); break; case C_CURRIGHT: xcur = (xcur + 1) % boardsize; (*io->setCursor) (xcur, ycur); (*io->refreshIO) (); break; case C_CURUP: ycur = (ycur - 1 + boardsize) % boardsize; (*io->setCursor) (xcur, ycur); (*io->refreshIO) (); break; case C_CURDOWN: ycur = (ycur + 1) % boardsize; (*io->setCursor) (xcur, ycur); (*io->refreshIO) (); break; case C_UPLEFT: ycur = (ycur - 1 + boardsize) % boardsize; xcur = (xcur - 1 + boardsize) % boardsize; (*io->setCursor) (xcur, ycur); (*io->refreshIO) (); break; case C_UPRIGHT: xcur = (xcur + 1) % boardsize; ycur = (ycur - 1 + boardsize) % boardsize; (*io->setCursor) (xcur, ycur); (*io->refreshIO) (); break; case C_DOWNLEFT: xcur = (xcur - 1 + boardsize) % boardsize; ycur = (ycur + 1) % boardsize; (*io->setCursor) (xcur, ycur); (*io->refreshIO) (); break; case C_DOWNRIGHT: xcur = (xcur + 1) % boardsize; ycur = (ycur + 1) % boardsize; (*io->setCursor) (xcur, ycur); (*io->refreshIO) (); break; } } } mgt-2.31/edit.c100640 1750 1750 23306 6176731452 11211 0ustar memmem/* "mgt" Copyright (c) 1991 Shodan */ #include "mgt.h" int first; nodep buffer = 0; FUNCTION void writeStrEscaped(output, s) FILE *output; char *s; { while (*s) { if (*s == ')' || *s == '(' || *s == ']' || *s == '[') fputc('\\', output); fputc(*(s++), output); } } #define WRITE(short,long) if (saveShort) fputs(short,output);else fputs(long,output) static char *infoshort[] = {"PB", "BR", "PW", "WR", "GN", "EV", "RO", "DT", "PC", "TM", "RE", "GC", "SO", "US", "KM"}; static char *infolong[] = { "PlayerBlack", "BlackRank", "PlayerWhite", "WhiteRank", "GameName", "EVent", "ROund", "DaTe", "PlaCe", "TiMe", "REsult", "GameComment", "SOurce", "USer", "KoMi"}; static void writeFirst(output) FILE *output; { int p; if (saveShort) { fprintf(output, "FF[1]GM[1]VW[]SZ[%d]", boardsize); if (handicap) fprintf(output, "HA[%d]", handicap); } else { fprintf(output, "FileFormat[1]GaMe[1]\nVieW[]\nSiZe[%d]\n", boardsize); if (handicap) fprintf(output, "HAndicap[%d]\n", handicap); } for (p = 0; p <= t_Komi - FIRSTINFO; p++) { if (info[p]) { WRITE(infoshort[p], infolong[p]); fputc('[', output); writeStrEscaped(output, info[p]); WRITE("]", "]\n"); } } } FUNCTION void writeNode(output, n) FILE *output; nodep n; { property *prop; char str[1445]; WRITE(";", ";\n"); if (first) { writeFirst(output); first = 0; } prop = n->p; while (prop) { switch (prop->t) { case t_AddBlack: if (writeCoordList(prop->data.stones, str)) { WRITE("AB", "AddBlack"); fputs(str, output); } break; case t_AddWhite: if (writeCoordList(prop->data.stones, str)) { WRITE("AW", "AddWhite"); fputs(str, output); } break; case t_White: if (writeCoordList(prop->data.stones, str)) { WRITE("W", "White"); fputs(str, output); } break; case t_Black: if (writeCoordList(prop->data.stones, str)) { WRITE("B", "Black"); fputs(str, output); } break; case t_AddEmpty: if (writeCoordList(prop->data.stones, str)) { WRITE("AE", "AddEmpty"); fputs(str, output); } break; case t_Mark: if (writeCoordList(prop->data.stones, str)) { WRITE("M", "Mark"); fputs(str, output); } break; case t_Letter: if (writeCoordList(prop->data.stones, str)) { WRITE("L", "Letter"); fputs(str, output); } break; case t_Name: if (strlen(prop->data.comment)) { WRITE("N[", "Name["); writeStrEscaped(output, prop->data.comment); WRITE("]", "]\n"); } break; case t_Pass: if (prop->data.player == t_Black) WRITE("B", "Black"); else WRITE("W", "White"); WRITE("[tt]", "[tt]\n"); break; case t_Player: WRITE("PL[", "PLayer["); if (prop->data.player == t_Black) fputc('B', output); else fputc('W', output); WRITE("]", "]\n"); break; case t_Comment: if (strlen(prop->data.comment)) { WRITE("C[", "Comment["); writeStrEscaped(output, prop->data.comment); WRITE("]", "]\n"); } break; } prop = prop->next; } } FUNCTION void WriteSubTree(output, root, sib) FILE *output; nodep root; int sib; { WRITE("(", "(\n"); do { if (sib && root->nextSibling) { WriteSubTree(output, root, 0); while (root->nextSibling) { root = root->nextSibling; WriteSubTree(output, root, 0); } root = NULL; } else { writeNode(output, root); root = root->child; sib = 1; } } while (root); WRITE(")", ")\n"); } FUNCTION int writeCoordList(list, str) coordList *list; char *str; { *str = 0; while (list) { sprintf(str + strlen(str), "[%c%c]", list->x + 'a', list->y + 'a'); list = list->next; } if (!(strlen(str))) return 0; if (!saveShort) strcat(str, "\n"); return 1; } FUNCTION int writeTree(name, root) char *name; nodep root; { FILE *output; if (output = fopen(name, "w")) { first = 1; WriteSubTree(output, root, 1); fclose(output); return 0; } else { (*io->notifyError) ("Error saving file."); return 1; } } static void clearSpace(prop, x, y) property *prop; int x, y; { while (prop) { switch (prop->t) { case t_AddEmpty: case t_AddBlack: case t_AddWhite: case t_Black: case t_White: case t_Mark: case t_Letter: clearCoord(x, y, &(prop->data.stones)); break; } prop = prop->next; } } FUNCTION int addMark(n, t, x, y) nodep n; Token t; int x, y; { property *prop; if (prop = getprop(n, t)) { if ((getCoord(x, y, prop->data.stones))) { clearCoord(x, y, &(prop->data.stones)); return 1; } } else { prop = (property *) malloc(sizeof(property)); if (!prop) barf("Memory allocation failure (markStone)"); prop->next = n->p; n->p = prop; prop->data.stones = 0; prop->t = t; } setCoord(x, y, &(prop->data.stones)); return 0; } FUNCTION void addStone(n, t, x, y) nodep n; Token t; int x, y; { property *prop; clearSpace(n->p, x, y); if (!(prop = getprop(n, t))) { prop = (property *) calloc(1, sizeof(property)); if (!prop) barf("Memory allocation failure (addStone)"); prop->next = n->p; n->p = prop; prop->data.stones = 0; prop->t = t; } setCoord(x, y, &(prop->data.stones)); } FUNCTION int makeMove(n, t, x, y) nodep n; Token t; int x, y; { nodep new; property *prop; int ret; ret = 0; if (!(n->p)) { new = n; ret = 1; } else { new = newNode(); if (n->child) n->child->parent = new; new->parent = n; new->child = n->child; n->child = new; } prop = (property *) calloc(1, sizeof(property)); if (!prop) barf("Memory allocation failure (makeMove)"); new->p = prop; prop->data.stones = 0; prop->t = t; setCoord(x, y, &(prop->data.stones)); return ret; } FUNCTION int passMove(n, t) nodep n; Token t; { nodep new; property *prop; int ret; ret = 0; if (!(n->p)) { new = n; ret = 1; } else { new = newNode(); if (n->child) n->child->parent = new; new->parent = n; new->child = n->child; n->child = new; } prop = (property *) calloc(1, sizeof(property)); if (!prop) barf("Memory allocation failure (passMove)"); new->p = prop; prop->data.player = t; prop->t = t_Pass; return ret; } FUNCTION void addPlayer(n, t) nodep n; Token t; { property *prop; if (!(prop = getprop(n, t_Player))) { prop = (property *) calloc(1, sizeof(property)); if (!prop) barf("Memory allocation failure (addPlayer)"); addprop(n, prop); } prop->data.player = t; prop->t = t_Player; } FUNCTION void makeVariation(n) nodep n; { nodep new, last; if (!(n->child)) { new = newNode(); new->parent = n; n->child = new; } else { new = newNode(); new->parent = n; last = treeLastSibling(n->child); last->nextSibling = new; new->lastSibling = last; } } FUNCTION void cutTree(n) nodep n; { freeNode(buffer); if (n->nextSibling) n->nextSibling->lastSibling = n->lastSibling; if (n->lastSibling) n->lastSibling->nextSibling = n->nextSibling; else if (n->parent) n->parent->child = n->nextSibling; n->nextSibling = 0; n->lastSibling = 0; buffer = n; } FUNCTION boolean pasteTree(n) nodep n; { nodep last, sib; if (buffer) { for (last = buffer; last->child; last = last->child); if (n->child) { n->child->parent = last; for (sib = n->child->nextSibling; sib; sib = sib->nextSibling) sib->parent = last; last->child = n->child; } n->child = buffer; buffer->parent = n; buffer = (nodep) 0; return true; } return false; } FUNCTION void edComment(n) nodep n; { property *prop; if (!(prop = getprop(n, t_Comment))) { prop = (property *) calloc(1, sizeof(property)); prop->t = t_Comment; prop->next = n->p; n->p = prop; } (*io->editComment) (prop->data.comment, &(prop->data.comment)); if (!(prop->data.comment)) { n->p = prop->next; free(prop); } } FUNCTION void deleteNode(n) nodep *n; { nodep last; if (!((*n)->child)) { freeProps(*n); (*n)->p = 0; } else { if ((*n)->parent && (*n)->parent->child == *n) (*n)->parent->child = (*n)->child; if ((*n)->lastSibling) { (*n)->child->lastSibling = (*n)->lastSibling; (*n)->lastSibling->nextSibling = (*n)->child; } /* new parent for all of child's sibs */ for (last = (*n)->child; last->nextSibling; last = last->nextSibling) last->parent = (*n)->parent; last->parent = (*n)->parent; /* Last of child's sibs get's to point to next sib of main node */ last->nextSibling = (*n)->nextSibling; if ((*n)->nextSibling) (*n)->nextSibling = last; last = *n; *n = (*n)->child; delNode(last); } } FUNCTION void makeName(n) nodep n; { char newname[41]; property *prop; (*io->queryStr) ("Name: ", newname, 40); if (prop = getprop(n, t_Name)) free(prop->data.comment); else { prop = (property *) calloc(1, sizeof(property)); addprop(n, prop); prop->t = t_Name; } prop->data.comment = dupStr(newname); } FUNCTION void replaceComment(n, str) nodep n; char *str; { property *prop; if (!(prop = getprop(n, t_Comment))) { prop = (property *) calloc(1, sizeof(property)); prop->t = t_Comment; prop->next = n->p; n->p = prop; } else free(prop->data.comment); prop->data.comment = dupStr(str); } mgt-2.31/help.c100640 1750 1750 2240 6176731440 11163 0ustar memmem/* "mgt" Copyright (c) 1991 Shodan */ /* Short help strings. Don't make any of these longer than the longest one * already present */ char *helpStr[] = { "Quit mgt", "Move forward", "Move backward", "Next node", "Previous node", "End of the current variation", "Beginning of file", "Next comment", "Previous comment", "Next variation branch", "Last variation branch", "Jump to a specific node number", "Write Smart-Go file", "Set black stone", "Set white stone", "Make variation", "Cut tree into buffer", "Add letter", "Add mark", "Load new file", "Paste buffer in", "Edit comment", "Delete current node", "Name the current node", "Score the game", "Pass move", "Other player's turn (permanent)", "Toggle stone", "Reverse through files", "Forward through files", "Redraw screen", "Toggle save format", "Toggle tutor mode", "Save screen image", "Show game info", "Make a move", "Cursor down left", "Cursor down", "Cursor down right", "Cursor left", "Cursor right", "Cursor up left", "Cursor up", "Cursor up right", "___last command marker___"}; mgt-2.31/mgt.c100640 1750 1750 6635 6176731453 11042 0ustar memmem/* "mgt" Copyright (c) 1991 Shodan */ #include #include "mgt.h" int retVal = 0; interface *io; /* current interface routines */ int boardsize; /* global for board size */ char *info[LASTINFO - FIRSTINFO + 2]; int handicap; char *commentBuf; /* pointer to current node's comment */ extern interface asciiInterface; int prisoners[2]; FILE *input = 0; char name_buf[512]; char *files[MAX_FILES]; int filecount, currentfile; #ifdef DEBUG FILE *debug; unsigned long totalmemory; #endif #ifdef MGT_IBM extern unsigned _stklen = 32000; #endif typedef struct { char *arg; int *flag; char **str; } argType; int mailFlag = 0; int saveShort = 0; int tutor = 0; char *saveName; static argType argTable[] = { {"-m", &mailFlag, &saveName}, {"-s", &saveShort, NULL}, {"-t", &tutor, NULL} }; FUNCTION main(argc, argv) int argc; char **argv; { #ifdef DEBUG debug = fopen("debug", "w"); #endif io = &asciiInterface; input = stdin; init(argv, &argc); parseLine(argc, argv); doit(); myexit(); } FUNCTION void die() { signal(SIGINT, SIG_DFL); myexit(); } FUNCTION void myexit() { (*io->clearScreen) (); (*io->refreshIO) (); (*io->close) (); printf("Thank you for using mgt\n"); exit(retVal); } FUNCTION void openfile(f) char *f; { #ifdef MGT_LIB static char game_lib[] = MGT_LIB; #endif /* MGT_LIB */ strcpy(name_buf, f); if (!(input = fopen(f, "r"))) strcpy(name_buf, ""); #ifdef MGT_LIB /* if not in local directory, try library */ if (!input) { strcpy(name_buf, game_lib); strcat(name_buf, f); input = fopen(name_buf, "r"); } #endif /* MGT_LIB */ } FUNCTION void barf(s) char *s; { int i; for (i = 24; i--;) fprintf(stderr, "\n"); fprintf(stderr, "%s\n", s); exit(1); } FUNCTION void initEnv() { extern char *getenv(); char *env; if (env = getenv("MGT")) while (*env) { while (*env && *env != '_') env++; if (*env) env++; if (*env) (*io->readEnv) (&env); } } FUNCTION void init(argv, argc) char *argv[]; int *argc; { initEnv(); (*io->open) (argv, argc); signal(SIGINT, die); readInit(); } FUNCTION void helpCommandLine(errMesg) char *errMesg; { (*io->close) (); fprintf(stderr, "\nERROR: %s\n\n", errMesg); fprintf(stderr, " MGT %s\n", VERSION); fprintf(stderr, "\nUsage: mgt [opts] [files]\n"); fprintf(stderr, "[opts] is any of:\n"); fprintf(stderr, "-m filename mail mode. Autosave on quit.\n"); fprintf(stderr, "-s use short format when saving.\n\n"); exit(2); } FUNCTION void parseLine(argc, argv) int argc; char **argv; { int i; filecount = 0; while (++argv, --argc > 0) { if (**argv != '-') { files[filecount++] = *argv; if (filecount == MAX_FILES) helpCommandLine("Too many files specified"); } else { for (i = 0; i < sizeof(argTable) / sizeof(argType); i++) if (!strcmp(argTable[i].arg, *argv)) { if (argTable[i].str) if (--argc) *(argTable[i].str) = (*++argv); else helpCommandLine("String expected on option"); (*(argTable[i].flag))--; break; } if (i == sizeof(argTable) / sizeof(argType)) helpCommandLine("Bad option"); } } if (!filecount) input = stdin; else { currentfile = 0; openfile(files[0]); if (!input) helpCommandLine("File not found"); } } mgt-2.31/mou.c100640 1750 1750 60077 6176731444 11073 0ustar memmem/***************************************************************************** * PROJECT: Mouse routines with 'real' graphic cursor in text mode. ***************************************************************************** * MODULE: MOU.C ***************************************************************************** * DESCRIPTION: * Main file for the mouse routines. * ***************************************************************************** * MODIFICATION NOTES: * Date Version Author Comment * 15-Mar-1991 1.04 dk Added function to set mouse position. From a * suggestion by Gary Tepel. * 17-Jan-1991 1.02 ta Diffs sent to me from Tony Acero for middle * mouse button support. * 10-Jan-1991 1.01 dk Made points variable global throughout module. * 07-Jan-1991 1.00 dk Fixed bugs and set up for release to Usenet. * 26-Oct-1990 0.00 dk Initial file. ***************************************************************************** * * DISCLAIMER: * * Programmers may incorporate any or all code into their programs, * giving proper credit within the source. Publication of the * source routines is permitted so long as proper credit is given * to Dave Kirsch. * * Copyright (C) 1990, 1991 by Dave Kirsch. You may use this program, or * code or tables extracted from it, as desired without restriction. * I can not and will not be held responsible for any damage caused from * the use of this software. * * Author: a563@mindlink.UUCP -or- Zoid@cc.sfu.ca * ***************************************************************************** * This source works with Turbo C 2.0 and MSC 6.0 and above. *****************************************************************************/ #ifdef __TURBOC__ #pragma inline #endif #include #include #include #include #include "mou.h" #define HEIGHT 16 int vgapresent=0; word mousehidden = 0; /* Is the mouse on? Additive flag */ mouseboolean mouseinstalled = FALSE; /* Is the mouse installed? */ volatile word mousex=0, mousey=0; /* Character position of mouse */ #ifndef __TURBOC__ STATIC word _based(_segname("_CODE")) DGroupSeg; #endif STATIC volatile word mbufin = 0, mbufout = 0; /* Mouse buffer pointers */ STATIC word mousefreeze = 0; /* Is mouse frozen in place? */ STATIC MOUINFOREC mbuf[MOUSEBUFFERSIZE]; /* Mouse buffer */ /* Save information for non EGA/VGA */ STATIC word oldword; STATIC word newword; STATIC mouseboolean saved = FALSE; STATIC word oldmx, oldmy; /* Save information for EGA/VGA displays */ mouseboolean egavga = FALSE; /* Do we have an EGA/VGA adapter? */ STATIC byte savechars[3][3]; /* The saved characters we overwrote */ STATIC dword mousecursormask[HEIGHT] = { 0x00000000L, /*0000000000000000*/ 0x40000000L, /*0100000000000000*/ 0x60000000L, /*0110000000000000*/ 0x70000000L, /*0111000000000000*/ 0x78000000L, /*0111100000000000*/ 0x7c000000L, /*0111110000000000*/ 0x7e000000L, /*0111111000000000*/ 0x7f000000L, /*0111111100000000*/ 0x7f800000L, /*0111111110000000*/ 0x7f000000L, /*0111111100000000*/ 0x7c000000L, /*0111110000000000*/ 0x46000000L, /*0100011000000000*/ 0x06000000L, /*0000011000000000*/ 0x03000000L, /*0000001100000000*/ 0x03000000L, /*0000001100000000*/ 0x00000000L /*0000000000000000*/ }; STATIC dword mousescreenmask[HEIGHT] = { 0x3fffffffL, /*0011111111111111*/ 0x1fffffffL, /*0001111111111111*/ 0x0fffffffL, /*0000111111111111*/ 0x07ffffffL, /*0000011111111111*/ 0x03ffffffL, /*0000001111111111*/ 0x01ffffffL, /*0000000111111111*/ 0x00ffffffL, /*0000000011111111*/ 0x007fffffL, /*0000000001111111*/ 0x003fffffL, /*0000000000111111*/ 0x007fffffL, /*0000000001111111*/ 0x01ffffffL, /*0000000111111111*/ 0x10ffffffL, /*0001000011111111*/ 0xb0ffffffL, /*1011000011111111*/ 0xf87fffffL, /*1111100001111111*/ 0xf87fffffL, /*1111100001111111*/ 0xfcffffffL /*1111110011111111*/ }; STATIC byte chardefs[32 * 9]; /* 9 character definitons. */ STATIC word mousepx, mousepy; /* Mouse pixel coordinates */ STATIC mouseboolean conditionalhidemouse = FALSE; STATIC word conx1, cony1, conx2, cony2; STATIC word vseg; /* Segment of video ram. */ STATIC word mcols, mrows; STATIC byte savevmode; STATIC word points; STATIC word maxx, maxy; STATIC mouseboolean desqview = FALSE; #define POKEATTRIB(x, y, a) pokeb(vseg, (y) * (mcols * 2) + ((x) << 1) + 1, a) #define PEEKATTRIB(x, y) peekb(vseg, (y) * (mcols * 2) + ((x) << 1) + 1) #define POINTS *((byte far *) 0x00000485) #define COLS *((byte far *) 0x0040004AL) #define ROWS *((byte far *) 0x00400084L) #define DEFCHAR 0xd0 /*********************************************************************/ /* Mon 07-Jan-1991 - dk */ /* */ /* Plot the cursor on the screen, save background, draw grid, etc. */ /* */ /*********************************************************************/ PRIVATE void LOCAL FAST plotegavgacursor(word func) { word off; word width, height, i, j; word disp; word x = 0, y = 0; static word lsavex = 0, lsavey = 0; switch (func) { case 0 : /* erase grid, put back save info */ x = lsavex; y = lsavey; break; case 1 : /* draw grid */ x = mousex; y = mousey; break; case 2 : /* save grid */ lsavex = x = mousex; lsavey = y = mousey; break; } width = mcols - x; if (width > 3) width = 3; height = mrows - y; if (height > 3) height = 3; off = y * (mcols * 2) + x * 2; disp = (mcols * 2) - width * 2; switch (func) { case 0 : /* erase grid, put back save info */ for (i = 0; i < height; i++, off += disp) for (j = 0; j < width; j++, off += 2) pokeb(vseg, off, savechars[i][j]); break; case 1 : /* draw grid. */ for (i = 0; i < height; i++, off += disp) for (j = 0; j < width; j++, off += 2) pokeb(vseg, off, DEFCHAR + i * 3 + j); break; case 2 : /* save grid. */ for (i = 0; i < height; i++, off += disp) for (j = 0; j < width; j++, off += 2) savechars[i][j] = peekb(vseg, off); break; } } PRIVATE void LOCAL FAST drawegavgacursor(void) { word off; word i, j; word s1, s2, s3; dword *defs; dword *masks; word shift; dword addmask; plotegavgacursor(2); /* Save current grid that is there. */ /* Time for some assembler. Program the EGA/VGA Sequencer and Graphics Controller for direct access to the character definition tables. Then read in the definitions for the characters we are changing, AND the screen mask, then OR the cursor mask to them. Then copy those defintions into the location of the mouse cursor defintions and set the Sequencer and Graphics Controller back to normal . */ /* Program the Sequencer */ asm pushf; /* Disable interrupts */ asm cli; asm mov dx, 3c4h; /* Sequencer port address */ asm mov ax, 0704h; /* Sequential addressing */ asm out dx, ax; /* Program the Graphics Controller */ asm mov dx, 3ceh; /* Graphics Controller port address */ asm mov ax, 0204h; /* Select map 2 for CPU reads */ asm out dx, ax; asm mov ax, 0005h; /* Disable odd-even addressing */ asm out dx, ax; asm mov ax, 0406h; /* Map starts at A000:0000 (64K mode) */ asm out dx, ax; asm popf; /* Ok, now we have direct access to the character defintion tables, copy over the defintions for the characters we are changing */ off = 0; for (i = 0; i < 9; i += 3) { /* Grid is three characters high. */ s1 = ((byte *)savechars)[i ] * 32; s2 = ((byte *)savechars)[i + 1] * 32; s3 = ((byte *)savechars)[i + 2] * 32; for (j = 0; j < points; j++) { off++; /* 4th byte, that we don't need. */ chardefs[off++] = peekb(0xa000, s3++); chardefs[off++] = peekb(0xa000, s2++); chardefs[off++] = peekb(0xa000, s1++); } } /* Ok, we've got the defintions for the characters that we are drawing the cursor on. AND the screen mask and OR the cursor mask to them, thereby 'drawing' the cursor. Since the cursor is 16 pixels wide and 16 pixels high, we have to save a 3 by 3 character grid where the mouse cursor is going. We use dwords (32 bits) to do the bit AND and OR. This could be made alot faster on a 386 by using 32 bit registers. */ shift = mousepx % 8; addmask = 0xff000000L << (8 - shift); masks = mousescreenmask; defs = ((dword *)chardefs) + mousepy % points; for (i = 0; i < HEIGHT; i++) *defs++ &= (*masks++ >> shift) | addmask; masks = mousecursormask; defs = ((dword *)chardefs) + mousepy % points; for (i = 0; i < HEIGHT; i++) *defs++ |= *masks++ >> shift; /* Ok, Everything is setup, now copy the modifed character definitions to their new location. */ asm mov dx, 3c4h; /* Sequencer port address */ asm mov ax, 0402h; /* CPU writes only to map 2 */ asm out dx, ax; off = 0; for (i = 0; i < 9; i += 3) { /* Grid is three characters high. */ s1 = (DEFCHAR + i ) * 32; s2 = (DEFCHAR + i + 1) * 32; s3 = (DEFCHAR + i + 2) * 32; for (j = 0; j < points; j++) { off++; /* 4th byte, that we don't need. */ pokeb(0xa000, s3++, chardefs[off++]); pokeb(0xa000, s2++, chardefs[off++]); pokeb(0xa000, s1++, chardefs[off++]); } } /* Ok, put the Sequencer and Graphics Controller back to normal */ /* Program the Sequencer */ asm pushf; /* Disable interrupts */ asm cli; asm mov dx, 3c4h; /* Sequencer port address */ asm mov ax, 0302h; /* CPU writes to maps 0 and 1 */ asm out dx, ax; asm mov ax, 0304h; /* Odd-even addressing */ asm out dx, ax; /* Program the Graphics Controller */ asm mov dx, 3ceh; /* Graphics Controller port address */ asm mov ax, 0004h; /* Select map 0 for CPU reads */ asm out dx, ax; asm mov ax, 1005h; /* Enable odd-even addressing */ asm out dx, ax; asm sub ax, ax; asm mov es, ax; /* Segment 0 */ asm mov ax, 0e06h; /* Map starts at B800:0000 */ asm mov bl, 7; asm cmp es:[49h], bl; /* Get current video mode */ asm jne notmono; asm mov ax, 0806h; /* Map starts at B000:0000 */ notmono: asm out dx, ax; asm popf; /* Ok, now put the bytes on the screen */ plotegavgacursor(1); /* Plot the new grid on the screen. */ } /*******************************************************/ /* 27-Oct-1990 - dk */ /* */ /* This function checks for the presense of EGA/VGA. */ /* */ /*******************************************************/ mouseboolean isegavga(void) { asm mov ax, 1a00h; /* ROM BIOS video function 1ah -- Read Display Code */ asm int 10h; asm cmp ah, 1ah; /* Is this call supported? */ asm je checkega; /* Not supported */ asm cmp bl, 7; /* VGA w/monochrome display? */ asm je isvga; /* Yup. */ asm cmp bl, 8; /* VGA w/color display? */ asm jne checkega; /* Nope */ isvga: vgapresent=1; isega: return TRUE; /* EGA/VGA is installed */ checkega: asm mov ah, 12h; /* EGA BIOS function */ asm mov bl, 10h; asm int 10h; asm cmp bl, 10h; /* Is EGA BIOS present? */ asm jne isega; /* There is an EGA in the system. */ return FALSE; /* Not EGA or VGA in system. */ } /************************************************/ /* 26-Oct-1990 - dk */ /* */ /* Mouse handler -- called from mouse driver. */ /* */ /************************************************/ PRIVATE void far mousehandler(void) /* This function is called whenever a button is pressed. Do not call this function directly!! */ { register word conditionmask; /* Get our data segment */ asm push ds #ifdef __TURBOC__ asm push ax asm mov ax, DGROUP asm mov ds, ax asm pop ax #else asm mov ds, cs:DGroupSeg #endif asm mov conditionmask,ax if (!mousefreeze) { /* save mouse info passed to us from driver */ asm mov mousex, cx asm mov mousey, dx asm mov mousepx, cx asm mov mousepy, dx mousex /= 8; /* Characters are 8 pixels wide */ mousey /= points; /* Scale mousey down */ /* See if the mouse has moved. */ if (conditionmask & MOUSEMOVE) { if (saved) { if (egavga) plotegavgacursor(0); else POKEATTRIB(oldmx, oldmy, oldword); saved = FALSE; } if (!mousehidden && conditionalhidemouse) /* Check to see if we need to hide */ if (mousex >= conx1 && mousex <= conx2 && mousey >= cony1 && mousey <= cony2) { mousehidden++; conditionalhidemouse = FALSE; } if (!mousehidden) { if (egavga) drawegavgacursor(); else { oldword = PEEKATTRIB(mousex, mousey); asm mov ax, oldword; /* Prepare to rotate attrib byte */ asm and al, 0f7h; /* Clear high bit */ asm mov cl, 4 /* We want to rotate 4 bits */ asm rol al, cl /* Rotate it */ asm mov newword, ax; POKEATTRIB(mousex, mousey, newword); /* Write out new mouse cursor */ } oldmx = mousex; oldmy = mousey; saved = TRUE; } } } /* Now, see if a mouse button was whacked */ if (conditionmask & ~MOUSEMOVE) if (((mbufin + 1) % MOUSEBUFFERSIZE) == mbufout) { /* Buffer full? */ #ifdef __TURBOC__ sound(1760); /* Make some noise. */ delay(10); nosound(); #endif } else { mbuf[mbufin].buttonstat = conditionmask & ~MOUSEMOVE; mbuf[mbufin].cx = mousex; mbuf[mbufin].cy = mousey; mbuf[mbufin].shiftstate = peekb(0, 0x417); /* Get shift byte */ mbufin = (mbufin + 1) % MOUSEBUFFERSIZE; } asm pop ds; } /************************************/ /* 26-Oct-1990 - dk */ /* */ /* Initialize the mouse routines. */ /* */ /************************************/ void FAST MOUinit(void) { extern int graphicalCursor; byte v; #ifndef __TURBOC__ asm mov cs:DGroupSeg,ds /* save for interrupt handler to use */ #endif asm sub ax,ax; /* Mouse driver function 0 -- reset and detect */ asm int 33h asm mov mouseinstalled, AX; if (mouseinstalled) { /* If a mouse is installed then activate driver */ mousefreeze++; /* Make sure handler doesn't do things, yet */ asm mov ax,0F00h; asm int 10h; asm mov v,al; if (v == 7) { vseg = 0xb000u; } else { vseg = 0xb800u; v = 3; } if (ROWS == 0) { /* No value, assume 80x25. */ mrows = 25; mcols = 80; points = 8; } else { mrows = ROWS + 1; mcols = COLS; points = POINTS; } /* Check to see if we are running in DESQview. If so, don't try to use the 'true' EGA/VGA cursor (DV doesn't like it at ALL). */ asm mov ax, 2b01h; asm mov cx, 4445h; asm mov dx, 5351h; asm int 21h; asm cmp al, 0ffh; asm je notdv; desqview = TRUE; notdv: /* Do we have an EGA or VGA? If so, and we are not in monochrome mode and we are not in DESQview then setup to draw a 'true' mouse cursor on an EGA/VGA */ egavga = isegavga() && vseg != 0xb000u && !desqview && graphicalCursor; if (egavga) { /* We are going to use our 'true' mouse cursor and we need pixel resolution, not character resolution from the mouse driver (In text mode, the mouse driver only returns coordinates in multiples of 8, which we don't want. We want multiples of 1, i.e. pixel resolution). To get the mouse driver to return coordinates in pixel resolution, we 'trick' it into thinking it's in graphics mode by setting the low memory byte indicating mode to mode 6 (CGA 640x200x2). Then we reset the mouse driver. The mouse driver will get the video mode then act as if it was in graphics mode, not text mode. */ savevmode = peekb(0x40, 0x49); pokeb(0x40, 0x49, 6); /* Does this work ?!?!?!?!? */ /* Reset driver for change in video mode to take effect. */ asm sub ax,ax asm int 33h /* Now that we've tricked the mouse driver into a grapics mode thereby causing it to give us pixel resolutions, put the old mode back. */ pokeb(0x40, 0x49, savevmode); } /* Set up max x and y ranges. */ maxx = mcols * 8 - 1; /* Pixels horizontally */ maxy = mrows * points - 1; /* Pixels vertically */ asm mov dx,maxx /* Pixels horizontally */ asm mov ax,7 /* mouse driver function 7 -- set max x range */ asm sub cx,cx /* Minimum range */ asm int 33h asm mov dx,maxy /* Pixels veritcally */ asm mov ax,8 /* mouse driver function 8 -- set max y range */ asm sub cx,cx /* Minimum range */ asm int 33h /* Now install user routine */ asm mov ax,cs asm mov es,ax asm mov dx, offset mousehandler /* Setup up bits for calling routine */ #ifdef __TURBOC__ _CX = LEFTBPRESS | LEFTBRELEASE | RIGHTBPRESS | RIGHTBRELEASE | MIDBPRESS | MIDBRELEASE | MOUSEMOVE; #else asm mov cx, LEFTBPRESS | LEFTBRELEASE | RIGHTBPRESS | RIGHTBRELEASE | MIDBPRESS | MIDBRELEASE | MOUSEMOVE; #endif asm mov ax,12 /* Function 12 -- set user routine */ asm int 33h mousex = mousey = mousepx = mousepy = 0; asm mov cx,mousepx /* xcoord */ asm mov dx,mousepy /* ycoord */ asm mov ax,4 /* mouse driver function 4 -- set mouse position */ asm int 33h MOUshow(); /* Call it twice just to make sure */ mousefreeze--; /* Handler can get into business, now */ } } /****************************/ /* 26-Oct-1990 - dk */ /* */ /* Hide the mouse cursor. */ /* */ /****************************/ void FAST MOUhide(void) /* This function turns off the mouse cursor, the mouse still responds to button presses */ { if (!mouseinstalled) return; mousefreeze++; /* don't have the handler doing weird things */ mousehidden++; /* indicate it's hidden now */ if (saved) { if (egavga) plotegavgacursor(0); else POKEATTRIB(oldmx, oldmy, oldword); saved = FALSE; } mousefreeze--; /* reactivate handler */ } /****************************/ /* 26-Oct-1990 - dk */ /* */ /* Show the mouse cursor. */ /* */ /****************************/ void FAST MOUshow(void) { if (!mouseinstalled) return; mousefreeze++; /* don't have the handler doing weird things */ /* Just in case we were in a conditionalhide */ if (conditionalhidemouse) { /* We were about to conditional hide, but we didn't, don't reactive mouse cursor. */ conditionalhidemouse = FALSE; mousefreeze--; /* Reactivate handler */ return; } if (mousehidden) mousehidden--; else { mousefreeze--; /* Reactivate handler */ return; /* It isn't hidden! */ } if (mousehidden) { mousefreeze--; /* reactivate handler */ return; /* still hidden! */ } /* Draw mouse cursor */ if (egavga) drawegavgacursor(); else { oldword = PEEKATTRIB(mousex, mousey); asm mov ax, oldword; /* Prepare to rotate attrib byte */ asm and al, 0f7h; /* Clear high bit */ asm mov cl, 4 /* We want to rotate 4 bits */ asm rol al, cl /* Rotate it */ asm mov newword, ax; POKEATTRIB(mousex, mousey, newword); /* Write out new mouse cursor */ } oldmx = mousex; oldmy = mousey; saved = TRUE; mousefreeze--; /* Reactivate handler */ } /*************************************************************/ /* 27-Oct-1990 - dk */ /* */ /* Returns true if there is something in the mouse buffer. */ /* */ /*************************************************************/ mouseboolean FAST MOUcheck(void) { return mbufin != mbufout; } /**************************************************************/ /* 26-Oct-1990 - dk */ /* */ /* Take a copy of the mouse event at the head of the queue. */ /* */ /**************************************************************/ void FAST MOUpreview(MOUINFOREC *mouinforec) { if (!mouseinstalled) return; if (mbufin != mbufout) /* if something is in buffer */ *mouinforec = mbuf[mbufout]; else { /* Nothing to pull, just report mouse position */ mouinforec -> cx = mousex; mouinforec -> cy = mousey; mouinforec -> buttonstat = 0; mouinforec -> shiftstate = peekb(0, 0x417); } } /****************************************************************/ /* 26-Oct-1990 - dk */ /* */ /* Get (and remove) the mouse event at the head of the queue. */ /* */ /****************************************************************/ void FAST MOUget(MOUINFOREC *mouinforec) { if (!mouseinstalled) return; if (mbufin != mbufout) { /* if something is in buffer */ if (mouinforec != NULL) *mouinforec = mbuf[mbufout]; mbufout = (mbufout + 1) % MOUSEBUFFERSIZE; } else { /* Nothing to pull, just report mouse position */ mouinforec -> cx = mousex; mouinforec -> cy = mousey; mouinforec -> buttonstat = 0; mouinforec -> shiftstate = peekb(0, 0x417); } } /**************************************/ /* 26-Oct-1990 - dk */ /* */ /* Deinitialize the mouse routines. */ /* */ /**************************************/ void FAST MOUdeinit(void) { if (!mouseinstalled) return; MOUhide(); asm sub ax,ax asm int 33h } /**************************************************/ /* 26-Oct-1990 - dk */ /* */ /* Returns the bits for the button status info. */ /* */ /**************************************************/ word FAST MOUbuttonstatus(void) { word buts; if (!mouseinstalled) return 0; asm mov ax,3 asm int 33h asm mov buts,bx return buts; } /************************************************************************/ /* 26-Oct-1990 - dk */ /* */ /* Hide the mouse *if* it enters a certain screen area, automatically. */ /* */ /************************************************************************/ void FAST MOUconditionalhide(int x1, int y1, int x2, int y2) { if (!mouseinstalled) return; mousefreeze++; /* hold the handler */ if (mousehidden) { mousefreeze--; /* reactivate handler */ return; /* already hidden! */ } conditionalhidemouse = TRUE; x1 -= 2; if (x1 < 0) x1 = 0; y1 -= 2; if (y1 < 0) y1 = 0; x2 += 2; y2 += 2; conx1 = x1; cony1 = y1; conx2 = x2; cony2 = y2; if (mousex >= conx1 && mousex <= conx2 && mousey >= cony1 && mousey <= cony2) { conditionalhidemouse = FALSE; /* We've already hidden it */ MOUhide(); /* turn it off now if it's there. */ } mousefreeze--; } /*********************************************************/ /* Fri 15-Mar-1991 - dk */ /* */ /* Set the mouse cursor to a specific screen position. */ /* */ /*********************************************************/ void FAST MOUsetpos(word x, word y) { if (!mouseinstalled) return; mousefreeze++; MOUhide(); mousex = x; mousey = y; mousepx = mousex * 8; mousepy = mousey * points; asm mov cx, mousepx /* xcoord */ asm mov dx, mousepy /* ycoord */ asm mov ax, 4 /* mouse driver function 4 -- set mouse position */ asm int 33h MOUshow(); mousefreeze--; } mgt-2.31/parse.c100640 1750 1750 20147 6176731453 11377 0ustar memmem/* "mgt" Copyright (c) 1991 Shodan */ #include #include "mgt.h" struct { char *str; Token val; } tokens[] = { { "W", t_White }, { "B", t_Black }, { "C", t_Comment }, { "AW", t_AddWhite }, { "AB", t_AddBlack }, { "L", t_Letter }, { "AE", t_AddEmpty }, { "N", t_Name }, { "M", t_Mark }, { "SZ", t_Size }, { "GN", t_GameName }, { "GC", t_GameComment }, { "EV", t_Event }, { "RO", t_Round }, { "DT", t_Date }, { "PC", t_Place }, { "PB", t_PlayerBlack }, { "PW", t_PlayerWhite }, { "RE", t_Result }, { "US", t_User }, { "TM", t_TimeLimit }, { "SO", t_Source }, { "BR", t_BlackRank }, { "WR", t_WhiteRank }, { "HA", t_Handicap }, { "KM", t_Komi }, { "PL", t_Player } }; char buf[1028], *curin, started; FUNCTION void readInit() { int p; buf[0] = '\0'; curin = &buf[0]; started = 1; boardsize = 19; handicap = 0; for (p = 0; p <= LASTINFO - FIRSTINFO + 1; p++) { if (info[p]) free(info[p]); info[p] = 0; } } static char *readLine() { curin = &buf[0]; buf[0] = '\0'; return fgets(&buf[0], 1023, input); } static char readChar() { if (*curin) return *(curin++); curin = &buf[0]; buf[0] = '\0'; fgets(&buf[0], 1023, input); return 0; } static int getCoordStr(co) coord *co; { if (strlen(curin) < 4 && curin[strlen(curin) - 1] != '\n') { char *dest; for (dest = buf; *curin; curin++, dest++) *dest = *curin; *dest = 0; fgets(dest, 1023, input); curin = buf; } if (curin[0] == '[' && curin[1] >= 'a' && curin[1] <= 's' && curin[2] >= 'a' && curin[2] <= 's' && curin[3] == ']') { co->x = curin[1] - 'a'; co->y = curin[2] - 'a'; curin += 4; while (*curin == ' ' || *curin == '\t') curin++; if (*curin == '\n') readLine(); return 1; } else return 0; } static void getCoordList(clp) coordList **clp; { coord co; while (getCoordStr(&co)) { setCoord(co.x, co.y, clp); } } static void addPass(n, t) nodep n; Token t; { property *p; if (!(p = (property *) calloc(1, sizeof(property)))) barf("Memory allocation error (addPass)"); p->t = t_Pass; p->data.player = t; addprop(n, p); } static void doPlayer(n) nodep n; { property *p; if (curin[0] == '[' && curin[2] == ']' && (curin[1] == 'B' || curin[1] == 'W')) { p = (property *) calloc(1, sizeof(property)); if (!p) barf("Memory allocation failure (doPlayer)"); p->t = t_Player; p->data.player = curin[1] == 'B' ? t_Black : t_White; curin += 3; addprop(n, p); } } static Token tokenize() { int i, len; char buf[4]; len = 0; do { if (!*curin || *curin == '\n') { if (!readLine()) return t_EOF; } if (*curin == ')') { curin++; return t_Close; } if (*curin == '(') { curin++; return t_Open; } if (*curin == ';') { curin++; return t_NewNode; } if (*curin >= 'A' && *curin <= 'Z') buf[len++] = *curin; curin++; } while (len < 3 && *curin != '['); buf[len] = 0; if (len == 1 || len == 2) for (i = 0; i < sizeof(tokens) / sizeof(tokens[0]); i++) if (!strcmp(buf, tokens[i].str)) return tokens[i].val; while (*curin != ']') { if (!*++curin) { if (!readLine()) return t_EOF; } } return t_WS; } static void addMoveArrayProp(t, n) Token t; nodep n; { property *p; #ifdef DEBUG totalmemory += sizeof(property); fprintf(debug, "%ld %ld\n", totalmemory, coreleft()); #endif if (!(p = getprop(n, t))) { p = (property *) calloc(1, sizeof(property)); #ifdef DEBUG totalmemory += sizeof(coordList); fprintf(debug, "%ld %ld\n", totalmemory, coreleft()); #endif if (!p) barf("Memory allocation failure (addMoveArrayProp)"); p->data.stones = 0; p->t = t; addprop(n, p); } getCoordList(&(p->data.stones)); } static void doSize() { int size; char *s, c, b[25]; s = &b[0]; readChar(); while ((c = readChar()) != ']') if (c && c != '\\') *s++ = c; *s = 0; size = atoi(b); if ((size > 1) && (size <= 19)) boardsize = size; } static void doHandicap() { int size; char *s, c, b[25]; s = &b[0]; readChar(); while ((c = readChar()) != ']') if (c && c != '\\') *s++ = c; *s = 0; size = atoi(b); if ((size > 1) && (size <= 17)) handicap = size; } /* gets text. Assumes we start on a '['. Returns pointer to a buffer which * should be freed */ static char *getText() { int c; char *s; char *buffer; int space = COMMENTALLOC; int blocks = 1; buffer = (char *) malloc(COMMENTALLOC); if (!buffer) barf("Memory Allocation Failure (getText)"); s = buffer; (void) readChar(); while ((c = readChar()) != ']') { if (!c) { c = readChar(); if (!c || c == ']') break; } if (space <= 1) { buffer = (char *) realloc(buffer, ++blocks * COMMENTALLOC); if (!buffer) barf("Memory Allocation Failure (getText)"); s = buffer - space + (blocks - 1) * COMMENTALLOC; space += COMMENTALLOC; } if (c == '\\') c = readChar(); if (c) { *s++ = c; space--; } } if (s != buffer && *(s - 1) == '\n') s--; *s = 0; return buffer; } static void doComment(n, t) nodep n; Token t; { property *p; char *buffer; p = (property *) calloc(1, sizeof(property)); if (!p) barf("Memory Allocation Failure (doComment)"); buffer = getText(); p->t = t; p->data.comment = dupStr(buffer); addprop(n, p); free(buffer); } static void doInfo(t) Token t; { char *buffer; buffer = getText(); info[(int) t - FIRSTINFO] = dupStr(buffer); free(buffer); } FUNCTION void addChild(n, c) /* add child c to node n */ nodep n, c; { if (n) { if (n->child) { nodep s; s = treeLastSibling(child(n)); s->nextSibling = c; c->lastSibling = s; c->parent = n; } else { n->child = c; c->parent = n; } } } FUNCTION nodep parse(lev) int lev; { nodep r, n, new; Token t; if (started) { started = 0; while (*curin != '(') { if (!readLine()) break; } } r = n = 0; for (;;) { t = tokenize(); switch (t) { case t_Size: doSize(); break; case t_White: case t_Black: if (curin[1] == 't' && curin[2] == 't' && curin[0] == '[' && curin[3] == ']') { addPass(n, t); break; } case t_AddWhite: case t_AddBlack: case t_AddEmpty: case t_Mark: case t_Letter: if (n) addMoveArrayProp(t, n); else fprintf(stderr, "Error - property w/o node in data\n"); break; case t_Player: if (n) doPlayer(n); else fprintf(stderr, "Error - property w/o node in data\n"); break; case t_Name: case t_Comment: if (n) doComment(n, t); else fprintf(stderr, "Error - property w/o node in data\n"); break; case t_NewNode: new = newNode(); if (!r) r = new; else addChild(n, new); n = new; break; case t_Open: if (lev == 1 && !r) n = r = newNode(); if (new = parse(lev + 1)) { addChild(n, new); if (!r) r = new; } break; case t_Close: case t_EOF: return r; case t_GameName: case t_GameComment: case t_Event: case t_Round: case t_Date: case t_Place: case t_PlayerBlack: case t_PlayerWhite: case t_Result: case t_User: case t_TimeLimit: case t_Source: case t_BlackRank: case t_WhiteRank: doInfo(t); break; case t_Komi:{ char *ch, *end; doInfo(t_Komi); end = ch = info[(int) t_Komi - FIRSTINFO]; while (*end) end++; for (end--; *end == '0' && (end != ch); end--); *++end = 0; } break; case t_Handicap: doHandicap(); break; default: break; } } } mgt-2.31/play.c100640 1750 1750 13430 6176731454 11230 0ustar memmem/* "mgt" Copyright (c) 1991 Shodan */ #include "mgt.h" #include #include /* void printboard(char *s,pBoard b) { FILE *fil; int i,j; * fil=fopen("dump","a+"); if (!fil) {printf("can't open file");getch();} * fprintf(fil,"%s\n",s); for(i=0;ib[i][j]==P_NOTHING?'.':(b->b[i][j]==P_BLACK?'*':'O'),fil); * fputc('\n',fil); } fclose(fil); } */ FUNCTION int legal(b, n, player, i, j) pBoard b; nodep n; int i, j; Token player; { board a, copy; int same, x, y, savex, savey, savemove; boolean islegal; extern int moveNum; int savepris[2]; Token savecurPlayer; savemove = moveNum; savecurPlayer = curPlayer; savex = xcur; savey = ycur; savepris[0] = prisoners[0]; savepris[1] = prisoners[1]; copyBoard(b, ©); islegal = true; if (b->b[i][j] != P_NOTHING) { (*io->notifyError) ("There's already a piece there."); return false; } placeStone(©, i, j, (player == t_Black) ? P_BLACK : P_WHITE); if (!alive(©, i, j)) { (*io->notifyError) ("That move is suicide."); islegal = false; } if (islegal && (n = n->parent)) { boardClear(&a); buildTree0(n, &a); same = true; for (x = boardsize; same && x--;) for (y = boardsize; same && y--;) { same = (copy.b[x][y] == a.b[x][y]); } if (same) { (*io->notifyError) ("Can't retake the ko yet."); islegal = false; } } xcur = savex; ycur = savey; prisoners[0] = savepris[0]; moveNum = savemove; prisoners[1] = savepris[1]; curPlayer=savecurPlayer; return islegal; } FUNCTION boolean inRange(i, j) { return i >= 0 && i < boardsize && j >= 0 && j < boardsize; } FUNCTION boolean alive0(b, m, i, j, t) pBoard b; pBoard m; int i, j; piece t; { piece pt; pt = b->b[i][j]; if ((pt != P_NOTHING && pt != t) || m->b[i][j] != P_NOTHING) return 0; m->b[i][j] = (pt == t) ? (piece) 1 : (piece) 2; if (pt == P_NOTHING) return 1; return (j < boardsize - 1 && alive0(b, m, i, j + 1, t)) || (i < boardsize - 1 && alive0(b, m, i + 1, j, t)) || (i && alive0(b, m, i - 1, j, t)) || (j && alive0(b, m, i, j - 1, t)); } FUNCTION boolean alive(b, i, j) /* Does group at i,j have liberties? */ pBoard b; int i, j; { board m; boardClear(&m); return alive0(b, &m, i, j, b->b[i][j]); } void removeStones0(b, i, j, t) pBoard b; int i, j; piece t; { if (b->b[i][j] != t) return; b->b[i][j] = P_NOTHING; prisoners[(int) t - 1]++; if (j < boardsize - 1) removeStones0(b, i, j + 1, t); if (i < boardsize - 1) removeStones0(b, i + 1, j, t); if (i) removeStones0(b, i - 1, j, t); if (j) removeStones0(b, i, j - 1, t); } FUNCTION void removeStones(b, i, j) pBoard b; int i, j; { removeStones0(b, i, j, b->b[i][j]); } FUNCTION boolean tryKill(b, i, j, t) pBoard b; int i, j; piece t; { piece w; if (!inRange(i, j)) return false; w = b->b[i][j]; if (w != P_NOTHING && w != t && !alive(b, i, j)) { removeStones(b, i, j); return true; } return false; } FUNCTION void placeStone(b, i, j, t) pBoard b; int i, j; piece t; { if (inRange(i, j)) { b->b[i][j] = t; xcur = i; ycur = j; if (j) tryKill(b, i, j - 1, t); if (j < boardsize - 1) tryKill(b, i, j + 1, t); if (i) tryKill(b, i - 1, j, t); if (i < boardsize - 1) tryKill(b, i + 1, j, t); } } FUNCTION void boardSet(b, i, j, p) pBoard b; int i, j; piece p; { b->b[i][j] = p; } FUNCTION piece boardGet(b, i, j) pBoard b; int i, j; { return b->b[i][j]; } FUNCTION void boardClear(b) pBoard b; { memset((char *) (b->b), 0, 361 * sizeof(piece)); /* int i, j; for (i = boardsize; i--;) for (j = boardsize; j--;) b->b[i][j] * = P_NOTHING; */ } FUNCTION void copyBoard(a, b) pBoard a, b; { int i, j; for (i = boardsize; i--;) for (j = boardsize; j--;) b->b[i][j] = a->b[i][j]; } int look(stone, array, index, i) int stone, array[], *index, i; { if (stone == P_NOTHING) array[(*index)++] = i; else if (stone == P_BLACK) return 1; else if (stone == P_WHITE) return 2; return 0; } int fillregion(b, x, y) pBoard b; int x, y; { int goup[19], godown[19], up = 0, down = 0, found = 0, i; for (i = x; i < boardsize && b->b[i][y] == P_NOTHING; i++) { b->b[i][y] = P_CHECKED; if (y > 0) found |= look(b->b[i][y - 1], goup, &up, i); if (y < boardsize - 1) found |= look(b->b[i][y + 1], godown, &down, i); } if (i != boardsize) { if (b->b[i][y] == P_BLACK) found |= 1; if (b->b[i][y] == P_WHITE) found |= 2; } for (i = x - 1; i >= 0 && b->b[i][y] == P_NOTHING; i--) { b->b[i][y] = P_CHECKED; if (y > 0) found |= look(b->b[i][y - 1], goup, &up, i); if (y < boardsize - 1) found |= look(b->b[i][y + 1], godown, &down, i); } if (i != -1) { if (b->b[i][y] == P_BLACK) found |= 1; if (b->b[i][y] == P_WHITE) found |= 2; } while (up) found |= fillregion(b, goup[--up], y - 1); while (down) found |= fillregion(b, godown[--down], y + 1); return found; } FUNCTION void scoreBoard(b, score) pBoard b; int score[]; { int x, y, i, j, owner; piece newval; score[0] = 0; score[1] = 0; for (i = 0; i < boardsize; i++) for (j = 0; j < boardsize; j++) { owner = fillregion(b, i, j); if (!owner) owner = 3; switch (owner) { case 3: newval = P_DAME; break; case 2: newval = P_WHITETERR; break; case 1: newval = P_BLACKTERR; break; } for (x = 0; x < boardsize; x++) for (y = 0; y < boardsize; y++) if (b->b[x][y] == P_CHECKED) { b->b[x][y] = newval; if (owner != 3) score[owner - 1]++; } } } mgt-2.31/tree.c100640 1750 1750 12502 6176731454 11221 0ustar memmem/* "mgt" Copyright (c) 1991 Shodan */ #include "mgt.h" static int newNodeNum; FUNCTION boolean getCoord(x, y, list) int x, y; coordList *list; { for (; list; list = list->next) if (list->x == x && list->y == y) return true; return false; } FUNCTION coordList *addCoord(x, y) int x, y; { coordList *co; if (!(co = (coordList *) malloc(sizeof(coordList)))) barf("Memory allocation failure (addCoord)"); co->next = 0; co->x = x; co->y = y; return co; } FUNCTION void setCoord(x, y, startlist) int x, y; coordList **startlist; { coordList *list; if (!*startlist) *startlist = addCoord(x, y); else { for (list = *startlist; list->next; list = list->next) if (x == list->x && y == list->y) return; list->next = addCoord(x, y); } } FUNCTION void clearCoord(x, y, startlist) int x, y; coordList **startlist; { coordList *last, *list; last = 0; list = *startlist; while (list && (x != list->x || y != list->y)) { last = list; list = list->next; } if (list) { if (last) last->next = list->next; else *startlist = list->next; free(list); } } FUNCTION void initNodes() { newNodeNum = 0; } FUNCTION nodep newNode() { nodep new; #ifdef DEBUG totalmemory += sizeof(node); fprintf(debug, "%ld %ld\n", totalmemory, coreleft()); #endif new = (nodep) calloc(1, sizeof(node)); if (!new) barf("Memory allocation failure (newnode)"); new->nodeNum = newNodeNum++; return new; } FUNCTION void freeNode(n) nodep n; { if (n) { freeNode(n->nextSibling); freeNode(n->child); delNode(n); } } FUNCTION char *dupStr(s) char *s; { char *c; #ifdef DEBUG totalmemory += strlen(s) + 1; fprintf(debug, "%ld %ld\n", totalmemory, coreleft()); #endif c = (char *) malloc((unsigned) strlen(s) + 1); if (!c) barf("Memory allocation failure (dupstr)"); strcpy(c, s); return c; } FUNCTION void freeProps(n) nodep n; { property *prop, *lastprop; coordList *cl, *lastcl; prop = n->p; while (prop) { switch (prop->t) { case t_AddEmpty: case t_AddBlack: case t_AddWhite: case t_Mark: case t_Letter: case t_Black: case t_White: cl = prop->data.stones; while (cl) { lastcl = cl; cl = cl->next; free(lastcl); } break; case t_Name: case t_Comment: free(prop->data.comment); break; } lastprop = prop; prop = prop->next; free(lastprop); } } FUNCTION void delNode(n) nodep n; { freeProps(n); free(n); } FUNCTION void addprop(n, p) nodep n; property *p; { p->next = n->p; n->p = p; } FUNCTION property *getprop(n, t) nodep n; Token t; { property *p; p = n->p; while (p && p->t != t) p = p->next; return p; } FUNCTION int treeCountSiblings(n) nodep n; { int i; nodep n1; n1 = n->child; i = 0; while (n1) { n1 = n1->nextSibling; i++; } return i; } FUNCTION nodep nthChild(n, c) /* nodep, int */ nodep n; int c; { if (n->child) { n = child(n); while (c-- && n) n = nextSibling(n); } else { n = 0; } return n; } /* TREE WALK functions KEEP TRACK OF DEPTH AS WELL */ FUNCTION nodep parent(n) nodep n; { return n->parent; } FUNCTION nodep child(n) nodep n; { return n->child; } FUNCTION nodep lastSibling(n) nodep n; { return n->lastSibling; } FUNCTION nodep nextSibling(n) nodep n; { return n->nextSibling; } FUNCTION nodep treeLastSibling(n) nodep n; { while (n->nextSibling) { n = n->nextSibling; } return n; } /* go to next node down the tree. Stop if at bottom. */ FUNCTION nodep treeDown(n) nodep n; { if (n->child) { BUG("treeDown: going down\n"); return child(n); } else { BUG("treeDown: stop\n"); return n; } } /* backup, stop if at top */ FUNCTION nodep treeUp(n) nodep n; { if (n->parent) { BUG("treeUp: going up\n"); return parent(n); } else { BUG("treeUp: staying\n"); return n; } } /* go to next node backing up the tree only */ FUNCTION nodep treeNextUp(n) nodep n; { if (n->nextSibling) { BUG("nextSibling "); return nextSibling(n); } else if (n->parent) { BUG("nextup-parent "); while (n->parent && !n->nextSibling) n = parent(n); if (n->nextSibling) return nextSibling(n); else return n; } else if (n->child) { BUG("child "); return child(n); } else { BUG("current "); return n; } } /* go to next node, backup if neccessary */ FUNCTION nodep treeNext(n) nodep n; { nodep r; BUG("treeNext:"); if (n != (r = treeDown(n))) { BUG("going down "); } else { BUG("going up "); r = treeNextUp(n); } BUG("\n"); return r; } FUNCTION nodep lastChildOfLastSibling(n) nodep n; { while (n->nextSibling) n = nextSibling(n); if (n->child) return lastChildOfLastSibling(child(n)); else return n; } /* go to next node, backup if neccessary */ FUNCTION nodep treeLast(n) nodep n; { nodep r; if (n->lastSibling) { n = lastSibling(n); if (n->child) r = lastChildOfLastSibling(child(n)); else r = n; } else if (n->parent) { r = parent(n); } else if (n->child) { r = lastChildOfLastSibling(child(n)); } else { r = n; } return r; } mgt-2.31/wrapmgt.c100640 1750 1750 4340 6176731472 11724 0ustar memmem#include main(argc, argv) int argc; char *argv[]; { char *last, line[100]; int cur, limit; int intext, incomment; limit = 79; if (argc > 2) { fprintf(stderr, "Wrong number of arguments.\n\n"); exit(1); } if (argc == 2) { limit = atoi(argv[1]); if (!limit) { fprintf(stderr, "Invalid limit\n\n"); exit(2); } } last = 0; cur = 0; intext = 0; incomment = 0; do { line[cur] = getchar(); /* This next line makes the program aggressively eat up white space */ /* found outside the text sections */ if (!intext && (line[cur] == ' ' || line[cur] == '\n' || line[cur] == '\r')) continue; /* These tests come first because they don't look at the current * character */ /* They need to be checked before the flags (next section) are reset */ /* line breaks at spaces within comments only */ if (incomment && cur && line[cur - 1] == ' ') last = &line[cur]; /* line breaks at after ']' if followed by capital letter */ if (!intext && cur > 2 && line[cur - 1] >= 'A' && line[cur - 1] <= 'Z' && line[cur - 2] == ']' && line[cur - 3] != '\\') last = &line[cur - 1]; /* These change the various flags */ /* Check for start of comment 'C[' */ if (cur && line[cur - 1] == 'C' && line[cur] == '[') incomment = intext = 1; /* Check for start of non-comment bracketed section */ if (line[cur] == '[' && (cur == 0 || line[cur - 1] != '\\')) intext = 1; /* check for end of bracketed sections ']' */ if (intext && line[cur] == ']' && (cur == 0 || line[cur - 1] != '\\')) intext = incomment = 0; /* This test does use current character */ /* line breaks at ';' outside of text */ if (!intext && line[cur] == ';') last = &line[cur]; if (line[cur] == '\n') { line[cur + 1] = 0; fputs(line, stdout); last = line; cur = -1; } cur++; if (cur >= limit && last) { char *loc, *end; for (loc = line; loc < last; loc++) putchar(*loc); putchar('\n'); loc = line; line[cur] = 0; strcpy(line, last); last = 0; cur = strlen(line); } } while (!feof(stdin)); line[cur] = 0; fputs(line, stdout); } mgt-2.31/Build.com100640 1750 1750 10104 6176731462 11650 0ustar memmem$! $! This file hacked by Adrian Mariano to correctly compile the $! mgt program. I don't want to compile all .c files in the $! current directory. $! $! This procedure checks all .C files in the current directory, and $! compiles any whose .OBJ file is older. Then, all files are $! linked. $! $! CAUTION: .H files are not checked, so if you change one, $! you'll need to delete the .OBJ files of any .C $! files that depend on that .H file. That will allow $! this BUILD.COM to recompile those .C files. $! $! Usage: $! $! @build [-Dname[=value]] [-g] [-ename] $! $! If -D is given, a corresponding /DEFINE is fed to the C compiler. $! $! If -g is given, the linker is told to link a debug version. $! $! If -e is given, name is used for name of executable. If not, $! sources are searched for "main(" or "main (" and that source name $! is used for name of executable. $! $! Author: Eric Osman 8-8-90 $! $ on warning then goto hey_stop $ on control_y then goto hey_stop $ cpl = "call do_cpl" $ q = "sys$scratch:''f$getjpi("","pid")'" !! Find macro definitions and link switches $ n = 1 $ macros = "" $ link_switches = "" $ plup: if n .le. 8 $ then next = p'n' $ n = n + 1 $ qual = f$edit (f$extr(0,2,next),"upcase") $ if qual .eqs. "-D" $ then definition = f$extr(2,f$len(next)-2,next) $ macros = macros + "/define=""" + definition + """" $ else if qual .eqs. "-E" $ then exe_name = f$parse(f$extr(2,f$len(next)-2,next),".exe") $ else if qual .eqs. "-G" $ then link_switches = link_switches + "/debug" $ endif $ endif $ endif $ goto plup $ endif $ $ !! Get all dates $ !! Begin hack $ $ rename wrapmgt.c wrapmgt.tmp $ rename mou.c mou.tmp $ $!! end hack $ $ write sys$output "[Getting list of sources and objects]" $ dir/date/col=1/nohead/notrail/out=temp.txt *.c.0,*.obj.0/exclude=foo.* $ $!! begin hack $ $ rename mou.tmp mou.c $ rename wrapmgt.tmp wrapmgt.c $ $!! end hack $ $ write sys$output "[Examining dates]" $ close/nolog b_chan $ close/nolog link_chan $ open b_chan temp.txt $ open/write link_chan temp.opt $ num = 0 $ slup: $ read/end=nomore b_chan file_line $ read/end=nomore b_chan date_line $ type = f$parse (file_line,,,"type") $ name = f$parse (file_line,,,"name") $ if "''type'" .eqs. ".C" $ then src_'num' = "''name'" $ num = num + 1 $ write link_chan name + ".obj" $ date_tag = name + "_SRC_DATE" $ else date_tag = name + "_OBJ_DATE" $ endif $ date = f$edit(date_line,"trim") $ 'date_tag' = f$cvt(f$el(0," ",date) + ":" + f$el(1," ",date)) $ goto slup $ nomore: close b_chan $ close link_chan $ n_srces = num $ num = 0 $ dlup: $ src_name = src_'num' $ src_date = 'src_name'_src_date $ if f$type ('src_name'_obj_date) .eqs. "" $ then obj_date = "" $ else obj_date = 'src_name'_obj_date $ endif $ define/user x11 decw$include: $ cpl 'src_name' "''src_date'" "''obj_date'" $ num = num + 1 $ if num .lt. n_srces then goto dlup $ delete temp.txt. $ !! Make option file specifying libraries to link with $ app sys$input temp.opt sys$share:vaxcrtl.exe/share $ !! If name of executable hasn't been specified, find which source !! has main routine in it. $ if f$type (exe_name) .eqs. "" $ then $ def/user sys$output nl: $ def/user sys$error nl: $ search/out='q'.out/window=0 *.c "main(","main (" $ close/nolog a $ open a 'q'.out $ read/end=better_ask a line $ exe_name = f$parse (".exe;0",line) $ close a $ delete 'q'.out. $ goto now_we_have_exe_name $ better_ask: $ close a $ read/prompt="Name for executable file: " sys$command exe_name $ endif $ now_we_have_exe_name: $ !! Link objects $ set verify $ link /exe='exe_name' temp/opt 'link_switches' $ delete temp.opt. ! 'f$ver(0)' $ exit $ hey_stop: $ set noverify $ exit $ do_cpl: $ subroutine $ on warning then exit $ on control_y then goto cleanup $ src = p1 + ".c" $ obj = p1 + ".obj" $ if f$search (obj) .eqs. "" then goto cpl_it $ if p2 .lts. p3 $ then $ write sys$output "[''obj' already o.k.]" $ exit $ endif $ cpl_it: $ def/user sys sys$library: $ set verify $ cc 'src' 'macros'/include=(decw$include:,sys$library:)/deb/mach/list - /obj=temp.obj $ rename temp.obj 'obj' ! 'f$ver(0)' $ exit $ cleanup: $ set nover $ exit %x610 $ endsubroutine mgt-2.31/Makefile100640 1750 1750 7462 6177477677 11566 0ustar memmem# There is NO X version of this program # # "mgt" Copyright 1991 Shodan # All Rights Reserved. # Program by Greg Hale and Adrian Mariano # #Permission to use, copy, modify, and distribute this software and its #documentation for any purpose and without fee is hereby granted, #provided that this entire comment and copyright notice appear in all #copies and that both that copyright notice and this permission notice #appear in supporting documentation. No representations are made about #the suitability of this software for any purpose. It is provided "as #is" without express or implied warranty. # #Please send copies of extensions to: # # hale@scam.berkeley.edu # 128.32.138.4 scam.berkeley.edu # #Donations for the 'From My Go Teacher' series may be sent to: # Shodan # P.O. Box 4456 # Berkeley, CA 94704 # (415) 574-5572 # # # Makefile for mgt # by Greg Hale and Adrian Mariano # # *** C compile flags. # # -O: optimize # -DDEBUG: turn on program debugging # # *** CONFIGURATION *** # # Choose one of # -DMGT_UNIX Compile under UNIX # -DMGT_IBM Compile on IBM PC under Turbo C (Use the other Makefile!) # # -DMGT_LIB=\"/usr/lib/mgt/\": defines a library directory for games # DEFS=-DMGT_UNIX -DMGT_LIB=\"/usr/lib/games/mgt/\" # If you read this Makefile, you may notice many references to an # X Windows program. This program has been released and is available # at the standard archive sites. E = O = .o CC = cc CFLAGS = -O $(DEFS) LD = cc LDFLAGS = LIBS = #CUR_LIBS = -lcurses -ltermcap CUR_LIBS = -lcurses X11_LIBS = # DIRECTORIES - CONFIGURE DESTINATIONS # BINDIR is where it is installed BINDIR = /usr/games MAN = mgt.doc SHAR = mgt.sh # files which make up the shell archive along with sources FILES = Smart-Go.def README Makefile format mgt.6 \ Spec.io Makefile.bc Build.com mailgo mailgo.6 mgtdoc.asc \ Sample.01 Sample.02 Rules Prop.lst README.IBM wrapmgt.6 \ wrapmgt.c mgt2short mgt2short.6 mgtshort.bat mgtshort.cmd SH_OBJS = help$O build$O comment$O doit$O \ edit$O mgt$O parse$O play$O tree$O SH_SRCS = help.c ascii.c build.c comment.c doit.c \ edit.c mgt.c parse.c play.c tree.c ASC_OBJS= ascii$O OBJECTS = help$O ascii$O build$O comment$O doit$O \ edit$O mgt$O parse$O play$O tree$O SRCS = help.c asc_ibm.inc asc_unix.inc mou.c \ ascii.c build.c comment.c doit.c edit.c \ mgt.c parse.c play.c tree.c HDRS = mgt.h proto.h mou.h all : begin curses wrapmgt man end begin : @echo Begin... end : @echo ...End curses : mgt$E @echo Completed curses based version. mgt$E : $(SH_OBJS) $(ASC_OBJS) $(LD) $(LDFLAGS) -o mgt$E $(SH_OBJS) $(ASC_OBJS) $(CUR_LIBS) wrapmgt$E : wrapmgt.o $(LD) -o wrapmgt$E wrapmgt.o ascii.o: ascii.c asc_unix.inc $(MAN): mgt.6 @echo "Creating mgt manual..." @nroff -man mgt.6 > $(MAN) @echo "done." mailgo.doc: mailgo.6 @echo "Creating mailgo manual..." @nroff -man mailgo.6 > mailgo.doc @echo "done." wrapmgt.doc: wrapmgt.6 @echo "Creating wrapmgt manual..." @nroff -man wrapmgt.6 > wrapmgt.doc @echo "done." mgt2short.doc: mgt2short.6 @echo "Creating mgt2short manual..." @nroff -man mgt2short.6 > mgt2short.doc @echo "done." man: $(MAN) wrapmgt.doc mailgo.doc mgt2short.doc clean: @echo "removing extra files..." @-rm -f *$O $(SHAR) xmgt$E mgt$E @echo "done." proto: @echo "making proto.h file..." @-rm -f ./proto.h @egrep "FUNCTION" $(SH_SRCS) | sed "s/(.*)/();/" | sed "s/^.*://" | sed "s/FUNCTION/extern/" | cat > ./proto.h @echo "done." lint: @echo "making lint file..." @-rm -f ./lint.out @lint -u $(DEFS) $(SH_SRCS) > ./lint.out @echo "done." new: proto clean all mgtdoc.asc: $(MAN) @echo "Making ascii doc file..." @cat $(MAN) | col -b > mgtdoc.asc; @echo "done." shar: mgtdoc.asc @shar $(SRCS) $(HDRS) $(FILES) > $(SHAR) install : $(PROGRAM) $(ARCHIVE) @-install $(PROGRAM) $(BINDIR)/$(PROGRAM) mgt-2.31/Makefile.bc100640 1750 1750 725 6176731462 12104 0ustar memmem# Makefile for Borland C++ 2.0 # Place your library directory below LIB=c:\prog\c\lib MDL=c mgt.exe: ascii.obj build.obj comment.obj doit.obj edit.obj\ parse.obj play.obj tree.obj mgt.obj help.obj mou.obj tlink /c /x $(LIB)\c0$(MDL) $(LIB)\wildargs ascii build comment doit \ edit mgt parse play tree mou help ,mgt,mgt,\ $(LIB)\c$(MDL) ascii.obj: asc_ibm.inc ascii.c .c.obj: bccx -m$(MDL) -w-pia -G -Z -O -c -DMGT_IBM $*.c mgt-2.31/Prop.lst100640 1750 1750 4641 6176731471 11546 0ustar memmem Smart-Go Properties mgt supports x "B" : Black move [move] x "W" : White move [move] x "C" : Comment [Text] x "N" : Node Name [Text] "V" : Node value [number] "CH": Check mark [triple] "GB": good for black [triple] "GW": good for white [triple] "TE": good move (tesuji) [triple] "BM": bad move [triple] "BL": time left for Black [real] "WL": time left for White [real] "FG": figure [none] x "AB": add black stones [point list] x "AW": add white stones [point list] x "AE": add empty stones [point list] x "PL": player to play first [color] x "GN": game name [text] x "GC": game comment [text] x "EV": event (tournament) [text] x "RO": round [text] x "DT": date [text] x "PC": place [text] x "PB": black player name [text] x "PW": white player name [text] x "RE": result, outcome [text] x "US": user (who entered game) [text] x "TM": time limit per player [text] x "SO": source (book, journal...) [text] x "GM": game [number] (Go=1) x "SZ": board size [number] "VW": partial view [point list] "BS": black species [number] (human=0, modem=-1, computer>0) "WS": white species [number] "EL": evaluation of computer mv [number] "EX": expected next move [move, game-specific] "SL": selected points [point list, game-specific] x "M" : marked points [point list, game-specific] x "L" : letters on points [point list, game-specific] x "BR": Black's rank [text] x "WR": White's rank [text] x "HA": handicap [number] x "KM": komi [real] "TB": Black's territory [point list] "TW": White's territory [point list] "SC": secure stones [point list] "RG": region of the board [point list] mgt-2.31/README100640 1750 1750 5753 6176731457 10773 0ustar memmem----------------------------------------------------------------------- "mgt" Copyright 1991 Shodan All Rights Reserved. Program by Greg Hale Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that this entire comment and copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. No representations are made about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty. ----------------------------------------------------------------------- To compile under UNIX, type 'make' Under VMS, delete the mou.c file and then type '@build' Under MS-DOS with Borland-C, type 'make -f makefile.bc' ----------------------------------------------------------------------- *** Be sure to get the From My Go Teacher tutorial materials available *** on anonymous ftp at bsdserver.ucsf.edu ----------------------------------------------------------------------- Please send copies of extensions to: hale@scam.berkeley.edu Thanks to the following for suggestions, debugging, code writing, and testing: mgt - you know why he's here :) Kurt Wallnau - for playing and suggesting Jeff Boscole - for sleepless nights of debugging and testing Thos Sumner - for extensive help with explaining some UNIX particulars Adrian Mariano - (adrian@bsdserver.ucsf.edu) - massive code extensions, plus IBM version Tim Casey (tcasey@adobe.com) Mike Dobbins - lots of testing, suggestions and comment editor rewrite Eric Osman - for getting things to work under VMS Steve Hollasch - debugging assistance Huayong Yang - comments, bug reports Jan van der Steen - bug reports and FIXES -------------------------------------- Changes: 3/13/93 V2.3 o Rewrite of the comment editor; edits comments up to 120 lines long; additional and user settable edit control commands o No limit on size of displayable comments o Added a vi-like edit mode for the comment editor o Fixed a few parsing bugs 4/30/92 V2.2 o Increased speed of moving backwards through game record or jumping to an arbitrary node. o Tutor mode o Support for informational properties o Support for PLayer property, and passing (as a move) o Removed restriction on number of letters or marks o Detection of ko during game play o For the IBM version: Mouse support and improved display 4/5/91 V2.1 o Short format game record support o Filename wild card support o Additional comment editor features o Improved game scoring 2/1/91 V2.0 o mgt is more optimized. o IBM version support o revision of display o fixed lots of little bugs o more commands o basic editing of comments o save & load o play-by-mail facility added. 2/6/90 V1.0 o First release. All is holding together fine, but no optimization has been done yet. That is next on the list. My apologies to the CPU's. :( mgt-2.31/README.IBM100640 1750 1750 22674 6176731471 11416 0ustar memmem The IBM Implementation The IBM PC implementation has several features which are absent from the UNIX version. Keyboard Extensions The cursor keys work in the editor as cursor keys. When not in the editor, the operation of the cursor keys is controlled by the _ASCARROW environment string: _ASCARROW:CURSOR The PC arrow keys move the board cursor. _ASCARROW:TREE The PC arrow keys are used for tree traversing, right, left: down tree, up tree (like > and < respectively) up, down: last, next variation branch pgup, pgdn: last, next comment _ASCARROW:MODE The operation of the PC arrow keys change depending upon the current mgt mode: cursor control in edit mode and tree control in tutor mode Display Extensions There are three display modes for the IBM mgt: graphics mode, nographics mode, and nocolor mode Graphics mode is the default on VGA or EGA systems. The board is displayed using special graphics characters. The _ASCCHAR specification is ignored. Note that despite its name, "graphics" mode does not use graphics mode. It uses text mode and redefines the font. In nographics mode, color is used to obtain good contrast between the board and the stones. The "black stone" character is used for both white and black stones with different colors. Similarly, the "black territory" marker is used for both white and black territory. The "white stone" character and the "white territory" character are ignored. Nocolor mode is the pure text display. The default uses IBM graphics characters for the borders. In both nographics mode and nocolor mode, ascii 3 (a heart symbol) is used the default for the black stone character. To force nographics mode, put _ASCNOGRAPH in your MGT environment string. To force nocolor mode, put _ASCNOCOLOR in the environment string. In either graphics or nographics modes, the display colors can be set through these environment strings: _ASCBCOL: black stone color _ASCWCOL: white stone color _ASCDAME: dame color _ASCBOARD: board color _ASCBG: background _ASCFG: foreground _ASCMARK: mark color _ASCLET: letter color _ASCMENUFG: menu foreground _ASCMENUBG: menu background The colors are: 0 black 8 dark gray 1 blue 9 light blue 2 green 10 light green 3 cyan 11 light cyan 4 red 12 light red 5 magenta 13 light magenta 6 brown 14 yellow 7 light gray 15 white To choose the defaults, you would execute the command: set MGT=_ASCBCOL:0 _ASCWCOL:7 _ASCDAME:1 _ASCBOARD:6 _ASCBG:0 _ASCFG:0 _ASCMARK:9 _ASCLET:1 _ASCMENUFG:2 _ASCMENUBG:0 (You don't need to do this if you like the defaults.) The _ASCINV environment item will swap the foreground and background, and set the menu background to the background. This is equivalent to pressing '&' from within mgt. If you run mgt in graphics mode with a VGA, color 6 is changed to a brown shade defined by red, green and blue components: _RED:39 _BLUE:5 _GREEN:33 This color is meant to be used for the board. Other colors for color 6 can be selected by specifying different values for red, green and blue in the environment. The range is 0-63. One person thought _RED:40 _GREEN:30 _BLUE:14 with the background inverted looked better than the defaults. A CGA user suggests the following combination: _ASCBOARD:5 _ASCMARK:4 _ASCLET:2 Some text, CGA and LCD portable users may want to use the _ASCCHAR string to set the Stones and board characters to some of the "special" IBM PC characters. The black and white smilie faces may be better for some as the stone characters. There are single line and double line border characters. A "dot in the middle" character seems to work well for the empty points on the board. These characters may be entered on a PC with the following key sequence: nnn The nnn represents a 1 to 3 digit decimal value for the character entered on the numeric keypad (the number keys across the top do not work.) The following "special" values seem to work well: Black stone: 2 White stone: 1 Empty point: 249 Vert. border: 179 or 186 Horz. border: 196 or 205 Upper left: 218 or 201 Upper right: 191 or 187 Lower left: 192 or 200 Lower right: 217 or 188 The first column is for a single line border and the second column is for a double line border. The sequence of characters after "_ASCCHAR:" is: black stone (002), white stone (001), dame territory ('?'), black territory ('+'), white territory ('-'), empty points (249), hosi points ('+'), vertical border (186), horizontal border (205), upper left corner (201), upper right corner (187), lower left corner (200), lower right corner (188). In nograph mode the board border characters are ignored, but the stone, empty point, hoshi points and territory points may be set. In nocolor mode all may be set. Mouse Support The mouse cursor is an arrow in EGA or VGA modes. If you don't want the arrow, put _ASCMOUSENORM in the environment variable. The mouse can be used to click on menus, or to click on various parts of the board. The top line contains various mode listings. help quit stone walk move Clicking on help or quit gets help or quits. The third word indicates the mode for placing items on the board. In stone mode, the left mouse button plays a stone on the board, and the right mouse button sets a stone on the board. (Equivalent to space, and either z or x respectively.) The color of the stone set is determined by the player indicator in the lower right corner of the screen. Clicking on the word "stone" on the top line will change it to "mark". In this mode, the left mouse button sets or unsets letters on the board and the right mouse button sets and unsets marks. The fourth item on the top line is either "walk" or "branch" to indicate the type of game tree traversal. In walk mode, clicking with the left button anywhere on the variation window moves down the tree (like the > key). In branch mode, clicking on a specific variation visits that variation (like pressing capital letters). In branch mode clicking on blank parts of the variation window does nothing. In either of these modes, right clicking moves back up the tree. The last mode indicator on the top line identifies the menu choice. There are four different menus you can choose: move: start end var comment This is the default menu. Clicking on start or end moves to the start of the game record or the end of the current variation (like the b and e keys). Left clicking on var or comment goes to the next variation branch or the next comment. Right clicking on either one goes to the previous variation branch or comment. play: score pass player These menu items score the game, pass a move (like p key) or set the player (like the o key), actually changing the Smart-Go record to specify the current player. edit: info cut paste delnode addvar These items invoke the info, cut, paste, delete node, and add variation commands. file: save load next prev These save the game record, load a file, move to the next, or the previous file. Some loading commands are available directly from the screen. If you loaded mgt with 2 or more files, then left clicking on the filename at the upper right will move to the next file, and right clicking will move to the previous file. If you specified only one file, then clicking on the filename will load a new file (by name). To scroll the comment window or variation windows with the mouse, click on the '+' or '-' character. To edit a comment, click on the comment window. To move to a node by number, click on the word "node" above the variation window, and to set the node name, click on the node name above the variation window. To select the stone color (like the 't' key) click on the stone that is displayed on the lower right corner of the screen. At any (y/n) query, press the left button once to get a 'y' and a second time to get a return. Pressing the right button twice gets a 'n' and return. Pressing one button and then the other gets either 'y' or 'n', and then a backspace to remove the character that is there. When scoring a game, press right button to score, left button to kill, or click on the words at the bottom of the screen to undo, quit, or score. Click on the word "tutor" to leave tutor mode, and click on "read" or "edit" to enter tutor mode. Click on the word "short" or "long" to toggle the save format for Smart-Go files between short and long. The mode line above the board and the menu line below the board are omitted if a mouse is not detect on the PC. All of the functions performed with the mouse have equivalent key commands. Conversion to Short Format A batch file called "mgtshort.bat" is included with mgt. You invoke it as mgtshort filespec where the filespec is either a single file or single wildcard specification. The batch file then invokes mgt on each file, and instructs mgt to save the file in short format. This removes any data from the file which mgt did not recognize. Be careful with this program, since it will destroy any files which are not Smart-Go. To install it, you need to edit the file mgtshort.bat to refer to the permanent location of the mgtshort.cmd file. mgt-2.31/Rules100640 1750 1750 55604 6176731470 11143 0ustar memmemThis files contains rules to the game of Go in Smart-Go format. It should be viewed with the mgt program. ( ; GaMe[1] VieW[] SiZe[19] Comment[ THE GAME OF GO A Brief Introduction by Adrian Mariano press . to move forward press , to move backward ] ; 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.] ; 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.] ; Comment[When a player has nothing left to do, he passes. After two consecutive passes, the game is over.] ; Comment[An empty intersection adjacent to a stone \(orthogonally\) is called a liberty. 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.] AddWhite[jj][js][ss] Mark[ij][ji][kj][jk][is][jr][ks][rs][sr] AddEmpty[aa] ; AddBlack[dc][dd][ed][fd][fe][ge] 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.] AddWhite[in][io][jn][jo][kl][km][ll][lm] Mark[ff][gf][he][gd][ee][de][cd][fc][ec][cc][db] 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] ; AddBlack[ij][ji][jj] 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] Comment[A group is captured if its last liberty is taken away. Here is a black group with seven liberties.] ; AddWhite[hj] Comment[A single white stone next to the group reduces it to six liberties.] ; AddWhite[ik][jh][jk][ki][kj] 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.\)] ; White[ii] Comment[The final white move captures the black group.] ; AddWhite[qh][qi][qj][rg][rk][sg][sk] AddBlack[rh][ri][rj][sh][sj] AddEmpty[aa][hj][ii][ik][jh][jk][ki][kj] Comment[The black group has only one liberty. White can capture the black group by playing inside black at T11.] ; White[si] ; AddBlack[rh][ri][rj][sh][sj] 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.] AddWhite[qh][qj][rg][rk][sg][sk] AddEmpty[aa][qi][si] ; Comment[Another rule of Go is the Ko rule. It is illegal to make a move which recreates preceeding board positions \(to prevent loops\). Suppose black captures the white stone at J12.] AddBlack[hh][ig][ii] AddWhite[ih][jg][ji][kh] 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] ; Black[jh] Comment[If white were allowed to play at J12 now, the board would look exactly as it did before.] ; AddEmpty[jh] AddWhite[ih] 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.] ; AddEmpty[aa][hh][ig][ih][ii][jg][ji][kh][ph][qh][qj][rg][rh][ri][rj][rk][sg][sh][sj][sk] 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. A liberty which is inside a group and completely surrounded is called an eye. A group with two disconnected eyes cannot be captured.] ; AddBlack[ic][id][ie][jc][je][jj][jk][jl][kc][kd][ke][kj][kl][lc][le][lj][lk][ll][mc][md][me] 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] AddEmpty[aa][hb][hf][ii][im][mi][mm][nb][nf] 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. 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.] ; White[kk] ; AddWhite[aq][ar][bq][bs][cq][cr][cs] AddBlack[ap][bp][cp][dp][dq][dr][ds] 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] 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.] ; 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.\)] AddBlack[ap][bp][cp][cq][cr][cs] AddWhite[ao][bo][co][do][dp][dq][dr][ds] AddEmpty[aa][aq][ar][bq][br][bs] ; AddBlack[ao][bo][co][do][eo][fo][go][ho][hp][hq][hr][hs] AddWhite[ap][bp][cp][cr][dp][dq][dr][ds][ep][fp][gp][gq][gr][gs] 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. ] AddEmpty[aa][cq][cs] ; AddBlack[af][al][bf][bg][bk][bl][cg][ch][ci][cj][ck][ga][gb][gc][hc][ic][jc][kc][lc][ma][mb][mc] AddWhite[ag][ai][ak][bh][bi][bj][ha][hb][ib][ja][jb][kb][la][lb] 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] 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!] ; 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.] Black[ah] ; Black[aj] ; Comment[Here is another example of a DEAD group. The white group at the bottom does NOT have two eyes.] AddBlack[lp][lq][lr][ls][mp][np][op][oq][or][pp][qp][rp][sp][sq][sr] AddWhite[mr][ms][nr][os][pq][pr][ps][qq][rq][rr][rs] 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] ; AddWhite[ar][br][cr][cs] AddBlack[aq][bq][cq][dq][dr][ds] 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] Comment[In this example, the white group is dead. There is nothing white can do to prevent black from capturing it.] ; Black[bs] ; White[as] ; Black[bs] 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.] ; AddWhite[ar][br][cr][dr][ds] AddBlack[eq][er][es] AddEmpty[aa][bs] Comment[This case is more complicated. If white plays first, then the group has two eyes and lives.] ; White[bs] ; Comment[On the other hand, if black plays first, the group is killed. ] AddEmpty[aa][bs] ; Black[bs] ; White[cs] ; Black[as] ; Comment[In this case, the white group is alive, even if black plays first.] AddWhite[ar][br][cr][dr][er][es] AddBlack[aq][fq][fr][fs] AddEmpty[aa][as][bs][en] ; Black[cs] ; White[bs] ; 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.\)] AddBlack[ap][bp][cp][dp][dq][eq][er][es] AddWhite[aq][bq][cq][cr][ds] AddEmpty[aa][ar][bn][br][bs][cs] ; Black[bs] ; White[br] ; Black[as] ; White[cs] ; Black[ar] ; AddWhite[ao][bo][co][do][dp][dq][dr][ds] AddBlack[ap][bp][cp][cq][cr][cs] AddEmpty[aa][aq][ar][as][bq][bs][eq][er][es][fq][fr][fs] 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.] ; Black[br] ; White[ar] ; Black[aq] ; White[bs] ; Black[as] ; AddEmpty[aa][aq][ar][as][br][es] Comment[If, however, white plays first, white can kill the black group.] ; White[br] ; Black[bs] ; White[ar] ; Black[aq] ; White[as] ; Black[bq] ; White[ar] ; Black[br] ; White[as] ; 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] 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] AddEmpty[aa][ao][as][bo][co][do][dp][sh] 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.] ; 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] 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] 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?] 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] ; 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] Comment[If there is debate over who owns a territory, or whether a group is alive, simply continue play until the players agree.] ; AddBlack[an][ap][bn][bo][bp][br][bs][cp][cs][dp][ds][ep][er][es][fp][gp][gq][gr][gs][hr][ir][is] AddWhite[aq][ar][as][bq][cq][dq][eq][fq][fr][fs] AddEmpty[ai][aj][ak][al][am][bi][bj][bk][bl][bm][cr][dr] 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. The reason is that neither black nor white can make a move in the region. ] ( ; White[cr] Comment[If white attempts to capture black by playing inside...] ; Black[dr] Comment[Then black captures the white stones.] ) ( ; Comment[If black tries to capture white by moving inside...] Black[cr] ; Comment[Then white captures black, and now the white group is alive. ] White[dr] ; 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.] ; 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] 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?] AddWhite[bh][bi][bj][bn][cj][cm][cn][dk][dl] AddBlack[bf][bk][bl][bm][cf][cg][ch][ci][ck][di][dj] ; White[am] ; Black[bg] ; White[al] ; Black[ah] ; White[ak] ; Black[ai] ; White[cl] ; Black[ag] ; White[aj] ; 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.] 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] AddBlack[aq][bq][cq][cr][dq][eq][fq][gq][gr][gs] AddWhite[ar][br][bs][dr][ds][er][fr][fs] ( ; Black[cs] Comment[If black plays here, then the two white groups will die, since each has only one eye.] ) ( ; White[cs] Comment[If white plays C1, then his stones are connected into one group which has two eyes.] ; AddEmpty[aa][aq][ar][bq][br][bs][cq][cr][cs][dq][dr][ds][eq][er][fq][fr][fs][gq][gr][gs] 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.] ; Comment[In this situation, the black stones can be considered connected, even though they are not yet orthogonally connected directly.] 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] AddBlack[ai][ak][bi][bj][bk][cj][dj][ej][fk][gk][hj][hk][hl][ij][il][jj][jk][jl] 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] ; Comment[If white threatens to disconnect the black stones...] White[fj] ; Comment[...black always has a response which connects his stones. ] Black[ek] ; AddBlack[lm][lp][mm][mp][nm][np] Comment[Here is another strong connection that cannot be cut.] AddWhite[io][jo][ko][ln][lo][nn][no][on][pn][qn] 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] ; Comment[If black tries to disconnect the white stones...] Black[mo] ; Comment[...as with the diagonal connection, white always has a response which directly connects his stones. \(This is called a bamboo connection\)] White[mn] ; Comment[There are several other weaker connections which can be cut. ] 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] ; 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. The marked locations are the cutting points -- the moves white would make to disconnect black.] Mark[fo][fb][fe][gh][fk] 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] 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] ; 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.] AddBlack[bp][cp][dp][dq][dr][ph][pm][pn][po][pp][pq][qi][qq][qr][qs][ri][rj][rk][rs][si][sl] AddWhite[bm][bo][co][do][eo][ep][eq][er][gr][oj][ok][ol][pl][ql][qn][rl][rn][ro][rp][rq][sq] 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] ; White[br] ; Black[ar] ; White[cr] ; Black[ds] ; White[ap] ; Black[aq] ; White[ao] ; Black[bq] ; White[cs] ; Black[bs] ; Comment[We have reached a Ko situation. Black may not retake the white stone at A1. Black may, however, attack the white formation on the right side of the board.] White[as] ; 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.] Black[qm] ( ; Name[On the right] Comment[White will now respond on the right, connecting the white groups together.] White[rm] ; Black[bs] ; 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.\)] White[sm] ; Black[cq] Comment[The black group lives.] ) ( ; Comment[White plays in the corner, planning to kill the group on the left.] Name[In the corner] ; White[bs] ; Black[cq] ; Comment[The black stones are dead.] White[bs] ; Comment[But black gets to cut off the white stones.] Black[rm] ; Comment[Suppose black wants to capture the white stone. ] AddBlack[dm][em][fn] AddWhite[en] 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] ( ; Comment[If black plays here...] Black[dn] ; Comment[...white escapes downward. This is not the correct approach.] White[eo] ) ( ; Comment[Instead, black should play here. This starts a pattern called the "ladder," a very common occurrence in go games.] Black[eo] ; Comment[The only direction white can go is leftwards. However, observe the sequence that follows. ] White[dn] ; Black[cn] ; White[do] ; Black[dp] ; White[co] ; Black[bo] ; White[cp] ; Black[cq] ; White[bp] ; Black[ap] ; White[bq] ; Black[br] ; White[aq] ; Comment[Each of the moves is forced, and white is unable to save the stones. White must be able to recognize this, so he can avoid playing this sequence and losing such a large group of stones.] Black[ar] ; Comment[The outcome is very different if white has a stone in the path of the ladder.] AddBlack[fn] AddWhite[bo][en] AddEmpty[aa][ap][ar][br][cn][co][cq][dn][dp][eo] ; Black[eo] ; White[dn] ; Black[cn] ; White[do] ; Black[dp] ; White[co] ; Black[cm] ; White[ep] ; Black[fo] ; Comment[Black fails to capture white in this case.] White[dq] ; Comment[In this case, white wishes to capture the black stone. ] AddWhite[jh][ji][jj][kj][lj] AddBlack[ki] AddEmpty[aa][bo][cm][cn][co][dm][dn][do][dp][dq][em][en][eo][ep][fn][fo][iq] ; Comment[To do so, white plays here.] White[lh] ; Black[li] ; White[mi] ; Black[kh] ; White[kg] ; AddEmpty[aa][jh][ji][jj][kg][kj][lh][lj][mi] 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.] ; 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] 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.] ; 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] 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.] Black[pp] ; White[qq] 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.] ; AddBlack[qq] AddEmpty[aa][pp] Comment[Opening at the 3,3 point insures ownership of the corner but has less potential for extension into the center.] ; AddBlack[de][pq] AddEmpty[aa][qq] Comment[Other good openings are the 5,4 point and the 3,4 point.] ; Comment[From either of these openings, black can make a corner enclosure so get corner territory.] AddBlack[dc][qo] ; Comment[And then extend along the side, staking out side territory.] AddBlack[ic][kq] ; AddEmpty[dc][de][ic][kq][pq][qo] AddBlack[dd][dj][dp][jj][pd][pj][pp] Comment[Go players use a handicap system to balance games between players of different skill. The weaker player starts by placing from two to nine stones on the board in a special configuration on the handicap points. This is a seven stone handicap.] ; AddEmpty[aa][dd][dj][dp][jj][pd][pj][pp] Comment[Playing strength of amateurs is measured on a scale where one unit corresponds to a handicap stone. A total beginner is 35 kyu, and will very quickly improve to 20 kyu. A player will reach 10 kyu after playing about 100 games. Ranks worse than 10 kyu are unreliable because playing is too uneven and players progress too quickly to get a stable rating.] ; Comment[Beyond the kyu ranks are the amateur dan ranks which go from 1 dan to 6 dan, the highest amateur rank. 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.] ; 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. ] ; 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.\)] ; 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.] ; 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. Computer go programs are presently very weak -- they are ranked around 10 kyu] ) ) ) ) ) mgt-2.31/Sample.01100640 1750 1750 4516 6176731466 11472 0ustar memmem( ; GaMe[1] VieW[] SiZe[19] Comment[A game between two amateurs both ranked betwen 10 kyu and 15 kyu Result: with no komi, black wins by 4] ; Black[pd] ; White[qp] ; Black[dp] ; White[dc] ; Black[op] ; White[po] ; Black[lp] ; White[pl] ; Black[de] ; White[cd] ; Black[ed] ; White[ce] ; Black[cf] ; White[ec] ; Black[ci] ; White[fd] ; Black[fe] ; White[gd] ; Black[ph] ; White[qi] ; Black[nc] ; White[cn] ; Black[dn] ; White[cp] ; Black[co] ; White[bo] ; Black[do] ; White[dq] ; Black[bp] ; White[bq] ; Black[ap] ; White[cq] ; Black[bn] ; White[ep] ; Black[eo] ; White[fq] ; Black[fp] ; White[eq] ; Black[gp] ; White[gq] ; Black[hq] ; White[hp] ; Black[ho] ; White[iq] ; Black[ip] ; White[hr] ; Black[jq] ; White[ir] ; Black[jr] ; White[go] ; Black[gn] ; White[io] ; Black[hn] ; White[hp] ; Black[fo] ; White[jp] ; Black[kq] ; White[jn] ; Black[kd] ; White[jc] ; Black[kc] ; White[jd] ; Black[lg] ; White[ke] ; Black[le] ; White[kf] ; Black[lf] ; White[if] ; Black[gg] ; White[ge] ; Black[ff] ; White[jh] ; Black[hj] ; White[jk] ; Black[mk] ; White[pq] ; Black[oq] ; White[qh] ; Black[qg] ; White[pi] ; Black[oh] ; White[oi] ; Black[ni] ; White[nh] ; Black[ng] ; White[nj] ; Black[mh] ; White[mj] ; Black[lm] ; White[kp] ; Black[lo] ; White[lq] ; Black[lr] ; White[js] ; Black[mq] ; White[oo] ; Black[no] ; White[nn] ; Black[nm] ; White[mn] ; Black[lj] ; White[mi] ; Black[li] ; White[mo] ; Black[np] ; White[nk] ; Black[ml] ; White[nl] ; Black[mm] ; White[om] ; Black[il] ; White[hh] ; Black[gh] ; White[gf] ; Black[kg] ; White[jg] ; Black[ii] ; White[bf] ; Black[df] ; White[cg] ; Black[dg] ; White[bh] ; Black[ch] ; White[bg] ; Black[bi] ; White[gi] ; Black[hi] ; White[dd] ; Black[ee] ; White[hg] ; Black[fg] ; White[ji] ; Black[gj] ; White[nh] ; Black[pg] ; White[aq] ; Black[ao] ; White[jl] ; Black[kl] ; White[im] ; Black[hl] ; White[ln] ; Black[pr] ; White[qr] ; Black[ps] ; White[qs] ; Black[or] ; White[km] ; Black[ko] ; White[lk] ; Black[kk] ; White[ll] ; Black[kj] ; White[jj] ; Black[jo] ; White[rg] ; Black[rf] ; White[rh] ; Black[ip] ; White[hq] ; Black[in] ; White[kn] ; Black[hm] ; White[kb] ; Black[lb] ; White[ka] ; Black[la] ; White[jb] ; Black[lc] ; White[ih] ; Black[ah] ; White[ag] ; Black[ai] ; White[be] ; Black[sg] ; White[sh] ; Black[ks] ; White[is] ; Black[ik] ; White[kh] ; Black[lh] ; White[jm] ; Black[sf] ; White[ni] ; Black[pp] ; White[qq] ) mgt-2.31/Sample.02100640 1750 1750 7317 6176731466 11475 0ustar memmem( ; GaMe[1] SiZe[19] VieW[] Comment[16th Honinbo League Playoff White: Sakata Eio 9-dan Black: Kitani Minoru 9-dan Komi: 4 1/2 Result: White wins by 3 1/2 points] Black[qd] ; White[dc] ; Black[pq] ; White[cq] ; Black[oc] ; White[po] ; Black[qo] ; White[qn] ; Black[qp] ; White[pm] ; Black[nq] ; White[qi] ; Black[ce] ; White[dh] ; Black[ee] ; White[cb] ; Black[cc] ; White[gc] ; Black[bc] ; White[bb] ; Black[qg] ; White[dd] ; Black[de] ; White[cg] ; Black[co] ; White[cm] ; Black[ep] ; White[do] ; Black[dp] ; White[cp] ; Black[dn] ; White[bo] ; Black[eo] ; White[cn] ; Black[el] ; White[dk] ; Black[ql] ; White[rm] ; Black[rj] ; White[qe] Comment[Complications start. Creating two weak groups. ] ; Black[qj] ; White[rd] ; Black[qc] ; White[qf] ; Black[pg] ; White[rc] ; Black[rb] ; White[oe] ; Black[mc] ; White[op] ; Black[on] ; White[pn] ; Black[oq] ; White[mo] ; Black[mp] Comment[Severe attack. ] ; White[lo] Comment[Counters aggressively. ] ; Black[no] ; White[np] ; Black[nm] Comment[Black cuts. Brings on crisis.] ; White[pj] ; Black[pi] ; White[pk] ; Black[rl] ; White[ml] ; Black[nl] ; White[nk] ; Black[mk] ; White[om] Comment[Exquisite shinogi tesuji. Lets W secure his endangered group] ; Black[nj] ; White[ok] ; Black[ll] ; White[lp] ; Black[mq] ; White[mn] ; Black[mm] ; White[nn] ; Black[rf] Comment[Turns toward other weak group. ] ; White[re] ; Black[rg] ; White[nd] ; Black[nc] ; White[nf] ; Black[nh] ; White[lf] ; Black[le] ; White[mh] ; Black[mi] ; White[me] ; Black[mg] ; White[ld] ; Black[ke] ; White[md] ; Black[kb] ; White[kc] ; Black[jb] ; White[id] ; Black[kf] ; White[oi] ; Black[ph] ; White[jc] Comment[Manages to rescue weak group. ] ; Black[ib] ; White[fd] ; Black[eg] ; White[lg] Comment[Double attack.] ; Black[lh] ; White[kg] ; Black[if] ; White[hg] ; Black[hf] ; White[gf] ; Black[ge] ; White[fe] ; Black[jg] ; White[he] Comment[First time that B is the one under pressure.] ; Black[gg] ; White[ff] ; Black[dg] ; White[ef] ; Black[df] ; White[fg] ; Black[ch] ; White[bh] ; Black[ci] ; White[bf] ; Black[ei] ; White[cj] ; Black[gh] ; White[fh] ; Black[eh] ; White[dj] ; Black[di] ; White[bi] ; Black[fi] ; White[gi] ; Black[gj] ; White[hh] ; Black[ii] ; White[mf] ; Black[jh] Comment[Fight ends. ] ; White[er] Comment[W has taken the lead.] ; Black[fk] ; White[ro] ; Black[rp] ; White[fq] ; Black[in] ; White[go] ; Black[gn] ; White[jn] ; Black[jm] ; White[fn] ; Black[hn] ; White[fo] ; Black[en] ; White[fm] ; Black[dl] ; White[cl] ; Black[hl] ; White[km] ; Black[jl] ; White[lq] ; Black[ip] ; White[lr] ; Black[hq] ; White[os] ; Black[or] ; White[gq] ; Black[dq] ; White[dr] ; Black[be] ; White[hb] ; Black[ic] ; White[sb] ; Black[ra] ; White[ie] ; Black[hc] ; White[gb] ; Black[gr] ; White[hi] ; Black[hj] ; White[ns] ; Black[ps] ; White[mr] ; Black[pp] ; White[oo] ; Black[rr] ; White[ej] ; Black[fj] ; White[ir] ; Black[hr] ; White[jr] ; Black[jo] ; White[kn] ; Black[ab] ; White[qk] ; Black[rk] ; White[oj] ; Black[ia] ; White[jp] ; Black[fr] ; White[iq] ; Black[hp] ; White[eq] ; Black[af] ; White[kl] ; Black[kk] ; White[ko] ; Black[ag] ; White[kh] ; Black[ki] ; White[bg] ; Black[gm] ; White[ng] ; Black[mh] ; White[sl] ; Black[so] ; White[rn] ; Black[hd] ; White[gd] ; Black[lm] ; White[ri] ; Black[si] ; White[sf] ; Black[sg] ; White[io] ; Black[ho] ; White[cd] ; Black[bd] ; White[pd] ; Black[pc] ; White[se] ; Black[nr] ; White[ms] ; Black[ha] ; White[ga] ; Black[lc] ; White[kd] ; Black[ed] ; White[ec] ; Black[fl] ; White[ah] ; Black[ae] ; White[je] ; Black[jf] ; White[ni] ; Black[mj] ; White[ih] ; Black[sc] ; White[sd] ; Black[od] ; White[pf] ; Black[db] ; White[eb] ; Black[ba] ; White[da] ; Black[do] ; White[hs] ; Black[og] ; White[of] ; Black[es] ; White[ds] ; Black[fs] ; White[jo] ; Black[ac] ; White[pe] ) mgt-2.31/Smart-Go.def100640 1750 1750 24145 6176731456 12237 0ustar memmem DEFINITION OF THE SMART-GO FORMAT From the Dissertation of Anders Kierulf "Smart Game Board: a Workbench for Game-Playing Programs, with Go and Othello as Case Studies" Entered by Greg Hale with permission for distribution. See the many sample files from the 'My Go Teacher' series for examples. ------------ A standard file format to exchange machine-readable games, problems, and opening libraries would save time and work. That goal may not be too far away. A standard for exchanging collections of Othello games is being worked out by Erik Jensen, Emmanuel Lazard, and Brian Rose in collaboration with the author. For Go, a new standard has recently been proposed [Connelley 89, High 89]; it seems to suffer from a wealth of features, but any standard for exchanging Go games is welcome, and will be supported by the Smart Game Board. The current file format is specialized for the needs of the Smart Game Board. It is based on an earlier proposal for a standard for Go games [Kierulf 87b] which was not widely adopted. The following description is not a new proposal; it is intended for those who want to read or white files that are compatible with the Smart Game Board. The game collections (documents) of the Smart Game Board are stored as text files. This has the advantage that files can be manipulated with standard text utilities, and that it's easier to exchange games by electronic mail. The disadvantage is that text files are less compact than binary files. The Smart Game Board stores the game trees of each document, with all their nodes and properties, and nothing more. Thus the file format reflects the regular internal structure of a tree of property lists. There are no exceptions; if a game needs to store some information on file with the document, a (game-specific) property must be defined for that purpose. I will first define the syntax of the game collections, then discuss syntax and semantic of various properties. GAME COLLECTIONS A collection of game sis simply the concatenation of the game trees. The structure of each tree is indicated by parentheses. A tree is written as "(" followed by a sequence of nodes (as long as the tree is unbranched) and a tree for each son, and terminated by ")". Each node is preceded by a separator, and contains a list of zero or more properties. Thus the main branch of the game is stored first in the file, and programs can easily read that part (until the first closing parenthesis) and ignore the rest. The conventions of EBNF are discussed in [Wirth 85]. A quick summary: "..." : terminal symbols [...] : option: occurs at most once {...} : repetition: any number of times, including zero (...) : grouping | : exclusive-or The overall definition of the file format is as follows: Collection = {GameTree}. GameTree = "(" Sequence {GameTree} ")". Sequence = Node {Node}. Node = ";" {Property} Any text before the first opening parenthesis is reserved for future extensions and is ignored when reading a file. Spaces, tabs, line breaks and so on can be inserted anywhere between properties and are also ignored. GAME-INDEPENDENT PROPERTIES Each property is identified by one or two capital letters. The property value is enclosed in brackets; lists of points or integers are written as a sequence of property values. Within text, a closing bracket is prefixed by a backslash, and a backslash is doubled. Moves and points are game-specific and are defined later. Property = PropIdent PropValue {PropValue}. PropIdent = UpperCase [UpperCase | Digit]. PropValue = "[" [Number | Text | Real | Triple | Color | Move | Point | ... ] "]" Number = ["+" | "-"] Digit {Digit}. Text = { any character; "\]" = "]", "\\" = "\"}. Real = { Number ["." {Digit}]. Triple = ("1" | "2"). Color = ("B" | "W"). Move and Point are game-specific and are described later. The following properties are understood by all games. The property type is given in brackets. "B" : Black move [move, game-specific] "W" : White move [move, game-specific] "C" : Comment [Text] "N" : Node Name [Text] The purpose of providing both a node name and a comment is to have a short identifier like "doesn't work" or "Dia. 15" that can be displayed directly with the properties of the node, even if the comment is turned off or shown in a separate window. There is no limit to the length of texts; programs must be able to ignore the rest of texts that are too long for them to handle. Reasonable limits are 32 characters for node names and at least 2000 characters for comments. "V" : Node value [number] Positive values are good for Black, negative values are good for White. The interpretation of particular values is game-specific. "CH": Check mark [triple] "GB": good for black [triple] "GW": good for white [triple] "TE": good move (tesuji) [triple] "BM": bad move [triple] The normal value for such properties is one, properties that are doubled for emphasis have the value two. "BL": time left for Black [real] "WL": time left for White [real] All times are given in seconds, or fractions thereof {Hale: these can be negative, indicating player is playing past time limit set}. "FG": figure [none] The figure property is used to divide a game into different figures for printing: a new figure starts at the node with a figure property. "AB": add black stones [point list, game specific] "AW": add white stones [point list, game specific] "AE": add empty stones [point list, game specific] "PL": player to play first [color] The above properties are used to set up positions in games with only black and white stones. The following properties are all part of the game info: "GN": game name [text] "GC": game comment [text] "EV": event (tournament) [text] "RO": round [text] "DT": date [text] "PC": place [text] "PB": black player name [text] "PW": white player name [text] "RE": result, outcome [text] "US": user (who entered game) [text] "TM": time limit per player [text] "SO": source (book, journal...) [text] The format in these game-info strings is free, but to be able to search for specific games in game collections, it is recommended to adhere to the following conventions: - Date is ISO-standard: "YYYY-MM-DD". - Result as "0" (zero) for a draw, "B+score" for a black win, and "W+score" for a white win, e.g. "B+2.5", "W+64" - Time limit as a number, in minutes. In addition, names, events, and places should be spelled the same im all games. The following properties may only be present at the root node: "GM": game [number] (Go=1, Othello=2, chess=3, Nine Mens Morris=5) "SZ": board size [number] "VW": partial view [point list, game-specific] "BS": black species [number] (human=0, modem=-1, computer>0) "WS": white species [number] The game number helps the program reject games it cannot handle (this property was mandatory as long as an application could play different games). The view gives two corner points of a rectangular subsection; an empty list denotes the whole board. The species denotes the kind of player (the source of the more input), with different version of computer algorithms denoted by positive numbers (default algorithm = 1). Computer algorithms may add the following properties: "EL": evaluation of computer move [number] "EX": expected next move [move, game-specific] Some games support markings on the board: selected points, triangles/crosses, or letters (a sequence of letters is shown on the points given in the list, starting with "A"): "SL": selected points [point list, game-specific] "M" : marked points [point list, game-specific] "L" : letters on points [point list, game-specific] GO-SPECIFIC PROPERTIES In my proposal for a standard [Kierul 87b], I intentionally broke with the tradition of labeling moves (and points) with letters "A"-"T" (excluding "i") and numbers 1-19. Two lowercase letters in the range "a"-"s" were used instead, for reasons of simplicity and compactness. This was criticized mainly because it was not human-readable, but as that is not an important feature of this file format, I continue to use that notation. (Hale: diagram omitted) The first letter designated the column (left to right), the second the row (top to bottom). The upper left part of the board is used for smaller boards, e.g. letters "a"-"m" for 13*13. (Column before row follows the principle "horizontal before vertical" used in x-y coordinate systems. The upper left corner as origin of the board corresponds to the way we read, and most modern computers use it as origin of the screen coordinates to simplify integration of text and graphics.) A pass move is written as "tt". The board must be quadratic, no smaller than 2x2, and no larger than 19x19. Additional game info properties are defined for Go: "BR": Black's rank [text] "WR": White's rank [text] "HA": handicap [number] "KM": komi [real] Sets of board points can be marked as territory, as secure stones, or just as a region of the board (e.g. to designate eye space): "TB": Black's territory [point list] "TW": White's territory [point list] "SC": secure stones [point list] "RG": region of the board [point list] mgt-2.31/Spec.io100640 1750 1750 10337 6176731462 11344 0ustar memmem INTERFACE SPECIFICATION FOR MGT If you wish to add a new interface to mgt, these are the functions you need to come up with. void open() Initialize interface. Any *interface* specific initialization is done here. void close() Leave the interface. void refreshIO() update screen to look like memory image. Somewhat curses specific. Probably will be a null function null(){} in most interfaces. void plotPiece(pBoard b, int i, int j) Plots the piece contained in b at i,j on the real screen. Board is read by call boardGet(b, i, j) which returns one of P_NOTHING, P_BLACK, P_WHITE, P_DAME, P_BLACKTERR, or P_WHITETERR. void clearComment() Clears comment window void initBoard() Draw a blank board of size 'boardsize' void clearScreen() clears screen. int idle(nodep n) Gets the next command. Acts like an event driven loop. Waits for keystroke. Returns a command casted to an int to indicate the command for doit.c to process. void drawTree(nodep n) Show the variations that are available in the var list on the right when starting at node n. (in Ascii version) Interface-local variables exists to handle scrolling. scrolling should be handled by the interface alone. void highlightLast(int x, y, movenum, turn) Show last move number, current turn, whose move it is, and the prisoner count. turn==0 means Black just moved. If x and y are equal to PASSVAL then the move was a pass. Use these to get current player turn and prisoner count extern int prisoners[black=0,white=1] ; extern int curPlayer; void readEnv(char **env) Check *env for environment string. Increment it to point to the first character not used. void notifyMessage(char *s) Print single line message someplace. void notifyClear() Clear notify message area int queryStr(char *query, char *dst, int maxLen) Print query out. Get at most maxLen chars into dst. Return length of the result. void setCursor(int i, int j) Move cursor (pointer) to position i,j on go board void plotMark(pBoard b,int i,int j) Plot mark at position i,j on displayed board. DOES NOT modify *b. Mark is erased by call to plotPiece void plotLetter(int i, int j, char c) Puts letter c on the screen at board position i,j int getPoint() Allow user to specify a board position (Cursor keys, mouse, etc) Used when scoring the game. Uses globals xcur and ycur to store the position. The return value can be C_QUIT to abort score. C_SCORE to calculate the score. C_REDRAW to redraw screen, or C_NOTHING to kill the group we're on right now. void editComment(char *inp, char **out) Edit a comment. inp contains the input comment to be edited. THIS MUST BE free()'d. out contains the return pointer. It should be allocated to the appropriate size and the new edited comment should be placed in the allocated space. int askYN(char *query, int defalt) Prompt user with query. The query will NOT end in " (y/n)? " If needed by the interface, this should be added here. Returns 1 for yes, 0 for no. defalt contains the default response (1 for yes, 0 for no). void notifyError(char *errormsg) Display error message. Give user a chance to see it, and clear message. void displayInfo(char *s) Formats and displays string s as a list of game information. Each informational item starts on its own line but may contain newlines. Token getInfoToChange() Passes back an informational token to change, or t_EOF to escape from the info editor. (Scrolling of the info region should be handled internally here.) void editInfo(char *input, char **output, property info_item) Edits the info item corresponding to info_item. The current text is given in input which should be freed. The replacement text should be put in *output which needs to be allocated by this function. (This works like the comment editor.) mgt-2.31/asc_ibm.inc100640 1750 1750 53625 6176731441 12215 0ustar memmem/* "mgt" Copyright (c) 1991 Shodan */ char chars[] = "\3O?+-\372.\263\304\332\277\300\331"; char graphchar[] = "\2O?\17.\305\307\335 "; int graphicalCursor = 1; int graphics = 1; int usecolor = 1; int boardcolor = 6; int blackstone = 0; int damecolor = 1; int whitestone = 7; int background = 0; int foreground = 7; int markcolor = 9; int lettercolor = 1; int menufg = 2; int menubg = 0; int branchmode = 0; int stonemode = 1; int bred = /* 0x3f; 63 44 40; */ 39; int bblue = /* 0x16; 22 15 14; */ 5; int bgreen = /* 0x2e; 46 32 30; */ 33; int fixfont = 0; int menu = 0; int cursorkey = 0; /* 0 tree mode 1 movement 2 variable */ char *stoneModeName[] = {"mark", "stone"}; char *branchModeName[] = {"walk", "branch"}; char *menumode[] = {"move", "play", "edit", "files"}; #define MENUITEMS 4 /* 6789012345678901234567890123456789012345 */ char *menulines[] = {" start end var comment ", " score pass player ", "info cut paste delnode addvar", " save load next prev "}; struct { char bottom, top; } menubounds[4][5] = { {{ -1, -1 }, { 10, 14 }, { 17, 19 }, { 22, 24 }, { 27, 33 } }, {{ -1, -1 }, { 13, 17 }, { 20, 23 }, { 26, 31 }, { -1, -1 } }, {{ 6, 9 }, { 12, 14 }, { 17, 21 }, { 24, 30 }, { 33, 38 } }, {{ -1, -1 }, { 11, 14 }, { 17, 20 }, { 23, 26 }, { 29, 32 } } }; #include #include #include "mou.h" #define doredraw() #define move(Y, X) gotoxy((X)+1, (Y)+1) #define mvaddstr(Y, X, STRING) gotoxy((X)+1, (Y)+1), cputs(STRING) #define mvprintw(Y, X, STRING) gotoxy((X)+1, (Y)+1), cputs(STRING) #define mvaddch(Y, X, CHAR) gotoxy((X)+1, (Y)+1), putch(CHAR) #define addch(CHAR) putch(CHAR) #define printw cprintf #define clrtoeol() clreol() #define clear() clrscr() #define refresh() #define wrefresh(win) #define wmove(win,y,x) move(y,x) #define waddch(win,c) addch(c) #define mvwaddch(win,y,x,c) mvaddch(y,x,c) #define waddstr(win,c) cputs(c) #define wclrtoeol(win) clreol() #define closewin() window(1,1,80,25) #define xpos(w) (wherex()-1) #define ypos(w) (wherey()-1) #define WINDOW char #define openwin() win=0,window(WINLEFT+1,WINTOP+1,WINRIGHT+1,WINBOT+2),clear() #define fixcursor() if (ypos(win)>WINHIGH) wmove(win,WINHIGH,WINWIDE); #define preserveScreen() char screen[160][25];gettext(1,1,80,25,&screen) #define restoreScreen() puttext(1,1,80,25,&screen) #define restoreRegion(x1,y1,dx,dy) puttext(x1+1,y1+1,x1+1+dx,y1+dy,savearea) #define saveRegion(x1,y1,dx,dy) gettext(x1+1,y1+1,x1+1+dx,y1+dy,savearea) #define normalize(c) (c) #define set_inverse() #define unset_inverse() #define mainwin() closewin() #define unmainwin() window(WINLEFT+1,WINTOP+1,WINRIGHT+1,WINBOT+2) void wclrtobot(win) int *win; { int savex, savey, y; savex = wherex(); savey = wherey(); clreol(); for (y = savey + 1; y <= WINBOT + 2; y++) { gotoxy(1, y); clreol(); } gotoxy(savex, savey); } static unsigned char far *getfont() { struct REGPACK regs; regs.r_ax = 0x1130; regs.r_bx = 0x0600; intr(0x10, ®s); return (unsigned char far *) MK_FP(regs.r_es, regs.r_bp); } static void setfont(unsigned char far * newfont) { struct REGPACK regs; regs.r_cx = 256; regs.r_bx = 0x1000; regs.r_dx = 0; regs.r_ax = 0x1100; regs.r_es = FP_SEG(newfont); regs.r_bp = FP_OFF(newfont); intr(0x10, ®s); } static void endwin() { closewin(); if (graphics && isegavga()) setfont(getfont()); normvideo(); MOUdeinit(); clrscr(); if (fixfont) { _AX = 0x1112; _BL = 0; geninterrupt(0x10); } } static void setcolor(bg, fg) int bg, fg; { if (usecolor) textattr((bg << 4) + fg); } static void drawPrisoners() { extern int ispl; char a, b, c, d; if (curPlayer == t_Black) { a = ispl ? '\20' : '>'; b = ispl ? '\21' : '<'; c = d = ' '; } else { a = b = ' '; c = ispl ? '\20' : '>'; d = ispl ? '\21' : '<'; } move(23, 49); if (usecolor) { setcolor(boardcolor, blackstone); printw(" %c %c: %d %c ", a, chars[CHAR_BLACK], prisoners[0], b); setcolor(boardcolor, whitestone); printw("%c %c: %d %c ", c, chars[CHAR_BLACK], prisoners[1], d); setcolor(background, foreground); } else printw(" %c %c: %d %c %c %c: %d %c ", a, chars[(int) CHAR_BLACK], prisoners[0], b, c, chars[(int) CHAR_WHITE], prisoners[1], d); clrtoeol(); } static char getKey() { MOUINFOREC m; for (; ; ) { if (MOUcheck()) { MOUget(&m); if (m.buttonstat & (LEFTBPRESS | RIGHTBPRESS)) return ' '; } if (kbhit()) return getch(); } } int iskey() { _AH = 1; geninterrupt(0x16); return (!(_FLAGS & 64)); } char altkey[] = "qwertyuiop????asdfghjkl?????zxcvbnm"; char getKeyEdit() { MOUINFOREC m; int key; for (; ; ) { if (MOUcheck()) MOUget(&m); if (iskey()) { _AX = 0; geninterrupt(0x16); if (_AL == ESC) { _AX = 0; geninterrupt(0x16); key = _AL; return 128 | key; } if (_AL) return _AL; key = _AH; switch (key) { case 77: return edcmds[EDRIGHT]; case 75: return edcmds[EDLEFT]; case 80: return edcmds[EDDOWN]; case 72: return edcmds[EDUP]; case 79: return edcmds[EDEOL]; case 71: return edcmds[EDBOL]; case 82: return edcmds[EDTINS]; case 83: return edcmds[EDDEL]; case 73: return edcmds[EDPUP]; case 81: return edcmds[EDPDOWN]; case 119: /* ctrl home */ return 0; case 117: /* ctrl end */ return edcmds[EDDEOL]; case 132: /* Ctrl Pg Up */ return edcmds[EDBOC]; case 118: /* Ctrl Pg Dn */ return edcmds[EDEOC]; default: if (key >= 16 && key <= 50) { return altkey[key - 16] | 128; } return 0; } } } } char getKeyLine() { static lastmouse = 0; MOUINFOREC m; for (; ; ) { if (MOUcheck()) { MOUget(&m); if (m.buttonstat & LEFTBPRESS) { if (lastmouse == 1) { lastmouse = 0; return '\r'; } if (!lastmouse) { lastmouse = 1; return 'y'; } lastmouse = 0; return '\b'; } if (m.buttonstat & RIGHTBPRESS) { if (lastmouse == 2) { lastmouse = 0; return '\r'; } if (!lastmouse) { lastmouse = 2; return 'n'; } lastmouse = 0; return '\b'; } } if (kbhit()) { lastmouse = 0; return getch(); } } } static char scoring = 0; void printmodes() { setcolor(menubg, menufg); move(0, 4); printw(" help quit %7s%7s%7s", stoneModeName[stonemode], branchModeName[branchmode], menumode[menu]); setcolor(background, foreground); setCursor(xcur, ycur); } int getmenu(cx) int cx; { int i; for (i = 0; i < 5; i++) if (cx <= menubounds[menu][i].top && cx >= menubounds[menu][i].bottom) return (menu << 4) + i; return -1; } int checkLeftButton(cx, cy) int cx, cy; { if (cy == COMMAND_Y && cx >= COMMAND_X) { cx -= COMMAND_X; if (cx < 10) return '?'; if (cx >= 15 && cx < 20) return keys[C_TUTORSWAP]; if (cx >= 24 && cx < 29) return keys[C_SAVESHORT]; cx += COMMAND_X; } if (cy >= COMMENT_Y && cy < COMMENT_Y + COMMENT_HIGH && cx >= COMMENT_X) return keys[C_EDCOMMENT]; if ((cy == 22) && usecolor) { switch (getmenu(cx)) { case 0x01: return keys[C_BEGINNING]; case 0x02: return keys[C_END]; case 0x03: return keys[C_DOWNFORK]; case 0x04: return keys[C_SEARCHCOMMENT]; case 0x11: return keys[C_SCORE]; case 0x12: return keys[C_PASSMOVE]; case 0x13: return keys[C_TOPLAY]; case 0x20: return keys[C_INFO]; case 0x21: return keys[C_TREECUT]; case 0x22: return keys[C_PASTE]; case 0x23: return keys[C_DELNODE]; case 0x24: return keys[C_ADDVAR]; case 0x31: return keys[C_WRITE]; case 0x32: return keys[C_LOAD]; case 0x33: return keys[C_NEXTFILE]; case 0x34: return keys[C_BACKFILE]; } } if (cy == STATUS_Y && cx >= STATUS_X) { return keys[filecount ? C_NEXTFILE : C_LOAD]; } if ((cy == 0) && usecolor) { MOUhide(); switch ((cx - 4) / 7) { case 0: MOUshow(); return '?'; case 1: MOUshow(); return keys[C_QUIT]; case 2: stonemode = !stonemode; printmodes(); break; case 3: branchmode = !branchmode; printmodes(); break; case 4: menu++; menu %= MENUITEMS; printmodes(); setcolor(menubg, menufg); mvaddstr(22, 6, menulines[menu]); setcolor(background, foreground); setCursor(xcur, ycur); break; } MOUshow(); } if (scoring && cy == 23 && cx <= 39) { if (cx <= 12) return '\r'; if (cx <= 24) return 0; else if (cx <= 32) return 'u'; else if (cx <= 39) return 'q'; } if (!((cx - LEFT) & 1) && inRange(cy - TOP, (cx - LEFT) / 2)) { xcur = (cx - LEFT) / 2; ycur = (cy - TOP); return stonemode || scoring ? 32 : keys[C_ADDLETTER]; } if ((cy == 23) && ((cx >= 48 && cx <= 54 && curPlayer != t_Black) || (cx >= 59 && cx <= 67 && curPlayer == t_Black))) return keys[C_TOGGLESTONE]; if (cx == COMMENT_X - 1 && cy == COMMENT_Y) return keys[C_COMMENTSCROLLUP]; if (cx == TREE_X - 1 && cy == TREE_Y + 1) return keys[C_TREESCROLLUP]; if (cx == TREE_X - 1 && cy == TREE_Y + TREEHIGH - 1) return keys[C_TREESCROLLDOWN]; if (cx == COMMENT_X - 1 && cy == COMMENT_Y + COMMENT_HIGH - 1) return keys[C_COMMENTSCROLLDOWN]; if (cx >= TREE_X && cy > TREE_Y && cy < TREE_Y + TREEHIGH) return branchmode ? 'A' + treeLine + cy - TREE_Y - 1 : keys[C_WALKDOWN]; if (cy == TREE_Y) { if (cx > TREE_X + 10) return keys[C_ADDNAME]; if (cx > TREE_X + 1) return keys[C_GOTO]; } return 0; } int checkRightButton(cx, cy) int cx, cy; { if (scoring) return '\r'; if ((cy == 22) && usecolor) { if (getmenu(cx) == 3) return keys[C_UPFORK]; if (getmenu(cx) == 4) return keys[C_SEARCHBACKCOMMENT]; } if ((!((cx - LEFT) & 1)) && inRange(cy - TOP, (cx - LEFT) / 2)) { xcur = (cx - LEFT) / 2; ycur = (cy - TOP); return keys[stonemode ? (curPlayer == t_Black ? C_ADDBLACK : C_ADDWHITE) : C_ADDMARK]; } if (cy == STATUS_Y && cx >= STATUS_X && filecount) { return keys[C_BACKFILE]; } if (cx >= TREE_X && cy > TREE_Y && cy < TREE_Y + TREEHIGH) return keys[branchmode ? C_UP : C_WALKUP]; return 0; } char getKeyIdle() { int key; MOUINFOREC m; MOUshow(); for (;;) { if (MOUcheck()) { MOUget(&m); if ((m.buttonstat & LEFTBPRESS) && (key = checkLeftButton(m.cx, m.cy))) { MOUhide(); return key; } if ((m.buttonstat & RIGHTBPRESS) && (key = checkRightButton(m.cx, m.cy))) { MOUhide(); return key; } } if (kbhit()) { MOUhide(); return getch(); } } } char getKeyScore() { char temp; scoring = 1; temp = getKeyIdle(); scoring = 0; return temp; } static void initAscii() { char stone[] = {0x00, 0x00, 0x00, 0x7E, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7E, 0x00, 0x00, 0x00}; char terr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x7e, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; char hoshi[] = {0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}; /* note 0x3c and 0xff for dot in hoshi are set below. */ unsigned char *dest, far * font; int i, j, k; unsigned char myfont[256][16]; extern vgapresent; struct text_info info; gettextinfo(&info); fixfont = info.screenheight == 50 || info.screenheight == 43; textmode(C80); if (graphics && isegavga()) { _AX = 0x1003; _BX = 0; geninterrupt(0x10); /* enable high intensity background */ if (vgapresent) { _AX = 0x1010; _BX = 0x0014; _CH = bgreen; _CL = bblue; _DH = bred; geninterrupt(0x10); /* change color 6 */ } font = getfont(); /* adaptively set hoshi point character */ for (k = 0; k < 16; k++) if (*(font + 197 * 16 + k) == 255) break; if (k == 16) k = 9; for (i = k - 2; i <= k + 2; i++) hoshi[i] = 0x3c; hoshi[k] = 0xff; for (dest = (char *) myfont, k = 0; k < 16 * 256; k++, dest++, font++) *dest = *font; for (k = 0; k < 16; k++) { myfont[2][k] = stone[k]; myfont[15][k] = terr[k]; myfont[199][k] = hoshi[k]; } setfont((unsigned char far *) myfont); strcpy(chars, graphchar); usecolor = 1; } else graphics = 0; if ((!graphics) && usecolor) strcpy(chars + CHAR_VERT, graphchar + CHAR_VERT); MOUinit(); MOUhide(); fixkeys(); fixedkeys(); } static void plotMarkAscii(b, i, j) pBoard b; int i, j; { void plotPieceAscii(); int sc; if (usecolor) { sc = boardcolor; boardcolor = markcolor; } else textattr(inverseFlag ? 0x07 : 0x70); plotPieceAscii(b, i, j); if (usecolor) { boardcolor = sc; } else textattr(inverseFlag ? 0x70 : 0x07); } static command specialKeysIdle(c) char c; { if (!c) { c = getKey(); switch (c) { case 77: return (cursorkey == 0 || (cursorkey == 2 && tutor)) ? C_DOWN : C_CURRIGHT; case 75: return (cursorkey == 0 || (cursorkey == 2 && tutor)) ? C_UP : C_CURLEFT; case 79: return (cursorkey == 0 || (cursorkey == 2 && tutor)) ? 0 : C_DOWNLEFT; case 80: return (cursorkey == 0 || (cursorkey == 2 && tutor)) ? C_DOWNFORK : C_CURDOWN; case 71: return (cursorkey == 0 || (cursorkey == 2 && tutor)) ? 0 : C_UPLEFT; case 72: return (cursorkey == 0 || (cursorkey == 2 && tutor)) ? C_UPFORK : C_CURUP; case 81: return (cursorkey == 0 || (cursorkey == 2 && tutor)) ? C_SEARCHCOMMENT : C_DOWNRIGHT; case 73: return (cursorkey == 0 || (cursorkey == 2 && tutor)) ? C_SEARCHBACKCOMMENT : C_UPRIGHT; default: return (command) 0; } } else return (command) 0; } static void drawPiece(i, j, c) int i, j; char c; { move(TOP + j, LEFT + 2 * i); setcolor(boardcolor, blackstone); if (c == chars[(int) CHAR_NOTHING]) { if (graphics) { if (i == 0) { if (j == boardsize - 1) c = '\300'; else if (j == 0) c = '\332'; else c = '\303'; } else if (i == boardsize - 1) { if (j == boardsize - 1) c = '\331'; else if (j == 0) c = '\277'; else c = '\264'; } else if (j == 0) c = '\302'; else if (j == boardsize - 1) c = '\301'; } } if (usecolor) { if (c == chars[(int) CHAR_WHITE]) { c = chars[(int) CHAR_BLACK]; setcolor(boardcolor, whitestone); } if (c == chars[(int) CHAR_WHITETERR]) { c = chars[(int) CHAR_BLACKTERR]; setcolor(boardcolor, whitestone); } if (c == chars[(int) CHAR_DAME]) { setcolor(boardcolor, damecolor); } if (c >= 'a' && c <= 'z') setcolor(boardcolor, lettercolor); } addch(c); setcolor(background, foreground); } static void initBoardAscii() { int i, j; if (!usecolor) { if (inverseFlag) textattr(0x70); else textattr(0x07); } if (inverseFlag && usecolor) { inverseFlag = foreground; foreground = background; background = inverseFlag; menubg = background; inverseFlag = 0; } setcolor(background, foreground); clrscr(); if (mouseinstalled & usecolor) { printmodes(); setcolor(menubg, menufg); mvaddstr(22, 6, menulines[menu]); setcolor(background, foreground); } if (usecolor) { setcolor(boardcolor, blackstone); for (i = LEFT + 1; i < LEFT + boardsize * 2 - 2; i += 2) for (j = TOP; j < TOP + boardsize; j++) mvaddch(j, i, graphics ? '\304' : ' '); } for (i = boardsize; i--;) { /* left */ set_inverse(); move(TOP + i, LEFT - 1); setcolor(boardcolor, background); addch(chars[(int) CHAR_VERT]); setcolor(background, boardcolor); /* top */ move(TOP - 1, LEFT + i * 2 - 1); printw("%c%c", chars[(int) CHAR_HORIZ], chars[(int) CHAR_HORIZ]); /* bottom */ move(TOP + boardsize, LEFT + i * 2 - 1); printw("%c%c", chars[(int) CHAR_HORIZ], chars[(int) CHAR_HORIZ]); /* right */ move(TOP + i, LEFT + boardsize * 2 - 1); setcolor(background, boardcolor); addch(chars[(int) CHAR_VERT]); setcolor(background, foreground); unset_inverse(); /* right */ printw("%-2d%c", boardsize - i, '\263'); /* left */ move(TOP + i, LEFT - 3); printw("%2d", boardsize - i); /* top */ move(TOP - 2 + usecolor, LEFT + i * 2); addch(xAxisChars[i]); /* bottom */ move(TOP + boardsize + 1 - usecolor, LEFT + i * 2); addch(xAxisChars[i]); for (j = boardsize; j--;) drawPiece(i, j, boardPiece(i, j)); } set_inverse(); move(TOP - 1, LEFT - 1); addch(chars[(int) CHAR_UPLEFT]); move(TOP + boardsize, LEFT - 1); addch(chars[(int) CHAR_DOWNLEFT]); move(TOP - 1, LEFT + boardsize * 2 - 1); addch(chars[(int) CHAR_UPRIGHT]); move(TOP + boardsize, LEFT + boardsize * 2 - 1); addch(chars[(int) CHAR_DOWNRIGHT]); unset_inverse(); mvaddstr(COMMAND_Y, COMMAND_X, helpMsg); printstatus(name_buf); } static char *mouseHelp[] = { " Mouse Commands", "Click on (left)=left click (right)=right click", " board \"stone\" mode: makes a move (left) sets stone (right)", " \"mark\" mode: places letter (left) places mark (right)", "", " \"Node #\" Goes to node by number", " node name Sets node name", " comment Edits the comment", " \"+\" or \"-\" (next to comment or variations) scroll the comment/variations", " filename Next (left) or previous (right) file, or load file.", " variation Go to that variation (left) back up (right)", " long/short Toggles save file format", " read/edit/tutor Toggles tutor mode", "", "When scoring a game, right button scores, left buttons kills, and clicking ", "on words at the bottom of the screen executes whatever function.", "", "Mouse clicks will remove error messages.", "At a (y/n) prompt, double click left to respond yes, double click right for no", "", "Menus above and below the board provide other functions", "", " Hit a key (or click) to continue"}; static char *ibmHelp[] = {" Cursor Keys", "", "To move the cursor on the board", "you must use the number keys", "(have num lock on)", "", "The cursor keys have the following functions:", "", "right down tree like ", "left up tree like ", "up previous variation branch", "down next variation branch", "pgup last comment", "pgdn next comment", "", " press a key" }; static void specialHelp() { int i; char ch; clrscr(); for (i = 0; i < sizeof(ibmHelp) / sizeof(char *); i++) { move(i + 5, 14); cputs(ibmHelp[i]); if (i == 8) addch(keys[C_DOWN]); if (i == 9) addch(keys[C_UP]); } ch = getKey(); if (ch != '\n' && ch != '\r' && mouseinstalled) { clrscr(); for (i = 0; i < sizeof(mouseHelp) / sizeof(char *); i++) { move(i, 0); if (i == 4) { printw(" "); if (usecolor) setcolor(boardcolor, blackstone); printw(" %c: ?? ", chars[CHAR_BLACK]); if (usecolor) setcolor(background, foreground); printw(" selects black stones, "); if (usecolor) { setcolor(boardcolor, whitestone); printw(" %c: ?? ", chars[CHAR_BLACK]); setcolor(background, foreground); } else printw(" %c: ?? ", chars[CHAR_WHITE]); printw(" selects white stones."); } cputs(mouseHelp[i]); } getKey(); clrscr(); printmodes(); mvaddstr(1, 20, " \263 \263 \300\304 indicates menu chosen. Click here to"); mvaddstr(2, 20, " \263 \263 switch to a different menu."); mvaddstr(3, 20, " \263 \300\304 type of movement through game tree (see previous"); move(4, 20); printw(" \263 screen). Branch for movement like %c and %c, ", keys[C_DOWN], keys[C_UP]); move(5, 20); printw(" \263 walk for movement like %c and %c. ", keys[C_WALKDOWN], keys[C_WALKUP]); mvaddstr(6, 20, " \300\304 Mouse button on the board sets stones or sets marks."); mvaddstr(7, 20, " Click here to toggle."); setcolor(menubg, menufg); mvaddstr(9, 0, menulines[0]); setcolor(background, foreground); mvaddstr(10, 2, "Click on start or end to go to start of file or end of current variation."); mvaddstr(11, 2, "Left click on var or comment to go to next variation branch or comment."); mvaddstr(12, 2, "Right click to go to last variation branch or comment."); setcolor(menubg, menufg); mvaddstr(13, 0, menulines[1]); setcolor(background, foreground); mvaddstr(14, 2, "Click on score to score, pass to play a pass move, and player to toggle the"); mvaddstr(15, 2, "current player with an item in the game tree."); setcolor(menubg, menufg); mvaddstr(16, 0, menulines[2]); setcolor(background, foreground); mvaddstr(17, 2, "Click on info to get info, cut or paste to cut and paste, delnode to delete a"); mvaddstr(18, 2, "node or addvar to add a variation."); setcolor(menubg, menufg); mvaddstr(19, 0, menulines[3]); setcolor(background, foreground); mvaddstr(20, 2, "Click on save to save the game record, load to load a new file, next to go to"); mvaddstr(21, 2, "the next file or prev to go to the previous file."); mvaddstr(23, 24, "Hit a key or click to continue."); getKey(); } } mgt-2.31/asc_unix.inc100640 1750 1750 10653 6176731442 12424 0ustar memmem/* "mgt" Copyright (c) 1991 Shodan */ #include char chars[] = "#O=+-.+|-++++"; #define doredraw() clearok(stdscr, TRUE), refresh(),clearok(stdscr, FALSE) #define openwin() win=subwin(stdscr,WINHIGH+1,WINWIDE+1,WINTOP,WINLEFT) /* ,wclear(win) */ #define fixcursor() #define specialKeysEdit(c) (c) #define closewin() delwin(win) #define getKey getch #define getKeyIdle getch #define getKeyLine getch #define getKeyScore getch #define specialHelp() #define preserveScreen() WINDOW *wi;wi=newwin(0,0,0,0);overwrite(stdscr,wi);touchwin(stdscr) #define restoreScreen() overwrite(wi,stdscr);refresh();delwin(wi) /* #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);} #define restoreRegion(x1,y1,dx,dy) * overwrite(wi,stdscr);refresh();delwin(wi) */ #define saveRegion(a,b,c,d) wi=newwin(0,0,0,0);overwrite(stdscr,wi);touchwin(stdscr) #define restoreRegion(a,b,c,d) restoreScreen() #define dopris() printw(" %c %c: %d %c %c %c: %d %c ", a, chars[(int)\ CHAR_BLACK], prisoners[0], b, c, \ chars[(int) CHAR_WHITE], prisoners[1], d) #define mainwin() #define unmainwin() static char getKeyEdit() { char c; c = getch(); if (!edvi && (c == ESC)) { c = 128 | getch(); } if (c == '\333') { /* ('[' | 128) */ c = getch(); if (c == 'A') c = edcmds[EDUP]; if (c == 'B') c = edcmds[EDDOWN]; if (c == 'C') c = edcmds[EDRIGHT]; if (c == 'D') c = edcmds[EDLEFT]; } return c; } static void drawPrisoners() { extern int ispl; char a, b, c, d; if (curPlayer == t_Black) { a = ispl ? '}' : '>'; b = ispl ? '{' : '<'; c = d = ' '; } else { a = b = ' '; c = ispl ? '}' : '>'; d = ispl ? '{' : '<'; } move(23, 50); printw("%c %c: %d %c %c %c: %d %c ", a, chars[(int) CHAR_BLACK], prisoners[0], b, c, chars[(int) CHAR_WHITE], prisoners[1], d); clrtoeol(); } static void initAscii() { fixkeys(); fixedkeys(); initscr(); noecho(); crmode(); } static void plotMarkAscii(b, i, j) pBoard b; int i, j; { void drawPiece(); piece p; p = boardGet(b, i, j); inverseFlag = !inverseFlag; drawPiece(i, j, (p == P_NOTHING ? boardPiece(i, j) : (p == P_BLACK ? chars[(int) CHAR_BLACK] : chars[(int) CHAR_WHITE]))); inverseFlag = !inverseFlag; } static int xpos(win) WINDOW *win; { int x, y; getyx(win, y, x); return x; } static int ypos(win) WINDOW *win; { int y, x; getyx(win, y, x); return y; } static command specialKeysIdle(c) char c; { return (command) 0; } static void set_inverse() { if (inverseFlag) standout(); } static void unset_inverse() { standend(); } static void drawPiece(i, j, c) int i, j; char c; { move(TOP + j, LEFT + 2 * i); set_inverse(); addch(c); unset_inverse(); } static void initBoardAscii() { int i, j; clear(); if (inverseFlag) { set_inverse(); for (i = LEFT + 1; i < LEFT + boardsize * 2 - 2; i += 2) for (j = TOP; j < TOP + boardsize; j++) mvaddch(j, i, ' '); unset_inverse(); } for (i = boardsize; i--;) { /* left */ move(TOP + i, LEFT - 3); printw("%2d", boardsize - i); set_inverse(); addch(chars[(int) CHAR_VERT]); /* right */ move(TOP + i, LEFT + boardsize * 2 - 1); addch(chars[(int) CHAR_VERT]); unset_inverse(); printw("%2d", boardsize - i); /* printw("%2d%c", boardsize - i, chars[(int) CHAR_VERT]); */ /* top */ move(TOP - 2, LEFT + i * 2); addch(xAxisChars[i]); move(TOP - 1, LEFT + i * 2 - 1); set_inverse(); printw("%c%c", chars[(int) CHAR_HORIZ], chars[(int) CHAR_HORIZ]); /* bottom */ move(TOP + boardsize, LEFT + i * 2 - 1); printw("%c%c", chars[(int) CHAR_HORIZ], chars[(int) CHAR_HORIZ]); unset_inverse(); move(TOP + boardsize + 1, LEFT + i * 2); addch(xAxisChars[i]); for (j = boardsize; j--;) drawPiece(i, j, boardPiece(i, j)); } set_inverse(); move(TOP - 1, LEFT - 1); addch(chars[(int) CHAR_UPLEFT]); move(TOP - 1, LEFT + boardsize * 2 - 1); addch(chars[(int) CHAR_UPRIGHT]); move(TOP + boardsize, LEFT - 1); addch(chars[(int) CHAR_DOWNLEFT]); move(TOP + boardsize, LEFT + boardsize * 2 - 1); addch(chars[(int) CHAR_DOWNRIGHT]); unset_inverse(); mvaddstr(COMMAND_Y, COMMAND_X, helpMsg); printstatus(name_buf); } mgt-2.31/format100750 1750 1750 136 6176731460 11270 0ustar memmem#!/bin/csh -f foreach f ( $* ) indent -ndj -i3 -ip0 -npcs -cli3 -di3 -npsl -ncdb -l80 $f end mgt-2.31/mailgo100750 1750 1750 26634 6176731464 11327 0ustar memmem#!/bin/sh # # mailgo 2.0 E-mail go game management program by Adrian Mariano # 3/24/93 I place it on the public domain. Please send improvements # to me at adrian@bsdserver.ucsf.edu # # Syntax: mailgo [-r] filename # mailgo -- # mailgo -n [filename] # mailgo -c # mailgo -e filename # # Filename should contain a mailgo go game # # -- reads game file from stdin # -r resends the file to the opponent # -n start a new game, using data in filename to get address # -c removes temporary files left when abnormally terminated: MailGo* # -e edits the mailgo header and/or the game record # # Invokes the game processor in the environment variable MAILGO, or attempts # to run mgt from the inherited path if MAILGO is not set. # # System V Unix users should change the assignment to the MAILER variable # from 'mail' to 'mailx' or 'elm' or some other compatible mailer. # MAILER=mail if [ $# -eq 0 ] then echo ' ' echo 'Syntax: mailgo [-r] filename' echo ' mailgo --' echo ' mailgo -n [filename]' echo ' mailgo -c ' echo ' mailgo -e filename' echo ' ' echo 'Mailgo is a program to manage email go games.' echo 'Filename should contain a mailgo go game' echo ' ' echo ' -- reads game file from stdin' echo ' -r resends the file to the opponent' echo ' -n start a new game, using data in filename to get address' echo ' -c removes temporary files left when abnormally terminated: MailGo*' echo ' -e edits the mailgo header and/or the game record' echo ' ' exit fi case $1 in -c) if [ $# -ne 1 ] then echo Wrong number of parameters exit else rm -f MailGo* MailFile* MailOut* exit fi;; -r) if [ $# != 2 ] then echo Wrong number of parameters exit fi if grep "\---GoGaMeEnD---" $2 >/dev/null 2>&1 then name=`sed -n '2,5s/TO: //p' $2` hisfile=`sed -n '2,5s/TOFILE: //p' $2` echo Remailing response to $name, $hisfile $MAILER -s "Remailed Go Game: $hisfile" $name < $2 exit else echo Invalid input file $2 exit fi;; -e) if [ $# -ne 2 ] then echo Wrong number of parameters exit fi if [ ! -s $2 ] then echo File $2 not found. exit fi sed -n '/---GoGaMeStArT---/,/---GoGaMeEnD---/{s/---GoGaMe.*---// p }' $2 > MailGo$$ if [ ! -s MailGo$$ ] then echo Invalid input file $2 exit fi opponent=`sed -n '2,5s/TO: //p' MailGo$$` echo To address: $opponent echo -n "new address, for no change: " read res if [ $res ] then opponent=$res fi hisfile=`sed -n '2,5s/TOFILE: //p' MailGo$$` echo To game file: $hisfile echo -n "new file name, for no change: " read res if [ $res ] then hisfile=$res fi me=`sed -n '2,5s/FROM: //p' MailGo$$` echo From address: $me echo -n "new address, for no change: " read res if [ $res ] then me=$res fi myfile=`sed -n '2,5s/FROMFILE: //p' MailGo$$` echo From game file: $myfile echo -n "new file name, for no change: " read res if [ $res ] then myfile=$res fi if sed -n 6,7p MailGo$$ | grep FORMAT > /dev/null 2>&1 then format=`sed -n '6,7s/FORMAT: //p' MailGo$$` if [ ! \( $format = 'L' -o $format = 'E' \) ] then format='S' fi else format='L' fi echo Old game record format: $format echo -n "New game record format (Long/Short/Extrashort): " read res case $res in L | l) format='L' ;; E | e) format='E' ;; S | s) format='S' ;; *) ;; esac case $format in L) sflag='';; *) sflag=-s;; esac if ${MAILGO-mgt} $sflag -m MailOut$$ MailGo$$ then if [ -s MailOut$$ ] then echo >> MailOut$$ cat < MailFile$$ ---GoGaMeStArT--- TO: $opponent TOFILE: $hisfile FROM: $me FROMFILE: $myfile FORMAT: $format END_END if [ $format = 'S' ] then sed 's/\(;[BC]\[\)/\ \1/g' MailOut$$ >>MailFile$$ else cat MailOut$$ >> MailFile$$ fi echo >> MailFile$$ echo "---GoGaMeEnD---" >> MailFile$$ else echo -n "---GoGaMeStArT---" > MailFile$$ sed "s/TO:.*/TO: $opponent/ s/TOFILE:.*/TOFILE: $hisfile/ s/FROM:.*/FROM: $me/ s/FROMFILE:.*/FROMFILE: $myfile/ s/FORMAT:.*/FORMAT: $format/" MailGo$$ >> MailFile$$ echo "---GoGaMeEnD---" >> MailFile$$ echo -n "empty mgt file" exit fi else echo -n "---GoGaMeStArT---" > MailFile$$ sed "s/TO:.*/TO: $opponent/ s/TOFILE:.*/TOFILE: $hisfile/ s/FROM:.*/FROM: $me/ s/FROMFILE:.*/FROMFILE: $myfile/ s/FORMAT:.*/FORMAT: $format/" MailGo$$ >> MailFile$$ echo "---GoGaMeEnD---" >> MailFile$$ echo "No move made, or mgt error" fi rm -f MailGo$$ MailOut$$ echo -n "Do you wish to keep updates (y/N)? " read res case $res in Y | y) cat MailFile$$ > $2 echo Updates saved to: $2 rm -f MailFile$$ exit;; *) echo NOT keeping updates. rm -f MailFile$$ exit;; esac ;; -n) if [ $# -gt 2 ] then echo Wrong number of parameters exit fi if [ $# -eq 2 ] then if [ ! -s $2 ] then echo File $2 not found. exit fi opponent=`sed -n '2,5s/TO: //p' $2` echo Opponent address: $opponent hisfile=`sed -n '2,5s/TOFILE: //p' $2` echo His game file: $hisfile me=`sed -n '2,5s/FROM: //p' $2` echo Your address: $me myfile=`sed -n '2,5s/FROMFILE: //p' $2` echo Your game file: $myfile else echo -n "Opponent address: " read opponent echo -n "Opponent game filename: " read hisfile echo -n "Your address: " read me echo -n "Your game filename: " read myfile fi echo -n "Black player name: " read bpname echo -n " rank: " read bprank echo -n "White player name: " read wpname echo -n " rank: " read wprank echo -n "Board size (return for 19): " read bsize if [ "$bsize" -lt 7 -o "$bsize" -gt 19 ] then bsize=19 fi echo -n "Handicap: " read handicap echo -n "Komi: " read komi echo -n "Game record format (Long/Short/Extrashort): " read format case $format in L | l) format='L' ;; E | e) format='E' ;; *) format='S' ;; esac started=`date|awk '{print $3, $2, $6}'` if grep "W\[\]" $myfile >/dev/null 2>&1 then echo -n "File $myfile contains game possibly in progress. Clobber (y/N)? " read res case $res in Y | y) ;; *) echo -n "Your game filename: " read myfile;; esac fi cat <$myfile ---GoGaMeStArT--- FROM: $me FROMFILE: $myfile TO: $opponent TOFILE: $hisfile NEWGAME FORMAT: $format END_END cat < MailGo$$ ( ; GaMe[1] VieW[] SiZe[$bsize] Comment[Black: $bpname, $bprank White: $wpname, $wprank `if [ "$handicap" ] ; then echo "Handicap: $handicap" ; fi` `if [ "$komi" ] ; then echo "Komi: $komi" ; fi` Started: $started] PB[$bpname] BR[$bprank] PW[$wpname] WR[$wprank] `if [ "$komi" ] ; then echo KoMi[$komi] ; fi` DT[$started] ` case $bsize.$handicap in 19.2) echo "PL[W]HA[2]AB[dp][pd]" ;; 19.3) echo "PL[W]HA[3]AB[dp][pd][pp]" ;; 19.4) echo "PL[W]HA[4]AB[dd][dp][pd][pp]" ;; 19.5) echo "PL[W]HA[5]AB[dd][dp][jj][pd][pp]" ;; 19.6) echo "PL[W]HA[6]AB[dd][dj][dp][pd][pj][pp]" ;; 19.7) echo "PL[W]HA[7]AB[dd][dj][dp][jj][pd][pj][pp]" ;; 19.8) echo "PL[W]HA[8]AB[dd][dj][dp][jd][jp][pd][pj][pp]" ;; 19.9) echo "PL[W]HA[9]AB[dd][dj][dp][jd][jj][jp][pd][pj][pp]" ;; 13.2) echo "PL[W]HA[2]AB[dj][jd]" ;; 13.3) echo "PL[W]HA[3]AB[dj][jd][jj]" ;; 13.4) echo "PL[W]HA[4]AB[dd][dj][jd][jj]" ;; 13.5) echo "PL[W]HA[5]AB[dd][dj][gg][jd][jj]" ;; 9.2) echo "PL[W]HA[2]AB[cg][gc]" ;; 9.3) echo "PL[W]HA[3]AB[cg][gc][gg]" ;; 9.4) echo "PL[W]HA[4]AB[cc][cg][gc][gg]" ;; esac` ) END_END case $format in L) sflag='';; *) sflag=-s;; esac if ${MAILGO-mgt} $sflag -m MailOut$$ MailGo$$ then if [ -s MailOut$$ ] then cat MailOut$$ >>$myfile else cat MailGo$$ >>$myfile fi else echo -n "No move made, or mgt error. Send anyway (y/N)? " read res case $res in Y | y) cat MailGo$$ >>$myfile;; *) echo NOT mailing new game. rm -f MailGo$$ MailOut$$ exit;; esac fi rm -f MailOut$$ MailGo$$ echo Mailing new game to $opponent, $hisfile echo >> $myfile echo "---GoGaMeEnD---" >> $myfile $MAILER -s "New Go Game: $hisfile" $opponent <$myfile exit ;; esac if [ $# -ne 1 ] then echo Wrong number of parameters exit fi if [ $1 = -- ] then cat >/tmp/mailgo$$ set /tmp/mailgo$$ exec MailGo$$ if [ ! -s MailGo$$ ] then echo Invalid input file $1 exit fi eval `sed -n '/---GoGaMeStArT---/,/(/{ s/^TOFILE: */fileout=/p s/^FROMFILE: */hisfile=/p s/^FORMAT: */format=/p s/^TO: */me=/p s/^FROM: */name=/p s/^NEWGAME/newgame=1/p }' $1` if [ -z "$format" ] then format=L elif [ "$format" != L -a "$format" != E ] then format=S fi case $format in L) sflag='';; *) sflag='-s';; esac if ${MAILGO-mgt} $sflag -m MailOut$$ MailGo$$ then echo >> MailOut$$ if [ "$newgame" = 1 -a -s $fileout ] then echo -n "File $fileout exists. Clobber (y/N)? " read res case $res in Y | y) rm -f $fileout ;; *) echo -n "Output filename: " read fileout ;; esac fi cat < MailFile$$ ---GoGaMeStArT--- TO: $name TOFILE: $hisfile FROM: $me FROMFILE: $fileout FORMAT: $format EOF case $format in S) sed 's/\(;[BC]\[\)/\ \1/g' MailOut$$ >>MailFile$$;; *) cat MailOut$$ >>MailFile$$;; esac echo "---GoGaMeEnD---" >> MailFile$$ echo Mailing response to $name, $hisfile $MAILER -s "Go Game: $hisfile" $name < MailFile$$ rm -f MailGo$$ MailOut$$ $1 if grep "\---GoGaMeEnD---" $fileout > /dev/null 2>&1 || [ ! -s $fileout ] then mv MailFile$$ $fileout else echo Save file $fileout doesn\'t look like a mailgo file. echo "Overwrite it anyway (y/N)?" read res case $res in y | Y) mv -f MailFile$$ $fileout;; *) echo Game record left in MailFile$$;; esac fi else echo No move made, or mgt error. NOT mailing response. rm -f MailGo$$ MailOut$$ fi mgt-2.31/mailgo.6100640 1750 1750 11056 6176731464 11461 0ustar memmem.TH MAILGO 6 "23 November 1992" .SH NAME mailgo - shell script for using mgt to automate email go games .SH SYNOPSIS .B mailgo [\-r] [\-n] [\-c] [\-e] [filename] .SH DESCRIPTION .B mailgo helps manage email games by processing Smart-Go game records received by mail, invoking mgt, and automatically sending your next move back. .LP Invoking .B mailgo with no flags instructs the program to search the specified file for a go game, ignoring mail headers or other such garbage. .B mailgo will invoke the game processor specified in the environment variable MAILGO or of this variable is undefined, will attempt to run .B mgt from the inherited path. If you give the filename -- then .B mailgo will read its input from stdin, allowing you to redirect messages into .B mailgo directly from your mailer. Your mail program may not support redirecting messages into external programs. Check it's man page to find out. This option to use stdin as the input is only valid if you give .B mailgo no other arguments. (Technical note: mgt is instructed to read its input from /dev/tty if you use this feature.) .LP If your opponent loses your move, you can resend the game with the \-r switch. .LP To start a new game, use the \-n switch. Without a file, you will be prompted for your address, your opponent's address, and the filename for both your and your opponent's local game record. The game processor will then be invoked for you to make the first move. If a filename is specified, the address and filename data is taken from that file. .LP The \-c switch causes the program to delete any extraneous files it might have created during a previous run which was abnormally terminated. These files have the form: MailGo* .LP To edit the mailgo headers (including mail addresses, file names and game record format) or the game record, use the \-e switch with the file name of the mailgo file you wish to edit. The file may be a saved mailgo mail message or a processed mailgo game file. The \-e option will not mail changes because of the possibility of confusing addresses. To mail edited files, use 'mailgo ' for edited mail messages and 'mailgo -r ' for edited files which have been previously processed by .B mailgo. .LP .B mailgo also supports go board sizes of 9x9, 13x13 and 19x19. Handicaps maybe set to values of 2-4 for 9x9 games, 2-5 for 13x13 games and 2-9 for 19x19 games. Any other board size or handicap must be set behind .B mailgo 's back. .SH FILE FORMAT .LP .sp .if Leading garbage ignored ---GoGaMeStArT--- TO: opponent@hissite TOFILE: his_game_record FROM: me@mysite FROMFILE: my_game_record FORMAT: format_code ( Smart\-Go game data ) ---GoGaMeEnD--- Trailing garbage ignored .fi .LP The game data file contains a leading tag to indicate the start of the data. It contains both addresses, as should be used to mail the game files, and it contains the files to store the games in. In the example above, you are playing opponent@hissite, and the game is being stored in my_game_record. .LP The file format used can be either long, short, or extrashort indicated by L, S, and E respectively. The long format uses the full size Smart-Go file saved with no options from mgt. The extrashort format uses mgt with the \-s option to save short format files. This format may cause problems for some mailers, however, because the lines will grow longer than 512 bytes. In any game record format, if very long comments are created, there is a danger of causing mailer problems. The short format is similar to the extrashort format but has extra newlines inserted. The short format is the default when selecting format from the prompt, but the long format is the default if a file contains no FORMAT line. When .B mailgo is used normally, the file specified on the command line is removed at successful completion, and the new game is saved to the file specified in the received game record. If the destination file does not look like a mailgo file, .B mailgo will query for confirmation. .LP When a new game is started, the first mailgo message contains the line NEWGAME inserted before the FORMAT line. This is used to check for the overwriting of old game records. .SH FILES mgt .LP Smart-Go.def, the Smart\-Go format definition. .sp .SH BUGS .LP .B mailgo tries to handle the case where you start a new game but do not make the first move. If after the first move you have a reason to convince mgt that you have changed the game record without really changing anything, you should enter and exit the comment editor. .fi .sp .SH AUTHOR Adrian Mariano (adrian@bsdserver.ucsf.edu) mgt-2.31/mgt.6100640 1750 1750 41724 6176731461 11002 0ustar memmem.\" Define keep macros as poor (wo)man's substitute for broken .DS/.DE macros .deKS \" start keep .sp \" make a little head room .ev 1 \" collect text in new environment .in 0n \" set zero indent relative to previous environment .nf \" assume no-fill mode .di GO \" start diversion called GO .. .deKE \" end keep .br \" get last partial line .di \" end diversion .ne \\n(dn \" declare space needed for GO .nf \" bring GO back "as is" .GO \" output GO text .ev \" return to previous environment .sp.5 \" a little room for the toes .. .TH MGT 6 "9 July 1993" .SH NAME mgt - game record display/editor for the oriental game of go .SH SYNOPSIS .B mgt [\-m filename] [\-s] [-t] [files] .SH DESCRIPTION Go is an ancient oriental strategy game based on the capturing of territory. The players alternate putting stones on the board, trying to surround as many empty intersections as possible. .LP .B Mgt allows the user to examine Go game tree files created through the Macintosh(tm) programs .B Smart-Go (tm) or .B Go Explorer (tm). .B Mgt also has basic Go game tree editing capabilities and may be used to create or edit game tree files. The on\-line material provided by a rather extensive and growing database allows many hours of instructional enjoyment of various studies and tutorials concerning the game of Go. .LP .B Mailgo is a utility which manages E-mail Go games using .B mgt as the Go board editor. It is included in the .B mgt package. .LP The .B mgt program was originally developed to be a companion for the series, "From My Go Teacher", archived bsdserver.ucsf.edu for ftp. Also available is the Internet GO Board communications program, 'go', also by Greg Hale, which connects up two terminals in real\-time anywhere in the world, and the clients for the Internet Go Server. .SH COMMAND LINE OPTIONS .TP 8 .B \-m filename Invoke a set of options used by the .B mailgo program for managing email games. If a filename is specified for loading (see below), the game record is loaded, and .B mgt automatically moves to the end of the main variation of the game record. The game can be modified without confirmation. If the game record has been modified, it will be automatically saved, on exit, to the filename specified after the \-m and .B mgt will return success (zero). If the game record has not been modified, or has not been allowed to be saved, then .B mgt will return failure (nonzero). .LP .TP 8 .B \-s Change save format used to write save files. The default save format is the long format Smart\-Go file. Using this option results in short format Smart\-Go files. .LP .TP 8 .B \-t Invoke tutor mode where you select variations by playing on the board. The key for making a move has special behavior in this mode. See the section on the "space or 0" keyboard command for a description. .LP .TP 8 .B files These are the files to be loaded. The Unix and IBM version support wildcards. If no file is specified, .B mgt loads a blank board. If you attempt to modify a file that was loaded, .B mgt will prompt for confirmation the first time. .LP .SH OPERATION .B Mgt can be used to view and edit game records, or as an electronic game board for a two person game. There are many keyboard commands which execute the various editing and display functions. .LP .TP 8 > Step down the game tree to the next move. Stop at the end of a variation and do not visit other variations. .LP .TP 8 < Move back up the game tree. (Previous move) .LP .TP 8 . Go to the next node using a tree traversal which will visit all nodes. Sometimes the order of traversal can be confusing. .LP .TP 8 , Go to the previous node -- the opposite of "." forward movement. .LP .TP 8 e Go to end of the current variation. .LP .TP 8 b Go to beginning of the game tree. .LP .TP 8 } Go forward like the "." command until a comment. .LP .TP 8 { Go backwards like the "," command until a comment. .LP .TP 8 g Go to a specified node. Type in the desired node number. .LP .TP 8 ] Move forward until there is a variation branch in the game tree. .LP .TP 8 [ Move backwards until there is a variation branch in the game tree. .LP .TP 8 k and i Scroll the game tree variation window up and down. A \- at the top of the variation window, and a + at the bottom indicate that more variations are available. .LP .TP 8 j and u Scroll comment window up and down. A \- at the top of the comment, and a + at the bottom indicate that more comments are available. .LP .TP 8 # Load new file. Will prompt for confirmation if the current file has been modified. .LP .TP 8 r Load previous file. (Reverse through the file list) .LP .TP 8 f Load next file. (Forward through the file list) .LP .TP 8 w Write out Smart\-Go file. Will prompt for a filename. The special filename * will save with the current name (which appears in the upper right corner). .LP .TP 8 space or 0 Make a move. The current player turn is indicated by the > < around the captured stones on the lower right. Normally, this adds the move to the game tree and moves to a new node. In tutor mode, it checks the various game continuations. If one of them contains the move you made, it moves to that variation. If not, it prints an error message. The game tree cannot be modified in tutor mode. .LP .TP 8 p Pass. Enter a pass move. .LP .TP 8 o Other player. Changes whose turn it is, adding a token in the game tree to force the change whenever this node is visited. If the player is forced by such a token, the current player turn is indicated by } { characters on the lower right. .LP .TP 8 t Toggle stone color. Changes whose turn it is without adding any tokens in the game tree. This will not work if the game tree has a PLayer token (generated by the o key) at the current node. .LP .TP 8 z Set/unset black stones. .LP .TP 8 x Set/unset white stones. .LP .TP 8 q or ESC. Quit. q will prompt for confirmation. ESC will not prompt for confirmation. .LP .TP 8 v Create a variation below the current node. The variation will initially contain a null node. You must move to that variation to make a move in it. If the "v" command is invoked at a node which is at the end of a variation, variation "A" is created with a null node. Subsequent invocations of the "v" command will create the "B", "C"... variations. .LP .TP 8 ! Cut tree. Moves the current node and everything below it to a temporary holding buffer. (Moves your location back to the parent of the node you are one when you invoke it.) .LP .TP 8 ^ Paste tree. Pastes the temporary holding buffer in after the current node. Usually the opposite of cutting the tree. .LP .TP 8 c Edit the current comment. The editor has two models of operation. The default model has been vaguely designed after emacs. That means that the editor commands are either 'control-key' or 'escape-key'. The controls are configurable through an environment variable. The notation "^key" is used to indicate control keys, and "]key" is used to indicate keys which should be preceeded by the escape character. On some terminals, instead of ESC-key, you can press Alt-key or Meta-key. (On the IBM version, you can use the Alt key.) Under VMS, the ESC key does not work. VMS users may need to redefine the edit keys. The second edit model was vaguely designed after vi. That means that the editor has a command mode for cursor movement, etc. and an insert mode for inserting text. The vi model editor starts in insert mode. The ESC key changes mode from insert mode to command mode. If pressed in command mode, the ESC key exits the comment editor and saves the comment. The letters below are typed in command mode to obtain the specified function. To leave command mode and enter insert mode, you must use the function which is listed as the insert mode command. This defaults to 'R'. To select the vi like mode of operation, put _ASCEDVI in your MGT environment variable. Defaults are: .in +4m .ta .ta \w'delete to end of line (kill)\ \ 'u +8m + .nf Command emacs vi cursor up (previous line) ^P k cursor down (next line) ^N j page up (prev page) ]p ^B page down (next page) ]n ^F cursor left (back) ^B h cursor right (forward) ^F l beginning of line ^A 0 end of line ^E $ beginning of comment ]< H end of comment ]> L delete one character ^D x delete to end of line (kill) ^K D toggle insert mode ^I R save comment ]z w exit, don't save comment ^W q .fi .in -4m Pressing c on a comment larger than the 120 lines allocated for comments will cause the extra to be lost. Also, on terminals which generate IBM PC arrow key codes, the arrow keys will correctly move the cursor within the comment editor. The arrow keys only work in the emacs based model. .LP .TP 8 d Delete node. Deletes the current node, replacing it with its child. If the current node has no child, then clear the properties of the current node. .LP .TP 8 n Name the current node. You will be prompted for the name. .LP .TP 8 s Score the game. After selecting this, move the cursor around and remove the dead groups with 0 or space. You can undo one (and only one) kill with the u key. Pressing return will score the game and print the (Japanese) score in the comment area. If you missed some dead groups, continue removing them. Press q when you wish to exit scoring mode. You will be prompted to either keep the score information as a comment for the current node or restore the old comment. .LP .TP 8 Ctrl\-I Enter info mode. In this mode, the various informational properties of the current file are displayed and may be edited. To edit an item, press the letter associated with it, and enter the new text. This letter must be entered in upper case. To see a list of letters, press ?. The comment window scrolling keys can be used to scroll the info display. The supported info properties are: Size, Handicap, playerBlack, bLackrank, playerWhite, whIterank, Gamename, Event, rouNd, Date, Place, Time, Result, gameComment, sOurce, User, Komi. The capital letters in this list indicate which letter selects that info property. .LP .TP 8 Ctrl\-T Toggle tutor mode. (See the section on space or 0 for explanation.) .LP .TP 8 Ctrl\-W Toggle the format used for writing Smart\-Go files between long and short. .LP .TP 8 Ctrl\-L Refresh the screen. .LP .TP 8 Ctrl\-F Save the current screen to a file. .LP .TP 8 ? Display a help screen. .LP .TP 8 12346789 Move the cursor around. Assumes standard numeric keypad orientation. .LP .SH ENVIRONMENT SETTINGS All of the characters used for the commands and the display are configurable via environment variables. For the ascii interface, use: .LP .sp .if n \{.nf setenv MGT '_ASCCOM:q><.,eb}{][gwzxv\\!lm#^cdn spotrfLWTFI012346789kiju& _ASCCHAR:#O:+\-.+|\-++++ _ASCINV _ASCED:PNpnBFAE<>DKIzO' (command should appear all on one line with a single space separating _ASC... from the previous string.) .fi \} .if t \{.nf setenv MGT '_ASCCOM:q><.,eb}{][gwzxv\\!lm#^cdnspotrfLWTFI012346789kiju& _ASCCHAR:#O=+\-.+|\-++++ _ASCINV _ASCED:PNpnBFAE<>DKIzW' .fi .in +.25i (command should appear all on one line with a single space separating _ASC... from the previous string.) .in -.25i \} .LP to get the default characters. (This is csh syntax. For other shells, the syntax will be different.) Place this line in your .cshrc so the alternate characters are always in effect. .LP The _ASCCOM string allows you to change the keyboard commands. Upper case letters stand for control characters. .LP The _ASCCHAR string specifies the display characters. For example, to use @ for black stones, change the # to @ in the _ASCCHAR string. You need only include one of the two declarations ("_ASCCOM:" or "_ASCCHAR:") if you only want to change the commands or characters but not both. .LP To set the default display type to inverse video, use _ASCINV in the MGT environment variable. .LP To set the comment editor commands, use _ASCED in the MGT environment variable. For the _ASCED environment variable setting in the emacs based editor model, control keys are specified with a capital letter, and ESC keys are anything which is not a capital letter. This is the key string for the defaults: PNpnBFAE<>DKIzO. Note that ^V, ^O, ^C and ^Z are poor characters to use for anything if you have berkeley unix because the berkeley tty drivers interpret these characters. The ^V character is the quoting character which quotes the following character. You will need to press it twice for mgt to see it. The other characters have to be quoted by first pressing ^V or mgt will not recognize your keypress. You cannot use ^H or ^? for anything because the editor always interprets these as destructive backspace. For the _ASCED environment variable setting in the vi based editor model, no special processing is done on the characters. In order to specify control keys, you must place actual control characters into your environment string. The default string has two control commands (^B and ^F) defined. This is the default: kj^B^Fhl0$HLxDRwq. The vi based editor model may be selected be including _ASCEDVI in the environment variable. .LP If you wish to include control characters in your string, you can do this most easily by editing a file which sets the environment. Vi can insert most of the control characters directly. .LP In all cases, when you set your own keys, you must set all of the keys, and they must appear in the correct order. If you give assign the same key to different functions, then an arbitrary one will be used by .B mgt and the other functions will be unavailable. If multiple contradictory specifications occur in the .B mgt environment variable, the last that appear will be used by the program. Any option not specified will assume the default values identified above. .LP With the IBM version, the same effects may be achieved under DOS 4.0 or DOS 5.0 with a SET command placed in the AUTOEXEC.BAT file. Under previous DOS versions, quotes were interpreted literally and "|", ">" and "<" characters have special meanings and thus cannot be put into environment variables with the SET command. .LP Under VMS, the command is just MGT = "_ASCCHAR:..." .LP .SH COMMENT FORMATTING Comments are expected to consist of long lines, each of which is one paragraph. A single long line will be formatted to fit the display. Line breaks will be ignored if they are preceeded by a space, but will be respected otherwise. .SH DISPLAYS All displays have in common the purpose of displaying a go tree. .LP .ft CW .KS ASCII display: A B C D E F G H S T +--------------- ---+ -Suppose this is the second 19|. . . # . . . . . .|19| line of the comment. Since 18|. O O # # # O . . .|18| there is some more of the 17|. # # O O O O . . .|17| comment above us unseen, 16|. # O + . . . . . .|16| the - appears to the left 15|. # O . O . . . . .|15| of 'Suppose'. 14|. . # O . . . . . .|14| 13|. . # . . . . . . .|13| 12|. . . . . . . . . .|12| 11|. . . . . . . . . .|11| And here, when there is 10|. . . + . . . . . .|10| more of the comment 9|. . . . . . . . . .| 9| below, the '+' 8|. . . . . . . . . .| 8|+appears to our left. 7|. . . . . . . . . .| 7| 6|. . . . . . . . . .| 6| Node #173: Name 5|. . . . . . . . . .| 5|-B: variation 1 hit 'B' to see 4|. . . + . . . . . .| 4| C: variation 2 hit 'C' 3|. . . . . . . . . .| 3| D: variation 3 etc... 2|. . . . . . . . . .| 2| E: variation 4 1|. . . . . . . . . .| 1|+F: variation 5 +--------------- ---+ ? for help read long A B C D E F G H S T Black #11 at 'D19' #: 0 > O: 0 < .KE .LP The bottom line indicates that Black has just made move #11. On the bottom right, the angle brackets around the white stone indicate that it is White's turn. Above that, the word "read" indicates that the Smart\-Go file hasn't been modified, and "long" indicates that the default save format is the long format. "Read" will change to "edit" if you modify the file, and it will say "tutor" if you enter tutor mode. .SH FILES wrapmgt - prepare short format Smart-Go files for mailing .LP mailgo - email go game management .LP mgt2short - script to convert Smart-Go files to short format .LP RULES - an introduction to the game in Smart-Go format. .LP The .B From My Go Teacher tutorial lessons, and many professional game records all available at bsdserver.ucsf.edu .LP Internet go, a program to play go over internet, available on bsdserver.ucsf.edu .LP Smart\-Go.def, the Smart\-Go format definition. .sp .SH BUGS .LP Comment editing is limited to 120 screen lines. .LP Most, but not all, of the Smart-Go properties are supported. .LP Send bug reports to "adrian@bsdserver.ucsf.edu" or "hale@scam.Berkeley.EDU" .fi .sp .SH AUTHORS Greg Hale .LP Jeff Boscole .LP Adrian Mariano (adrian@bsdserver.ucsf.edu) .LP Mike Dobbins (mdobbins@asns.tredydev.unisys.com) .sp .SH SEE ALSO rec.games.go \- a newsgroup on the game .br Graded go problems for beginners, vol 1-4, Ishi Press .br In the Beginning, Ishi Press. .br The Treasure Chest Enigma, Ishi Press. mgt-2.31/mgt.h100640 1750 1750 6501 6176731455 11041 0ustar memmem/* "mgt" Copyright (c) 1991 Shodan */ #define VERSION "2.31" #ifdef DEBUG #define BUG(s) fprintf(debug,s) #else #define BUG(s) #endif #define FUNCTION #define false 0 #define true 1 #define MAX(a,b) ((a)>(b)?a:b) #define MIN(a,b) ((a)<(b)?a:b) #define MAX_FILES 200 #define MAXCOMMENTWIDTH 50 #define COMMENTALLOC 4096 typedef int boolean; typedef enum { C_QUIT = 0, C_DOWN, C_UP, C_WALKDOWN, C_WALKUP, C_END, C_BEGINNING, C_SEARCHCOMMENT, C_SEARCHBACKCOMMENT, C_DOWNFORK, C_UPFORK, C_GOTO, C_WRITE, C_ADDBLACK, C_ADDWHITE, C_ADDVAR, C_TREECUT, C_ADDLETTER, C_ADDMARK, C_LOAD, C_PASTE, C_EDCOMMENT, C_DELNODE, C_ADDNAME, C_SCORE, C_PASSMOVE, C_TOPLAY, C_TOGGLESTONE, C_BACKFILE, C_NEXTFILE, C_REDRAW, C_SAVESHORT, C_TUTORSWAP, C_SAVESCREEN, C_INFO, C_MOVE, C_DOWNLEFT, C_CURDOWN, C_DOWNRIGHT, C_CURLEFT, C_CURRIGHT, C_UPLEFT, C_CURUP, C_UPRIGHT, C_LASTCOMMAND, C_UNDO } command; /* C_COMMENTSCROLLDOWN, C_COMMENTSCROLLUP, C_TREESCROLLDOWN, C_TREESCROLLUP, */ #define C_NOTHING ((command) 75) #define C_CHOSECHILD ((command) 76) #define C_NEXTCMD ((command) 127) typedef enum { t_White, t_Black, t_Open, t_Close, t_NewNode, t_Comment, t_AddWhite, t_AddBlack, t_Letter, t_Mark, t_AddEmpty, t_Name, t_Pass, t_Player, t_Size, t_Handicap, t_PlayerBlack, t_BlackRank, t_PlayerWhite, t_WhiteRank, t_GameName, t_Event, t_Round, t_Date, t_Place, t_TimeLimit, t_Result, t_GameComment, t_Source, t_User, t_Komi, t_WS, t_EOF } Token; #define FIRSTINFO ((int)t_PlayerBlack) #define LASTINFO ((int)t_User) typedef enum { P_NOTHING = 0, P_BLACK, P_WHITE, P_DAME, P_BLACKTERR, P_WHITETERR, P_CHECKED } piece; typedef piece boardType[19][19]; typedef struct { boardType b; } board, *pBoard; typedef int (*pfi) (); typedef struct { char *name; char *option; char *storage; pfi open, close, refreshIO, plotPiece, displayComment; pfi clearComment, initializeBoard, clearScreen, idle; pfi drawTree, highlightLast, readEnv, notifyMessage; pfi notifyClear, queryStr, setCursor, plotMark, plotLetter; pfi getPoint, editComment, askYN, notifyError, displayInfo; pfi getInfoToChange, editInfo; } interface, *interfaceP; typedef struct { char x, y; } coord; typedef struct coordstruct { char x, y; struct coordstruct *next; } coordList; typedef struct propertyRec { struct propertyRec *next; Token t; union { coordList *stones; char *comment; Token player; } data; } property; typedef struct noderec { property *p; int nodeNum; struct noderec *parent, *child, *nextSibling, *lastSibling; } node, *nodep; /* board coordinates used to indicate a pass */ #define PASSVAL 25 #include "proto.h" #include #ifdef MGT_IBM #include #endif extern char *info[LASTINFO - FIRSTINFO + 2]; extern int handicap; extern int prisoners[]; extern interface *io; extern int boardsize; extern FILE *input; extern int xcur, ycur; extern Token curPlayer; extern int mailFlag; extern int saveShort; extern int tutor; extern char *saveName; extern int retVal; extern char name_buf[512]; extern filecount, currentfile; extern char *files[MAX_FILES]; #ifdef DEBUG extern FILE *debug; extern unsigned long totalmemory; #endif mgt-2.31/mgt2short100750 1750 1750 110 6176731472 11724 0ustar memmem#!/bin/sh for f in "$@" do mgt -s $f </dev/null w* qy EOF done mgt-2.31/mgt2short.6100640 1750 1750 666 6176731472 12106 0ustar memmem.TH MGT2SHORT 6 "26 February 1993" .SH NAME mgt2short - converts Smart-Go files to the short format. .SH SYNOPSIS .B mgt2short files .SH DESCRIPTION .B Mgt2short converts Smart-Go files to the short format by invoking .B mgt on each file and instructing mgt to save the file in the short format. This means that any data in the files which mgt does not recognize will be lost. .SH AUTHOR Adrian Mariano (adrian@bsdserver.ucsf.edu) mgt-2.31/mgtdoc.asc100640 1750 1750 46072 6176731465 12076 0ustar memmem 9 July 1993 MGT(6) NAME mgt - game record display/editor for the oriental game of go SYNOPSIS mgt [-m filename] [-s] [-t] [files] DESCRIPTION Go is an ancient oriental strategy game based on the capturing of terri- tory. The players alternate putting stones on the board, trying to sur- round as many empty intersections as possible. Mgt allows the user to examine Go game tree files created through the Macintosh(tm) programs Smart-Go (tm) or Go Explorer (tm). Mgt also has basic Go game tree editing capabilities and may be used to create or edit game tree files. The on-line material provided by a rather exten- sive and growing database allows many hours of instructional enjoyment of various studies and tutorials concerning the game of Go. Mailgo is a utility which manages E-mail Go games using mgt as the Go board editor. It is included in the mgt package. The mgt program was originally developed to be a companion for the series, "From My Go Teacher", archived bsdserver.ucsf.edu for ftp. Also available is the Internet GO Board communications program, 'go', also by Greg Hale, which connects up two terminals in real-time anywhere in the world, and the clients for the Internet Go Server. COMMAND LINE OPTIONS -m filename Invoke a set of options used by the mailgo program for managing email games. If a filename is specified for loading (see below), the game record is loaded, and mgt automatically moves to the end of the main variation of the game record. The game can be modified without confirmation. If the game record has been modified, it will be automatically saved, on exit, to the filename specified after the -m and mgt will return success (zero). If the game record has not been modified, or has not been allowed to be saved, then mgt will return failure (nonzero). -s Change save format used to write save files. The default save format is the long format Smart-Go file. Using this option results in short format Smart-Go files. -t Invoke tutor mode where you select variations by playing on the board. The key for making a move has special behavior in this mode. See the section on the "space or 0" keyboard command for a description. files These are the files to be loaded. The Unix and IBM version sup- port wildcards. If no file is specified, mgt loads a blank board. If you attempt to modify a file that was loaded, mgt 1 MGT(6) 9 July 1993 will prompt for confirmation the first time. OPERATION Mgt can be used to view and edit game records, or as an electronic game board for a two person game. There are many keyboard commands which execute the various editing and display functions. > Step down the game tree to the next move. Stop at the end of a variation and do not visit other variations. < Move back up the game tree. (Previous move) . Go to the next node using a tree traversal which will visit all nodes. Sometimes the order of traversal can be confusing. , Go to the previous node -- the opposite of "." forward movement. e Go to end of the current variation. b Go to beginning of the game tree. } Go forward like the "." command until a comment. { Go backwards like the "," command until a comment. g Go to a specified node. Type in the desired node number. ] Move forward until there is a variation branch in the game tree. [ Move backwards until there is a variation branch in the game tree. k and i Scroll the game tree variation window up and down. A - at the top of the variation window, and a + at the bottom indicate that more variations are available. j and u Scroll comment window up and down. A - at the top of the com- ment, and a + at the bottom indicate that more comments are available. # Load new file. Will prompt for confirmation if the current file has been modified. r Load previous file. (Reverse through the file list) f Load next file. (Forward through the file list) w Write out Smart-Go file. Will prompt for a filename. The spe- cial filename * will save with the current name (which appears in the upper right corner). space or 0 Make a move. The current player turn is indicated by the > < around the captured stones on the lower right. Normally, this 2 9 July 1993 MGT(6) adds the move to the game tree and moves to a new node. In tutor mode, it checks the various game continuations. If one of them contains the move you made, it moves to that variation. If not, it prints an error message. The game tree cannot be modi- fied in tutor mode. p Pass. Enter a pass move. o Other player. Changes whose turn it is, adding a token in the game tree to force the change whenever this node is visited. If the player is forced by such a token, the current player turn is indicated by } { characters on the lower right. t Toggle stone color. Changes whose turn it is without adding any tokens in the game tree. This will not work if the game tree has a PLayer token (generated by the o key) at the current node. z Set/unset black stones. x Set/unset white stones. q or ESC. Quit. q will prompt for confirmation. ESC will not prompt for confirmation. v Create a variation below the current node. The variation will initially contain a null node. You must move to that variation to make a move in it. If the "v" command is invoked at a node which is at the end of a variation, variation "A" is created with a null node. Subsequent invocations of the "v" command will create the "B", "C"... variations. ! Cut tree. Moves the current node and everything below it to a temporary holding buffer. (Moves your location back to the parent of the node you are one when you invoke it.) ^ Paste tree. Pastes the temporary holding buffer in after the current node. Usually the opposite of cutting the tree. c Edit the current comment. The editor has two models of opera- tion. The default model has been vaguely designed after emacs. That means that the editor commands are either 'control-key' or 'escape-key'. The controls are configurable through an environ- ment variable. The notation "^key" is used to indicate control keys, and "]key" is used to indicate keys which should be pre- ceeded by the escape character. On some terminals, instead of ESC-key, you can press Alt-key or Meta-key. (On the IBM version, you can use the Alt key.) Under VMS, the ESC key does not work. VMS users may need to redefine the edit keys. The second edit model was vaguely designed after vi. That means that the editor has a command mode for cursor movement, etc. and 3 MGT(6) 9 July 1993 an insert mode for inserting text. The vi model editor starts in insert mode. The ESC key changes mode from insert mode to command mode. If pressed in command mode, the ESC key exits the comment editor and saves the comment. The letters below are typed in command mode to obtain the specified function. To leave command mode and enter insert mode, you must use the function which is listed as the insert mode command. This defaults to 'R'. To select the vi like mode of operation, put _ASCEDVI in your MGT environment variable. Defaults are: Command emacs vi cursor up (previous line) ^P k cursor down (next line) ^N j page up (prev page) ]p ^B page down (next page) ]n ^F cursor left (back) ^B h cursor right (forward) ^F l beginning of line ^A 0 end of line ^E $ beginning of comment ]< H end of comment ]> L delete one character ^D x delete to end of line (kill) ^K D toggle insert mode ^I R save comment ]z w exit, don't save comment ^W q Pressing c on a comment larger than the 120 lines allocated for comments will cause the extra to be lost. Also, on terminals which generate IBM PC arrow key codes, the arrow keys will correctly move the cursor within the comment editor. The arrow keys only work in the emacs based model. d Delete node. Deletes the current node, replacing it with its child. If the current node has no child, then clear the proper- ties of the current node. n Name the current node. You will be prompted for the name. s Score the game. After selecting this, move the cursor around and remove the dead groups with 0 or space. You can undo one (and only one) kill with the u key. Pressing return will score the game and print the (Japanese) score in the comment area. If you missed some dead groups, continue removing them. Press q when you wish to exit scoring mode. You will be prompted to either keep the score information as a comment for the current node or restore the old comment. Ctrl-I Enter info mode. In this mode, the various informational pro- perties of the current file are displayed and may be edited. To edit an item, press the letter associated with it, and enter the new text. This letter must be entered in upper case. To see a list of letters, press ?. The comment window scrolling keys can 4 9 July 1993 MGT(6) be used to scroll the info display. The supported info proper- ties are: Size, Handicap, playerBlack, bLackrank, playerWhite, whIterank, Gamename, Event, rouNd, Date, Place, Time, Result, gameComment, sOurce, User, Komi. The capital letters in this list indicate which letter selects that info property. Ctrl-T Toggle tutor mode. (See the section on space or 0 for explana- tion.) Ctrl-W Toggle the format used for writing Smart-Go files between long and short. Ctrl-L Refresh the screen. Ctrl-F Save the current screen to a file. ? Display a help screen. 12346789 Move the cursor around. Assumes standard numeric keypad orien- tation. ENVIRONMENT SETTINGS All of the characters used for the commands and the display are confi- gurable via environment variables. For the ascii interface, use: setenv MGT '_ASCCOM:q><.,eb}{][gwzxv\!lm#^cdn spotrfLWTFI012346789kiju& _ASCCHAR:#O:+-.+|-++++ _ASCINV _ASCED:PNpnBFAE<>DKIzO' (command should appear all on one line with a single space separating _ASC... from the previous string.) to get the default characters. (This is csh syntax. For other shells, the syntax will be different.) Place this line in your .cshrc so the alternate characters are always in effect. The _ASCCOM string allows you to change the keyboard commands. Upper case letters stand for control characters. The _ASCCHAR string specifies the display characters. For example, to use @ for black stones, change the # to @ in the _ASCCHAR string. You need only include one of the two declarations ("_ASCCOM:" or "_ASCCHAR:") if you only want to change the commands or characters but not both. To set the default display type to inverse video, use _ASCINV in the MGT environment variable. To set the comment editor commands, use _ASCED in the MGT environment variable. 5 MGT(6) 9 July 1993 For the _ASCED environment variable setting in the emacs based editor model, control keys are specified with a capital letter, and ESC keys are anything which is not a capital letter. This is the key string for the defaults: PNpnBFAE<>DKIzO. Note that ^V, ^O, ^C and ^Z are poor characters to use for anything if you have berkeley unix because the berkeley tty drivers interpret these characters. The ^V character is the quoting character which quotes the following character. You will need to press it twice for mgt to see it. The other characters have to be quoted by first pressing ^V or mgt will not recognize your keypress. You cannot use ^H or ^? for anything because the editor always inter- prets these as destructive backspace. For the _ASCED environment variable setting in the vi based editor model, no special processing is done on the characters. In order to specify control keys, you must place actual control characters into your environment string. The default string has two control commands (^B and ^F) defined. This is the default: kj^B^Fhl0$HLxDRwq. The vi based edi- tor model may be selected be including _ASCEDVI in the environment vari- able. If you wish to include control characters in your string, you can do this most easily by editing a file which sets the environment. Vi can insert most of the control characters directly. In all cases, when you set your own keys, you must set all of the keys, and they must appear in the correct order. If you give assign the same key to different functions, then an arbitrary one will be used by mgt and the other functions will be unavailable. If multiple contradictory specifications occur in the mgt environment variable, the last that appear will be used by the program. Any option not specified will assume the default values identified above. With the IBM version, the same effects may be achieved under DOS 4.0 or DOS 5.0 with a SET command placed in the AUTOEXEC.BAT file. Under pre- vious DOS versions, quotes were interpreted literally and "|", ">" and "<" characters have special meanings and thus cannot be put into environment variables with the SET command. Under VMS, the command is just MGT = "_ASCCHAR:..." COMMENT FORMATTING Comments are expected to consist of long lines, each of which is one paragraph. A single long line will be formatted to fit the display. Line breaks will be ignored if they are preceeded by a space, but will be respected otherwise. DISPLAYS All displays have in common the purpose of displaying a go tree. 6 9 July 1993 MGT(6) ASCII display: A B C D E F G H S T +--------------- ---+ -Suppose this is the second 19|. . . # . . . . . .|19| line of the comment. Since 18|. O O # # # O . . .|18| there is some more of the 17|. # # O O O O . . .|17| comment above us unseen, 16|. # O + . . . . . .|16| the - appears to the left 15|. # O . O . . . . .|15| of 'Suppose'. 14|. . # O . . . . . .|14| 13|. . # . . . . . . .|13| 12|. . . . . . . . . .|12| 11|. . . . . . . . . .|11| And here, when there is 10|. . . + . . . . . .|10| more of the comment 9|. . . . . . . . . .| 9| below, the '+' 8|. . . . . . . . . .| 8|+appears to our left. 7|. . . . . . . . . .| 7| 6|. . . . . . . . . .| 6| Node #173: Name 5|. . . . . . . . . .| 5|-B: variation 1 hit 'B' to see 4|. . . + . . . . . .| 4| C: variation 2 hit 'C' 3|. . . . . . . . . .| 3| D: variation 3 etc... 2|. . . . . . . . . .| 2| E: variation 4 1|. . . . . . . . . .| 1|+F: variation 5 +--------------- ---+ ? for help read long A B C D E F G H S T Black #11 at 'D19' #: 0 > O: 0 < The bottom line indicates that Black has just made move #11. On the bottom right, the angle brackets around the white stone indicate that it is White's turn. Above that, the word "read" indicates that the Smart-Go file hasn't been modified, and "long" indicates that the default save format is the long format. "Read" will change to "edit" if you modify the file, and it will say "tutor" if you enter tutor mode. FILES wrapmgt - prepare short format Smart-Go files for mailing mailgo - email go game management mgt2short - script to convert Smart-Go files to short format RULES - an introduction to the game in Smart-Go format. The From My Go Teacher tutorial lessons, and many professional game records all available at bsdserver.ucsf.edu Internet go, a program to play go over internet, available on bsdserver.ucsf.edu Smart-Go.def, the Smart-Go format definition. 7 MGT(6) 9 July 1993 BUGS Comment editing is limited to 120 screen lines. Most, but not all, of the Smart-Go properties are supported. Send bug reports to "adrian@bsdserver.ucsf.edu" or "hale@scam.Berkeley.EDU" AUTHORS Greg Hale Jeff Boscole Adrian Mariano (adrian@bsdserver.ucsf.edu) Mike Dobbins (mdobbins@asns.tredydev.unisys.com) SEE ALSO rec.games.go - a newsgroup on the game Graded go problems for beginners, vol 1-4, Ishi Press In the Beginning, Ishi Press. The Treasure Chest Enigma, Ishi Press. 8 mgt-2.31/mgtshort.bat100640 1750 1750 55 6176731473 12376 0ustar memmemfor %%f in (%1) do mgt -s %%f < mgtshort.cmd mgt-2.31/mgtshort.cmd100640 1750 1750 10 6176731473 12362 0ustar memmemw* qy mgt-2.31/mou.h100640 1750 1750 12477 6176731456 11104 0ustar memmem/***************************************************************************** * PROJECT: Mouse routines with 'real' graphic cursor in text mode. ***************************************************************************** * MODULE: MOU.H ***************************************************************************** * DESCRIPTION: * Header file for the mouse routines. * ***************************************************************************** * MODIFICATION NOTES: * Date Author Comment * 07-Jan-1991 dk Fixed bugs and set up for release to Usenet. * 26-Oct-1990 dk Initial file. ***************************************************************************** * * DISCLAIMER: * * Programmers may incorporate any or all code into their programs, * giving proper credit within the source. Publication of the * source routines is permitted so long as proper credit is given * to Dave Kirsch. * * Copyright (C) 1990, 1991 by Dave Kirsch. You may use this program, or * code or tables extracted from it, as desired without restriction. * I can not and will not be held responsible for any damage caused from * the use of this software. * ***************************************************************************** * This source works with Turbo C 2.0 and MSC 6.0 and above. *****************************************************************************/ /********************************************************/ /* 26-Oct-1990 - dk */ /* */ /* Standard types and constants I use in my programs. */ /* */ /********************************************************/ typedef unsigned char byte; typedef unsigned short int word; typedef unsigned short int mouseboolean; typedef unsigned long int dword; #define FALSE 0 #define TRUE (!FALSE) #ifdef __TURBOC__ #define FAST pascal /* for fast calling of functions -- Turbo C */ #else #define FAST _fastcall /* for fast calling of functions -- MicroSoft C 6.0 */ #define asm _asm #endif #define LOCAL near /* function can not be called outside of this module */ #define PRIVATE static /* function is private */ #define STATIC static /* private variables */ #ifndef MK_FP #define MK_FP(seg,ofs) ((void far *) \ (((unsigned long)(seg) << 16) | (unsigned)(ofs))) #endif #ifndef poke #define poke(a,b,c) (*((int far*)MK_FP((a),(b))) = (int)(c)) #define pokeb(a,b,c) (*((char far*)MK_FP((a),(b))) = (char)(c)) #define peek(a,b) (*((int far*)MK_FP((a),(b)))) #define peekb(a,b) (*((char far*)MK_FP((a),(b)))) #endif /***************************************************/ /* Mon 07-Jan-1991 - dk */ /* */ /* Variables and defines for the mouse routines. */ /* */ /***************************************************/ /* Size of mouse "click" ahead buffer. */ #define MOUSEBUFFERSIZE 16 /* Bit defines for mouse driver function 12 -- define handler. */ #define MOUSEMOVE 1 #define LEFTBPRESS 2 #define LEFTBRELEASE 4 #define RIGHTBPRESS 8 #define RIGHTBRELEASE 16 #define MIDBPRESS 32 #define MIDBRELEASE 64 #define LEFTBDOWN 1 #define RIGHTBDOWN 2 #define MIDBDOWN 4 /* Shift states for byte a 0:417h bit 7 =1 INSert active bit 6 =1 Caps Lock active bit 5 =1 Num Lock active bit 4 =1 Scroll Lock active bit 3 =1 either Alt pressed bit 2 =1 either Ctrl pressed bit 1 =1 Left Shift pressed bit 0 =1 Right Shift pressed */ #define SHIFT_RIGHTSHIFT 0x01 #define SHIFT_LEFTSHIFT 0x02 #define SHIFT_SHIFT 0x03 /* Either shift key. */ #define SHIFT_CTRL 0x04 #define SHIFT_ALT 0x08 #define SHIFT_SCROLLLOCK 0x10 #define SHIFT_NUMLOCK 0x20 #define SHIFT_CAPSLOCK 0x40 #define SHIFT_INS 0x80 /* Mouse information record */ struct minforectype { word buttonstat; word cx, cy; byte shiftstate; }; #define MOUINFOREC struct minforectype extern word mousehidden; /* Is the mouse on? Additive flag */ extern mouseboolean mouseinstalled; /* Is the mouse installed? */ extern volatile word mousex, mousey; /* Mouse coordinates in characters. */ /* Initialize the mouse routines -- must be called. */ void FAST MOUinit(void); /* Deinitialize the mouse routines -- must be called on shutdown. Failure to call it will most likely result in a system crash if the mouse is moved. */ void FAST MOUdeinit(void); /* Hide the mouse cursor */ void FAST MOUhide(void); /* Hide the mouse cursor if it moves or is in a specific rectangular region of the screen. */ void FAST MOUconditionalhide(int x1, int y1, int x2, int y2); /* Show the mouse cursor */ void FAST MOUshow(void); /* return TRUE if there are events waiting in the buffer. */ mouseboolean FAST MOUcheck(void); /* look at the next event in the buffer, but don't pull it out. */ void FAST MOUpreview(MOUINFOREC *mouinforec); /* get and remove next event from the buffer. */ void FAST MOUget(MOUINFOREC *mouinforec); /* return the current status of the mouse buttons (see defines above). */ word FAST MOUbuttonstatus(void); /* Set the mouse cursor to a specific screen position. */ void FAST MOUsetpos(word x, word y); mgt-2.31/proto.h100640 1750 1750 4401 6176731455 11412 0ustar memmemextern void clearLast(); extern void highlightLast(); extern void doPlace(); extern void doProps(); extern void doPropComment(); extern void buildTree0(); extern void buildTree(); extern void setPiece(); extern void updateBoard(); extern char *commentGet(); /* int */ extern int commentLines(); extern void formatComment(); extern int okChange(); extern int okExit(); extern nodep search(); /* return 0 on failure */ extern void step(); extern void stepDown(); extern void doScore(); extern nodep loadFile(); extern nodep makeTutor(); extern void doit(); extern void writeStrEscaped(); extern void writeNode(); extern void WriteSubTree(); extern int writeCoordList(); extern int writeTree(); extern int addMark(); extern void addStone(); extern int makeMove(); extern int passMove(); extern void addPlayer(); extern void makeVariation(); extern void cutTree(); extern boolean pasteTree(); extern void edComment(); extern void deleteNode(); extern void makeName(); extern void replaceComment(); extern main(); extern void die(); extern void myexit(); extern void openfile(); extern void barf(); extern void initEnv(); extern void init(); extern void helpCommandLine(); extern void parseLine(); extern void readInit(); extern void addChild(); /* add child c to node n */ extern nodep parse(); extern int legal(); extern boolean inRange(); extern boolean alive0(); extern boolean alive(); /* Does group at i,j have liberties? */ extern void removeStones(); extern boolean tryKill(); extern void placeStone(); extern void boardSet(); extern piece boardGet(); extern void boardClear(); extern void copyBoard(); extern void scoreBoard(); extern boolean getCoord(); extern coordList *addCoord(); extern void setCoord(); extern void clearCoord(); extern void initNodes(); extern nodep newNode(); extern void freeNode(); extern char *dupStr(); extern void freeProps(); extern void delNode(); extern void addprop(); extern property *getprop(); extern int treeCountSiblings(); extern nodep nthChild(); /* nodep, int */ extern nodep parent(); extern nodep child(); extern nodep lastSibling(); extern nodep nextSibling(); extern nodep treeLastSibling(); extern nodep treeDown(); extern nodep treeUp(); extern nodep treeNextUp(); extern nodep treeNext(); extern nodep lastChildOfLastSibling(); extern nodep treeLast(); mgt-2.31/wrapmgt.6100640 1750 1750 1436 6176731472 11652 0ustar memmem.TH WRAPMGT 6 "23 November 1992" .SH NAME wrapmgt - wraps long lines in Smart-Go files to make them safe to post or email .SH SYNOPSIS .B wrapmgt [nn] .SH DESCRIPTION .B Wrapmgt formats Smart-Go files as generated by .B mgt so that the lines are shorter than nn, the number specified on the command line. The default format width is 79 characters. .B Wrapmgt reads its input from stdin and writes to stdout. This means you should invoke it using I/O redirection which is done under unix and DOS with wrapmgt < infile > outfile. .LP The files are formatted in such a way that if the files are viewed in mgt after being formatted, they will look the same as the original. The new line breaks will be visible from within the editor, however. .SH AUTHOR Adrian Mariano (adrian@bsdserver.ucsf.edu) mgt-2.31/wrapmgt100755 1750 1750 12050 6177513625 11526 0ustar memmemELF4 4 (444   d dd/lib/ld-linux.so.1    d,*0 6DKX>VPTb"j(8qH"v 8b@$TTh"! Flibc.so.5_DYNAMIC_GLOBAL_OFFSET_TABLE__init_fini__fpu_controlstrcpy__setfpucw_IO_stderr_fprintfatexitatoi__environexitfeof__uflow__overflow_IO_stdin__IO_stdout_fputsenviron__libc_init_etext_edata__bss_start_endP8<@DH LP T X \`50%4%8h%<h%@h%Dh%Hh %Lh(%Ph0%Th8p%Xh@`%\hHP%`hP@YЃPSQ̀D$P;haLP^[t&̀&S(=(t Ѓ;u[Í6ÐUpWVSEU EO~%hhPj u+BPEuh hPj611EE69wh] D+}u< < < }tt |+ ut+}u!~D+<w|+]u |+\ttt|+Cu|+[u'EE|+[ut|+\tE}t&|+]ut|+\tEE}u |+;ut+|+ uD+h]S޻C9]}9s= 9wPh&  G9rá 9wj h&   }D+VWk10ЍXhkD+hEPe[^_]ÐS=t Ѓ;u[Í6Ð Wrong number of arguments. Invalid limit d.>N^n  < ,XL, GCC: (GNU) 2.7.2GCC: (GNU) 2.7.2GCC: (GNU) 2.7.2.symtab.strtab.shstrtab.interp.hash.dynsym.dynstr.rel.bss.rel.plt.init.plt.text.fini.rodata.data.ctors.dtors.got.dynamic.bss.comment#) 1<<9 ,, B LLXKQVT\b-j p w$$ ~,, 8dd   6* 4@( t        1  > I W(dk   p $ I    dTPT$b F! ""T-;p B Q]  b@j p(8w~,8H"X>h"crtstuff.cgcc2_compiled.__do_global_ctors_aux__CTOR_END__init_dummyforce_to_data__DTOR_END__crt0.Sdone__do_global_dtors_aux__DTOR_LIST__fini_dummy__CTOR_LIST__wrapmgt.cstrcpy_DYNAMIC_etext_IO_stdout__IO_stderr___overflowfeof__environ_init__libc_initenvironfprintf_IO_stdin___fpu_control_start___crt_dummy____bss_startmain__uflow_finiatexit_edata_GLOBAL_OFFSET_TABLE__endexitatoi__setfpucwfputsmgt-2.31/mgt.doc100644 1750 1750 56153 6177477720 11416 0ustar memmem 1 MGT(6) MGT(6) NNAAMMEE mgt - game record display/editor for the oriental game of go SSYYNNOOPPSSIISS mmggtt [-m filename] [-s] [-t] [files] DDEESSCCRRIIPPTTIIOONN Go is an ancient oriental strategy game based on the cap- turing of territory. The players alternate putting stones on the board, trying to surround as many empty intersec- tions as possible. MMggtt allows the user to examine Go game tree files created through the Macintosh(tm) programs SSmmaarrtt--GGoo ((ttmm)) or GGoo EExxpplloorreerr ((ttmm)).. MMggtt also has basic Go game tree editing capabilities and may be used to create or edit game tree files. The on-line material provided by a rather exten- sive and growing database allows many hours of instruc- tional enjoyment of various studies and tutorials concern- ing the game of Go. MMaaiillggoo is a utility which manages E-mail Go games using mmggtt as the Go board editor. It is included in the mmggtt package. The mmggtt program was originally developed to be a companion for the series, "From My Go Teacher", archived bsd- server.ucsf.edu for ftp. Also available is the Internet GO Board communications program, 'go', also by Greg Hale, which connects up two terminals in real-time anywhere in the world, and the clients for the Internet Go Server. CCOOMMMMAANNDD LLIINNEE OOPPTTIIOONNSS --mm ffiilleennaammee Invoke a set of options used by the mmaaiillggoo program for managing email games. If a filename is speci- fied for loading (see below), the game record is loaded, and mmggtt automatically moves to the end of the main variation of the game record. The game can be modified without confirmation. If the game record has been modified, it will be automatically saved, on exit, to the filename specified after the -m and mmggtt will return success (zero). If the game record has not been modified, or has not been allowed to be saved, then mmggtt will return failure (nonzero). --ss Change save format used to write save files. The default save format is the long format Smart-Go file. Using this option results in short format Smart-Go files. 9 July 1993 1 MGT(6) MGT(6) --tt Invoke tutor mode where you select variations by playing on the board. The key for making a move has special behavior in this mode. See the sec- tion on the "space or 0" keyboard command for a description. ffiilleess These are the files to be loaded. The Unix and IBM version support wildcards. If no file is specified, mmggtt loads a blank board. If you attempt to modify a file that was loaded, mmggtt will prompt for confirmation the first time. OOPPEERRAATTIIOONN MMggtt can be used to view and edit game records, or as an electronic game board for a two person game. There are many keyboard commands which execute the various editing and display functions. > Step down the game tree to the next move. Stop at the end of a variation and do not visit other variations. < Move back up the game tree. (Previous move) . Go to the next node using a tree traversal which will visit all nodes. Sometimes the order of traversal can be confusing. , Go to the previous node -- the opposite of "." forward movement. e Go to end of the current variation. b Go to beginning of the game tree. } Go forward like the "." command until a comment. { Go backwards like the "," command until a comment. g Go to a specified node. Type in the desired node number. 9 July 1993 2 MGT(6) MGT(6) ] Move forward until there is a variation branch in the game tree. [ Move backwards until there is a variation branch in the game tree. k and i Scroll the game tree variation window up and down. A - at the top of the variation window, and a + at the bottom indicate that more variations are available. j and u Scroll comment window up and down. A - at the top of the comment, and a + at the bottom indicate that more comments are available. # Load new file. Will prompt for confirmation if the current file has been modified. r Load previous file. (Reverse through the file list) f Load next file. (Forward through the file list) w Write out Smart-Go file. Will prompt for a file- name. The special filename * will save with the current name (which appears in the upper right corner). space or 0 Make a move. The current player turn is indicated by the > < around the captured stones on the lower right. Normally, this adds the move to the game tree and moves to a new node. In tutor mode, it checks the various game continuations. If one of them contains the move you made, it moves to that variation. If not, it prints an error message. The game tree cannot be modified in tutor mode. p Pass. Enter a pass move. o Other player. Changes whose turn it is, adding a token in the game tree to force the change when- ever this node is visited. If the player is forced by such a token, the current player turn is 9 July 1993 3 MGT(6) MGT(6) indicated by } { characters on the lower right. t Toggle stone color. Changes whose turn it is without adding any tokens in the game tree. This will not work if the game tree has a PLayer token (generated by the o key) at the current node. z Set/unset black stones. x Set/unset white stones. q or ESC. Quit. q will prompt for confirmation. ESC will not prompt for confirmation. v Create a variation below the current node. The variation will initially contain a null node. You must move to that variation to make a move in it. If the "v" command is invoked at a node which is at the end of a variation, variation "A" is cre- ated with a null node. Subsequent invocations of the "v" command will create the "B", "C"... varia- tions. ! Cut tree. Moves the current node and everything below it to a temporary holding buffer. (Moves your location back to the parent of the node you are one when you invoke it.) ^ Paste tree. Pastes the temporary holding buffer in after the current node. Usually the opposite of cutting the tree. c Edit the current comment. The editor has two mod- els of operation. The default model has been vaguely designed after emacs. That means that the editor commands are either 'control-key' or 'escape-key'. The controls are configurable through an environment variable. The notation "^key" is used to indicate control keys, and "]key" is used to indicate keys which should be preceeded by the escape character. On some terminals, instead of ESC-key, you can press Alt-key or Meta-key. (On the IBM version, you can use the Alt key.) Under VMS, the ESC key 9 July 1993 4 MGT(6) MGT(6) does not work. VMS users may need to redefine the edit keys. The second edit model was vaguely designed after vi. That means that the editor has a command mode for cursor movement, etc. and an insert mode for inserting text. The vi model editor starts in insert mode. The ESC key changes mode from insert mode to command mode. If pressed in command mode, the ESC key exits the comment editor and saves the comment. The letters below are typed in command mode to obtain the specified function. To leave command mode and enter insert mode, you must use the function which is listed as the insert mode command. This defaults to 'R'. To select the vi like mode of operation, put _ASCEDVI in your MGT environment variable. Defaults are: Command emacs vi cursor up (previous line) ^P k cursor down (next line) ^N j page up (prev page) ]p ^B page down (next page) ]n ^F cursor left (back) ^B h cursor right (forward) ^F l beginning of line ^A 0 end of line ^E $ beginning of comment ]< H end of comment ]> L delete one character ^D x delete to end of line (kill) ^K D toggle insert mode ^I R save comment ]z w exit, don't save comment ^W q Pressing c on a comment larger than the 120 lines allocated for comments will cause the extra to be lost. Also, on terminals which generate IBM PC arrow key codes, the arrow keys will correctly move the cursor within the comment editor. The arrow keys only work in the emacs based model. d Delete node. Deletes the current node, replacing it with its child. If the current node has no child, then clear the properties of the current node. n Name the current node. You will be prompted for the name. 9 July 1993 5 MGT(6) MGT(6) s Score the game. After selecting this, move the cursor around and remove the dead groups with 0 or space. You can undo one (and only one) kill with the u key. Pressing return will score the game and print the (Japanese) score in the comment area. If you missed some dead groups, continue removing them. Press q when you wish to exit scoring mode. You will be prompted to either keep the score information as a comment for the current node or restore the old comment. Ctrl-I Enter info mode. In this mode, the various infor- mational properties of the current file are dis- played and may be edited. To edit an item, press the letter associated with it, and enter the new text. This letter must be entered in upper case. To see a list of letters, press ?. The comment window scrolling keys can be used to scroll the info display. The supported info properties are: Size, Handicap, playerBlack, bLackrank, player- White, whIterank, Gamename, Event, rouNd, Date, Place, Time, Result, gameComment, sOurce, User, Komi. The capital letters in this list indicate which letter selects that info property. Ctrl-T Toggle tutor mode. (See the section on space or 0 for explanation.) Ctrl-W Toggle the format used for writing Smart-Go files between long and short. Ctrl-L Refresh the screen. Ctrl-F Save the current screen to a file. ? Display a help screen. 12346789 Move the cursor around. Assumes standard numeric keypad orientation. EENNVVIIRROONNMMEENNTT SSEETTTTIINNGGSS All of the characters used for the commands and the dis- play are configurable via environment variables. For the ascii interface, use: 9 July 1993 6 MGT(6) MGT(6) setenv MGT '_ASCCOM:q><.,eb}{][gwzxv\!lm#^cdn spotrfLWTFI012346789kiju& _ASCCHAR:#O:+-.+|-++++ _ASCINV _ASCED:PNpnBFAE<>DKIzO' (command should appear all on one line with a single space separating _ASC... from the previous string.) to get the default characters. (This is csh syntax. For other shells, the syntax will be different.) Place this line in your .cshrc so the alternate characters are always in effect. The _ASCCOM string allows you to change the keyboard com- mands. Upper case letters stand for control characters. The _ASCCHAR string specifies the display characters. For example, to use @ for black stones, change the # to @ in the _ASCCHAR string. You need only include one of the two declarations ("_ASCCOM:" or "_ASCCHAR:") if you only want to change the commands or characters but not both. To set the default display type to inverse video, use _ASCINV in the MGT environment variable. To set the comment editor commands, use _ASCED in the MGT environment variable. For the _ASCED environment variable setting in the emacs based editor model, control keys are specified with a cap- ital letter, and ESC keys are anything which is not a cap- ital letter. This is the key string for the defaults: PNpnBFAE<>DKIzO. Note that ^V, ^O, ^C and ^Z are poor characters to use for anything if you have berkeley unix because the berkeley tty drivers interpret these charac- ters. The ^V character is the quoting character which quotes the following character. You will need to press it twice for mgt to see it. The other characters have to be quoted by first pressing ^V or mgt will not recognize your keypress. You cannot use ^H or ^? for anything because the editor always interprets these as destructive backspace. For the _ASCED environment variable setting in the vi based editor model, no special processing is done on the characters. In order to specify control keys, you must place actual control characters into your environment string. The default string has two control commands (^B and ^F) defined. This is the default: kj^B^Fhl0$HLxDRwq. The vi based editor model may be selected be including _ASCEDVI in the environment variable. If you wish to include control characters in your string, 9 July 1993 7 MGT(6) MGT(6) you can do this most easily by editing a file which sets the environment. Vi can insert most of the control char- acters directly. In all cases, when you set your own keys, you must set all of the keys, and they must appear in the correct order. If you give assign the same key to different functions, then an arbitrary one will be used by mmggtt and the other functions will be unavailable. If multiple contradictory specifications occur in the mmggtt environment variable, the last that appear will be used by the program. Any option not specified will assume the default values identified above. With the IBM version, the same effects may be achieved under DOS 4.0 or DOS 5.0 with a SET command placed in the AUTOEXEC.BAT file. Under previous DOS versions, quotes were interpreted literally and "|", ">" and "<" characters have special meanings and thus cannot be put into environ- ment variables with the SET command. Under VMS, the command is just MGT = "_ASCCHAR:..." CCOOMMMMEENNTT FFOORRMMAATTTTIINNGG Comments are expected to consist of long lines, each of which is one paragraph. A single long line will be for- matted to fit the display. Line breaks will be ignored if they are preceeded by a space, but will be respected oth- erwise. DDIISSPPLLAAYYSS All displays have in common the purpose of displaying a go tree. AASSCCIIII ddiissppllaayy:: AA BB CC DD EE FF GG HH SS TT ++------------------------------ ------++ --SSuuppppoossee tthhiiss iiss tthhee sseeccoonndd 1199||.. .. .. ## .. .. .. .. .. ..||1199|| lliinnee ooff tthhee ccoommmmeenntt.. SSiinnccee 1188||.. OO OO ## ## ## OO .. .. ..||1188|| tthheerree iiss ssoommee mmoorree ooff tthhee 1177||.. ## ## OO OO OO OO .. .. ..||1177|| ccoommmmeenntt aabboovvee uuss uunnsseeeenn,, 1166||.. ## OO ++ .. .. .. .. .. ..||1166|| tthhee -- aappppeeaarrss ttoo tthhee lleefftt 1155||.. ## OO .. OO .. .. .. .. ..||1155|| ooff ''SSuuppppoossee''.. 1144||.. .. ## OO .. .. .. .. .. ..||1144|| 1133||.. .. ## .. .. .. .. .. .. ..||1133|| 1122||.. .. .. .. .. .. .. .. .. ..||1122|| 1111||.. .. .. .. .. .. .. .. .. ..||1111|| AAnndd hheerree,, wwhheenn tthheerree iiss 1100||.. .. .. ++ .. .. .. .. .. ..||1100|| mmoorree ooff tthhee ccoommmmeenntt 99||.. .. .. .. .. .. .. .. .. ..|| 99|| bbeellooww,, tthhee ''++'' 88||.. .. .. .. .. .. .. .. .. ..|| 88||++aappppeeaarrss ttoo oouurr lleefftt.. 77||.. .. .. .. .. .. .. .. .. ..|| 77|| 66||.. .. .. .. .. .. .. .. .. ..|| 66|| NNooddee ##117733:: NNaammee 55||.. .. .. .. .. .. .. .. .. ..|| 55||--BB:: vvaarriiaattiioonn 11 hhiitt ''BB'' ttoo sseeee 44||.. .. .. ++ .. .. .. .. .. ..|| 44|| CC:: vvaarriiaattiioonn 22 hhiitt ''CC'' 9 July 1993 8 MGT(6) MGT(6) 33||.. .. .. .. .. .. .. .. .. ..|| 33|| DD:: vvaarriiaattiioonn 33 eettcc...... 22||.. .. .. .. .. .. .. .. .. ..|| 22|| EE:: vvaarriiaattiioonn 44 11||.. .. .. .. .. .. .. .. .. ..|| 11||++FF:: vvaarriiaattiioonn 55 ++------------------------------ ------++ ?? ffoorr hheellpp rreeaadd lloonngg AA BB CC DD EE FF GG HH SS TT BBllaacckk ##1111 aatt ''DD1199'' ##:: 00 >> OO:: 00 << The bottom line indicates that Black has just made move #11. On the bottom right, the angle brackets around the white stone indicate that it is White's turn. Above that, the word "read" indicates that the Smart-Go file hasn't been modified, and "long" indicates that the default save format is the long format. "Read" will change to "edit" if you modify the file, and it will say "tutor" if you enter tutor mode. FFIILLEESS wrapmgt - prepare short format Smart-Go files for mailing mailgo - email go game management mgt2short - script to convert Smart-Go files to short for- mat RULES - an introduction to the game in Smart-Go format. The FFrroomm MMyy GGoo TTeeaacchheerr tutorial lessons, and many profes- sional game records all available at bsdserver.ucsf.edu Internet go, a program to play go over internet, available on bsdserver.ucsf.edu Smart-Go.def, the Smart-Go format definition. BBUUGGSS Comment editing is limited to 120 screen lines. Most, but not all, of the Smart-Go properties are sup- ported. Send bug reports to "adrian@bsdserver.ucsf.edu" or "hale@scam.Berkeley.EDU" AAUUTTHHOORRSS Greg Hale Jeff Boscole Adrian Mariano (adrian@bsdserver.ucsf.edu) Mike Dobbins (mdobbins@asns.tredydev.unisys.com) 9 July 1993 9 MGT(6) MGT(6) SSEEEE AALLSSOO rec.games.go - a newsgroup on the game Graded go problems for beginners, vol 1-4, Ishi Press In the Beginning, Ishi Press. The Treasure Chest Enigma, Ishi Press. 9 July 1993 10 mgt-2.31/wrapmgt.doc100644 1750 1750 2173 6177477722 12263 0ustar memmem WRAPMGT(6) WRAPMGT(6) NNAAMMEE wrapmgt - wraps long lines in Smart-Go files to make them safe to post or email SSYYNNOOPPSSIISS wwrraappmmggtt [[nnnn]] DDEESSCCRRIIPPTTIIOONN WWrraappmmggtt formats Smart-Go files as generated by mmggtt so that the lines are shorter than nn, the number specified on the command line. The default format width is 79 characters. WWrraappmmggtt reads its input from stdin and writes to stdout. This means you should invoke it using I/O redirection which is done under unix and DOS with wrapmgt < infile > outfile. The files are formatted in such a way that if the files are viewed in mgt after being formatted, they will look the same as the original. The new line breaks will be visible from within the editor, however. AAUUTTHHOORR Adrian Mariano (adrian@bsdserver.ucsf.edu) 23 November 1992 1 mgt-2.31/mailgo.doc100644 1750 1750 13625 6177477724 12100 0ustar memmem MAILGO(6) MAILGO(6) NNAAMMEE mailgo - shell script for using mgt to automate email go games SSYYNNOOPPSSIISS mmaaiillggoo [[--rr]] [[--nn]] [[--cc]] [[--ee]] [[ffiilleennaammee]] DDEESSCCRRIIPPTTIIOONN mmaaiillggoo helps manage email games by processing Smart-Go game records received by mail, invoking mgt, and automati- cally sending your next move back. Invoking mmaaiillggoo with no flags instructs the program to search the specified file for a go game, ignoring mail headers or other such garbage. mmaaiillggoo will invoke the game processor specified in the environment variable MAILGO or of this variable is undefined, will attempt to run mmggtt from the inherited path. If you give the filename -- then mmaaiillggoo will read its input from stdin, allowing you to redirect messages into mmaaiillggoo directly from your mailer. Your mail program may not support redirecting messages into external programs. Check it's man page to find out. This option to use stdin as the input is only valid if you give mmaaiillggoo no other arguments. (Technical note: mgt is instructed to read its input from /dev/tty if you use this feature.) If your opponent loses your move, you can resend the game with the -r switch. To start a new game, use the -n switch. Without a file, you will be prompted for your address, your opponent's address, and the filename for both your and your oppo- nent's local game record. The game processor will then be invoked for you to make the first move. If a filename is specified, the address and filename data is taken from that file. The -c switch causes the program to delete any extraneous files it might have created during a previous run which was abnormally terminated. These files have the form: MailGo* To edit the mailgo headers (including mail addresses, file names and game record format) or the game record, use the -e switch with the file name of the mailgo file you wish to edit. The file may be a saved mailgo mail message or a processed mailgo game file. The -e option will not mail changes because of the possibility of confusing addresses. To mail edited files, use 'mailgo ' for edited mail messages and 'mailgo -r ' for edited files which have been previously processed by mmaaiillggoo.. mmaaiillggoo also supports go board sizes of 9x9, 13x13 and 23 November 1992 1 MAILGO(6) MAILGO(6) 19x19. Handicaps maybe set to values of 2-4 for 9x9 games, 2-5 for 13x13 games and 2-9 for 19x19 games. Any other board size or handicap must be set behind mmaaiillggoo FFIILLEE FFOORRMMAATT ---GoGaMeStArT--- TO: opponent@hissite TOFILE: his_game_record FROM: me@mysite FROMFILE: my_game_record FORMAT: format_code ( Smart-Go game data ) ---GoGaMeEnD--- Trailing garbage ignored The game data file contains a leading tag to indicate the start of the data. It contains both addresses, as should be used to mail the game files, and it contains the files to store the games in. In the example above, you are playing opponent@hissite, and the game is being stored in my_game_record. The file format used can be either long, short, or extrashort indicated by L, S, and E respectively. The long format uses the full size Smart-Go file saved with no options from mgt. The extrashort format uses mgt with the -s option to save short format files. This format may cause problems for some mailers, however, because the lines will grow longer than 512 bytes. In any game record format, if very long comments are created, there is a dan- ger of causing mailer problems. The short format is simi- lar to the extrashort format but has extra newlines inserted. The short format is the default when selecting format from the prompt, but the long format is the default if a file contains no FORMAT line. When mmaaiillggoo is used normally, the file specified on the command line is removed at successful completion, and the new game is saved to the file specified in the received game record. If the destination file does not look like a mailgo file, mmaaiillggoo will query for confirmation. When a new game is started, the first mailgo message con- tains the line NEWGAME inserted before the FORMAT line. This is used to check for the overwriting of old game records. FFIILLEESS mgt Smart-Go.def, the Smart-Go format definition. 23 November 1992 2 MAILGO(6) MAILGO(6) BBUUGGSS mmaaiillggoo tries to handle the case where you start a new game but do not make the first move. If after the first move you have a reason to convince mgt that you have changed the game record without really changing anything, you should enter and exit the comment editor. AAUUTTHHOORR Adrian Mariano (adrian@bsdserver.ucsf.edu) 23 November 1992 3 mgt-2.31/mgt2short.doc100644 1750 1750 1317 6177477725 12535 0ustar memmem MGT2SHORT(6) MGT2SHORT(6) NNAAMMEE mgt2short - converts Smart-Go files to the short format. SSYYNNOOPPSSIISS mmggtt22sshhoorrtt ffiilleess DDEESSCCRRIIPPTTIIOONN MMggtt22sshhoorrtt converts Smart-Go files to the short format by invoking mmggtt on each file and instructing mgt to save the file in the short format. This means that any data in the files which mgt does not recognize will be lost. AAUUTTHHOORR Adrian Mariano (adrian@bsdserver.ucsf.edu) 26 February 1993 1