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

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

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



#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 3 (of 4)."
# Contents:  Makefile Sample.02 Smart-Go.def Spec.io build.c edit.c
#   mailgo play.c tree.c
# Wrapped by billr@saab on Tue Jun  4 12:33:09 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(3837 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X#
X#        "mgt" Copyright 1991 Shodan
X#		All Rights Reserved.
X#		Program by Greg Hale and Adrian Mariano
X#
X#Permission to use, copy, modify, and distribute this software and its
X#documentation for any purpose and without fee is hereby granted,
X#provided that this entire comment and copyright notice appear in all
X#copies and that both that copyright notice and this permission notice
X#appear in supporting documentation.  No representations are made about
X#the suitability of this software for any purpose.  It is provided "as
X#is" without express or implied warranty.
X#
X#Please send copies of extensions to:
X#
X#hale@scam.berkeley.edu
X#128.32.138.4    scam.berkeley.edu
X#
X#Donations for the 'From My Go Teacher' series may be sent to:
X#	Shodan
X#	P.O. Box 4456
X#	Berkeley, CA 94704
X#	(415) 849-9475
X#
X#
X# Makefile for mgt
X# by Greg Hale and Adrian Mariano
X#
X# *** C compile flags.
X#
X# -O: optimize
X# -DDEBUG: turn on program debugging
X#
X# *** CONFIGURATION ***
X#
X# Choose one of
X#   -DMGT_UNIX  Compile under UNIX
X#   -DMGT_IBM   Compile on IBM PC under Turbo C (Use the other Makefile!)
X#
X#   -DMGT_LIB="/usr/hale/mgt.lib/":   defines a library directory for games
X#
X
XDEFS=-DMGT_UNIX
X
X# If you read this Makefile, you may notice many references to an 
X# X Windows program.  This program is under development but has not yet
X# been released.  Send email inquiries to tcasey@triton.unm.edu.
X
X
X#CFLAGS= -g -O $(DEFS) -I/usr/include/X11 -I/usr/include/Xaw -I/usr/include/X11/Xaw
X
XCFLAGS = -O $(DEFS)
X
X# DIRECTORIES - CONFIGURE DESTINATIONS
X# BINDIR is where it is installed
XDEST		=		.
XBINDIR		=		.
XASC_PROGRAM	=		mgt
XX_PROGRAM	=		xmgt
XMAN             =		mgt.doc
XSHAR 		=		mgt.sh
X
X# files which make up the shell archive along with sources
X
XFILES = Smart-Go.def README Makefile format mgt.6 Spec.io Makefile.tc \
XBuild.com mailgo mailgo.6 mgtdoc.asc Sample.01 Sample.02 Rules
X
XSH_OBJS= help.o \
Xbuild.o comment.o doit.o edit.o mgt.o parse.o play.o tree.o
X
XSH_SRCS= help.c \
Xascii.c build.c comment.c doit.c edit.c mgt.c parse.c play.c tree.c
X
XX_OBJS=Board.o create.o X11.o
XASC_OBJS=ascii.o
X
XX_SRC=Board.c create.c X11.c
XASC_SRC=ascii.c asc_ibm.inc asc_unix.inc
X
XX_LIBS=-lXaw -lXmu -lXt -lX11
XASC_LIBS= -lcurses -ltermlib
X
XOBJECTS = help.o \
Xascii.o build.o comment.o doit.o edit.o mgt.o parse.o play.o tree.o
X
X
XSRCS = help.c asc_ibm.inc asc_unix.inc \
Xascii.c build.c comment.c doit.c edit.c mgt.c parse.c play.c tree.c
X
XHDRS = mgt.h proto.h
X
Xall: ascii
X		
X#P@echo "Usage:  make [X11 | ascii]"
X
XX11: $(X_PROGRAM) man 
X	#cludge
X	touch X11
X
Xascii.o: ascii.c asc_unix.inc
X
X
Xascii: $(ASC_PROGRAM) man
X
X
X$(X_PROGRAM): $(SH_OBJS) $(X_OBJS)
X	@echo -n "loading $(X_PROGRAM)..."
X	@cc $(SH_OBJS) $(X_OBJS) $(X_LIBS) -o $(DEST)/$(X_PROGRAM);
X	@echo "done."
X
X$(ASC_PROGRAM): $(SH_OBJS) $(ASC_OBJS)
X	@echo -n "loading $(ASC_PROGRAM)..."
X	@cc $(SH_OBJS) $(ASC_OBJS) $(ASC_LIBS) -o $(DEST)/$(ASC_PROGRAM);
X	@echo "done."
X
X$(MAN): mgt.6
X	@echo -n "Creating mgt manual..."
X	@nroff -man mgt.6 > $(MAN)
X	@echo "done."
X
Xmailgo.doc: mailgo.6
X	@echo -n "Creating mailgo manual..."
X	@nroff -man mailgo.6 > mailgo.doc
X	@echo "done."
X
Xman: $(MAN) mailgo.doc
X
Xclean:
X	@echo -n "removing extra files..."
X	@-rm -f *.o $(DEST)/$(X_PROGRAM) $(DEST)/$(ASC_PROGRAM) $(SHAR)
X	@echo "done."
X
Xproto:
X	@echo -n "making proto.h file..."
X	@-rm -f ./proto.h
X	@egrep "FUNCTION" $(SH_SRCS) | sed "s/(.*)/();/" | sed "s/^.*://" | sed "s/FUNCTION/extern/"  | cat > ./proto.h
X	@echo "done."
X
Xlint:
X	@echo -n "making lint file..."
X	@-rm -f ./lint.out
X	@lint -u $(DEFS) $(SRCS) > ./lint.out
X	@echo "done."
X
Xnew: proto clean all
X
Xmgtdoc.asc: $(MAN)
X	@echo -n "Making ascii doc file..."
X	@cat $(MAN) | col -b > mgtdoc.asc;
X	@echo "done."
X
X
Xshar: mgtdoc.asc
X	@shar $(SRCS) $(HDRS) $(FILES)  > mgt.shar
X
Xinstall: $(PROGRAM) $(ARCHIVE)
X	@-install $(DEST)/$(PROGRAM) $(BINDIR)/$(PROGRAM)
X
X
X
X
END_OF_FILE
if test 3837 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'Sample.02' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Sample.02'\"
else
echo shar: Extracting \"'Sample.02'\" \(3791 characters\)
sed "s/^X//" >'Sample.02' <<'END_OF_FILE'
X(
X;
XGaMe[1]
XSiZe[19]
XVieW[]
XComment[16th Honinbo League Playoff
X    
XWhite: Sakata Eio 9-dan    
X    
XBlack: Kitani Minoru 9-dan
X    
XKomi: 4 1/2    
X
XResult: White wins by 3 1/2 points]
XBlack[qd]
X;
XWhite[dc]
X;
XBlack[pq]
X;
XWhite[cq]
X;
XBlack[oc]
X;
XWhite[po]
X;
XBlack[qo]
X;
XWhite[qn]
X;
XBlack[qp]
X;
XWhite[pm]
X;
XBlack[nq]
X;
XWhite[qi]
X;
XBlack[ce]
X;
XWhite[dh]
X;
XBlack[ee]
X;
XWhite[cb]
X;
XBlack[cc]
X;
XWhite[gc]
X;
XBlack[bc]
X;
XWhite[bb]
X;
XBlack[qg]
X;
XWhite[dd]
X;
XBlack[de]
X;
XWhite[cg]
X;
XBlack[co]
X;
XWhite[cm]
X;
XBlack[ep]
X;
XWhite[do]
X;
XBlack[dp]
X;
XWhite[cp]
X;
XBlack[dn]
X;
XWhite[bo]
X;
XBlack[eo]
X;
XWhite[cn]
X;
XBlack[el]
X;
XWhite[dk]
X;
XBlack[ql]
X;
XWhite[rm]
X;
XBlack[rj]
X;
XWhite[qe]
XComment[Complications start. Creating two weak groups. ]
X;
XBlack[qj]
X;
XWhite[rd]
X;
XBlack[qc]
X;
XWhite[qf]
X;
XBlack[pg]
X;
XWhite[rc]
X;
XBlack[rb]
X;
XWhite[oe]
X;
XBlack[mc]
X;
XWhite[op]
X;
XBlack[on]
X;
XWhite[pn]
X;
XBlack[oq]
X;
XWhite[mo]
X;
XBlack[mp]
XComment[Severe attack. ]
X;
XWhite[lo]
XComment[Counters aggressively. ]
X;
XBlack[no]
X;
XWhite[np]
X;
XBlack[nm]
XComment[Black cuts. Brings on crisis.]
X;
XWhite[pj]
X;
XBlack[pi]
X;
XWhite[pk]
X;
XBlack[rl]
X;
XWhite[ml]
X;
XBlack[nl]
X;
XWhite[nk]
X;
XBlack[mk]
X;
XWhite[om]
XComment[Exquisite shinogi tesuji. Lets W secure his endangered group]
X;
XBlack[nj]
X;
XWhite[ok]
X;
XBlack[ll]
X;
XWhite[lp]
X;
XBlack[mq]
X;
XWhite[mn]
X;
XBlack[mm]
X;
XWhite[nn]
X;
XBlack[rf]
XComment[Turns toward other weak group. ]
X;
XWhite[re]
X;
XBlack[rg]
X;
XWhite[nd]
X;
XBlack[nc]
X;
XWhite[nf]
X;
XBlack[nh]
X;
XWhite[lf]
X;
XBlack[le]
X;
XWhite[mh]
X;
XBlack[mi]
X;
XWhite[me]
X;
XBlack[mg]
X;
XWhite[ld]
X;
XBlack[ke]
X;
XWhite[md]
X;
XBlack[kb]
X;
XWhite[kc]
X;
XBlack[jb]
X;
XWhite[id]
X;
XBlack[kf]
X;
XWhite[oi]
X;
XBlack[ph]
X;
XWhite[jc]
XComment[Manages to rescue weak group. ]
X;
XBlack[ib]
X;
XWhite[fd]
X;
XBlack[eg]
X;
XWhite[lg]
XComment[Double attack.]
X;
XBlack[lh]
X;
XWhite[kg]
X;
XBlack[if]
X;
XWhite[hg]
X;
XBlack[hf]
X;
XWhite[gf]
X;
XBlack[ge]
X;
XWhite[fe]
X;
XBlack[jg]
X;
XWhite[he]
XComment[First time that B is the one under pressure.]
X;
XBlack[gg]
X;
XWhite[ff]
X;
XBlack[dg]
X;
XWhite[ef]
X;
XBlack[df]
X;
XWhite[fg]
X;
XBlack[ch]
X;
XWhite[bh]
X;
XBlack[ci]
X;
XWhite[bf]
X;
XBlack[ei]
X;
XWhite[cj]
X;
XBlack[gh]
X;
XWhite[fh]
X;
XBlack[eh]
X;
XWhite[dj]
X;
XBlack[di]
X;
XWhite[bi]
X;
XBlack[fi]
X;
XWhite[gi]
X;
XBlack[gj]
X;
XWhite[hh]
X;
XBlack[ii]
X;
XWhite[mf]
X;
XBlack[jh]
XComment[Fight ends. ]
X;
XWhite[er]
XComment[W has taken the lead.]
X;
XBlack[fk]
X;
XWhite[ro]
X;
XBlack[rp]
X;
XWhite[fq]
X;
XBlack[in]
X;
XWhite[go]
X;
XBlack[gn]
X;
XWhite[jn]
X;
XBlack[jm]
X;
XWhite[fn]
X;
XBlack[hn]
X;
XWhite[fo]
X;
XBlack[en]
X;
XWhite[fm]
X;
XBlack[dl]
X;
XWhite[cl]
X;
XBlack[hl]
X;
XWhite[km]
X;
XBlack[jl]
X;
XWhite[lq]
X;
XBlack[ip]
X;
XWhite[lr]
X;
XBlack[hq]
X;
XWhite[os]
X;
XBlack[or]
X;
XWhite[gq]
X;
XBlack[dq]
X;
XWhite[dr]
X;
XBlack[be]
X;
XWhite[hb]
X;
XBlack[ic]
X;
XWhite[sb]
X;
XBlack[ra]
X;
XWhite[ie]
X;
XBlack[hc]
X;
XWhite[gb]
X;
XBlack[gr]
X;
XWhite[hi]
X;
XBlack[hj]
X;
XWhite[ns]
X;
XBlack[ps]
X;
XWhite[mr]
X;
XBlack[pp]
X;
XWhite[oo]
X;
XBlack[rr]
X;
XWhite[ej]
X;
XBlack[fj]
X;
XWhite[ir]
X;
XBlack[hr]
X;
XWhite[jr]
X;
XBlack[jo]
X;
XWhite[kn]
X;
XBlack[ab]
X;
XWhite[qk]
X;
XBlack[rk]
X;
XWhite[oj]
X;
XBlack[ia]
X;
XWhite[jp]
X;
XBlack[fr]
X;
XWhite[iq]
X;
XBlack[hp]
X;
XWhite[eq]
X;
XBlack[af]
X;
XWhite[kl]
X;
XBlack[kk]
X;
XWhite[ko]
X;
XBlack[ag]
X;
XWhite[kh]
X;
XBlack[ki]
X;
XWhite[bg]
X;
XBlack[gm]
X;
XWhite[ng]
X;
XBlack[mh]
X;
XWhite[sl]
X;
XBlack[so]
X;
XWhite[rn]
X;
XBlack[hd]
X;
XWhite[gd]
X;
XBlack[lm]
X;
XWhite[ri]
X;
XBlack[si]
X;
XWhite[sf]
X;
XBlack[sg]
X;
XWhite[io]
X;
XBlack[ho]
X;
XWhite[cd]
X;
XBlack[bd]
X;
XWhite[pd]
X;
XBlack[pc]
X;
XWhite[se]
X;
XBlack[nr]
X;
XWhite[ms]
X;
XBlack[ha]
X;
XWhite[ga]
X;
XBlack[lc]
X;
XWhite[kd]
X;
XBlack[ed]
X;
XWhite[ec]
X;
XBlack[fl]
X;
XWhite[ah]
X;
XBlack[ae]
X;
XWhite[je]
X;
XBlack[jf]
X;
XWhite[ni]
X;
XBlack[mj]
X;
XWhite[ih]
X;
XBlack[sc]
X;
XWhite[sd]
X;
XBlack[od]
X;
XWhite[pf]
X;
XBlack[db]
X;
XWhite[eb]
X;
XBlack[ba]
X;
XWhite[da]
X;
XBlack[do]
X;
XWhite[hs]
X;
XBlack[og]
X;
XWhite[of]
X;
XBlack[es]
X;
XWhite[ds]
X;
XBlack[fs]
X;
XWhite[jo]
X;
XBlack[ac]
X;
XWhite[pe]
X)
END_OF_FILE
if test 3791 -ne `wc -c <'Sample.02'`; then
    echo shar: \"'Sample.02'\" unpacked with wrong size!
fi
# end of 'Sample.02'
fi
if test -f 'Smart-Go.def' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Smart-Go.def'\"
else
echo shar: Extracting \"'Smart-Go.def'\" \(10342 characters\)
sed "s/^X//" >'Smart-Go.def' <<'END_OF_FILE'
X                   DEFINITION OF THE SMART-GO FORMAT
X
X>From the Dissertation of Anders Kierulf
X
X"Smart Game Board:
Xa Workbench for Game-Playing
XPrograms, with Go and Othello
Xas Case Studies"
X
XEntered by Greg Hale with permission for distribution. See the many sample 
Xfiles from the 'My Go Teacher' series for examples. 
X    
X------------
X
XA standard file format to exchange machine-readable games, problems,
Xand opening libraries would save time and work.  That goal may not be
Xtoo far away.  A standard for exchanging collections of Othello games
Xis being worked out by Erik Jensen, Emmanuel Lazard, and Brian Rose in
Xcollaboration with the author.  For Go, a new standard has recently
Xbeen proposed [Connelley 89, High 89]; it seems to suffer from a wealth
Xof features, but any standard for exchanging Go games is welcome, and
Xwill be supported by the Smart Game Board.
X
XThe current file format is specialized for the needs of the Smart Game
XBoard.  It is based on an earlier proposal for a standard for Go games
X[Kierulf 87b] which was not widely adopted.  The following description
Xis not a new proposal; it is intended for those who want to read or
Xwhite files that are compatible with the Smart Game Board.
X
XThe game collections (documents) of the Smart Game Board are stored as
Xtext files.  This has the advantage that files can be manipulated with
Xstandard text utilities, and that it's easier to exchange games by
Xelectronic mail.  The disadvantage is that text files are less compact
Xthan binary files.
X
XThe Smart Game Board stores the game trees of each document, with all
Xtheir nodes and properties, and nothing more.  Thus the file format
Xreflects the regular internal structure of a tree of property lists.
XThere are no exceptions; if a game needs to store some information on
Xfile with the document, a (game-specific) property must be defined for
Xthat purpose.
X
XI will first define the syntax of the game collections, then discuss
Xsyntax and semantic of various properties.
X
X
XGAME COLLECTIONS
X
XA collection of game sis simply the concatenation of the game trees.
XThe structure of each tree is indicated by parentheses.  A tree is
Xwritten as "(" followed by a sequence of nodes (as long as the tree is
Xunbranched) and a tree for each son, and terminated by ")".  Each node
Xis preceded by a separator, and contains a list of zero or more
Xproperties.
X
XThus the main branch of the game is stored first in the file, and
Xprograms can easily read that part (until the first closing
Xparenthesis) and ignore the rest.
X
XThe conventions of EBNF are discussed in [Wirth 85].  A quick summary:
X
X"..." : terminal symbols
X[...] : option: occurs at most once
X{...} : repetition: any number of times, including zero
X(...) : grouping
X  |   : exclusive-or
X
XThe overall definition of the file format is as follows:
X
X        Collection      = {GameTree}.
X        GameTree        = "(" Sequence {GameTree} ")".
X        Sequence        = Node {Node}.
X        Node            = ";" {Property}
X
XAny text before the first opening parenthesis is reserved for future
Xextensions and is ignored when reading a file.  Spaces, tabs, line
Xbreaks and so on can be inserted anywhere between properties and are
Xalso ignored.
X
X
XGAME-INDEPENDENT PROPERTIES
X
XEach property is identified by one or two capital letters.  The
Xproperty value is enclosed in brackets; lists of points or integers are
Xwritten as a sequence of property values.  Within text, a closing
Xbracket is prefixed by a backslash, and a backslash is doubled.  Moves
Xand points are game-specific and are defined later.
X
X        Property        = PropIdent PropValue {PropValue}.
X        PropIdent       = UpperCase [UpperCase | Digit].
X        PropValue       = "[" [Number | Text | Real | Triple
X                                  | Color | Move | Point | ... ] "]"
X        Number          = ["+" | "-"] Digit {Digit}.
X        Text            = { any character; "\]" = "]", "\\" = "\"}.
X        Real            = { Number ["." {Digit}].
X        Triple          = ("1" | "2").
X        Color           = ("B" | "W").
X
XMove and Point are game-specific and are described later.  The
Xfollowing properties are understood by all games.  The property type is
Xgiven in brackets.
X
X        "B" : Black move                [move, game-specific]
X        "W" : White move                [move, game-specific]
X        "C" : Comment                   [Text]
X        "N" : Node Name                 [Text]
X
XThe purpose of providing both a node name and a comment is to have a
Xshort identifier like "doesn't work" or "Dia. 15" that can be displayed
Xdirectly with the properties of the node, even if the comment is turned
Xoff or shown in a separate window.  There is no limit to the length of
Xtexts; programs must be able to ignore the rest of texts that are too
Xlong for them to handle.  Reasonable limits are 32 characters for node
Xnames and at least 2000 characters for comments.
X
X        "V" : Node value                [number]
X
XPositive values are good for Black, negative values are good for
XWhite.  The interpretation of particular values is game-specific.
X
X        "CH": Check mark                [triple]
X        "GB": good for black            [triple]
X        "GW": good for white            [triple]
X        "TE": good move (tesuji)        [triple]
X        "BM": bad move                  [triple]
X
XThe normal value for such properties is one, properties that are
Xdoubled for emphasis have the value two.
X
X        "BL": time left for Black       [real]
X        "WL": time left for White       [real]
X
XAll times are given in seconds, or fractions thereof {Hale: these can
Xbe negative, indicating player is playing past time limit set}.
X
X        "FG": figure                    [none]
X
XThe figure property is used to divide a game into different figures for
Xprinting: a new figure starts at the node with a figure property.
X
X        "AB": add black stones          [point list, game specific]
X        "AW": add white stones          [point list, game specific]
X        "AE": add empty stones          [point list, game specific]
X        "PL": player to play first      [color]
X
XThe above properties are used to set up positions in games with only
Xblack and white stones.  The following properties are all part of the
Xgame info:
X
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
XThe format in these game-info strings is free, but to be able to search
Xfor specific games in game collections, it is recommended to adhere to
Xthe following conventions:
X
X        - Date is ISO-standard: "YYYY-MM-DD".
X        - Result as "0" (zero) for a draw, "B+score" for a black win,
X                and "W+score" for a white win, e.g. "B+2.5", "W+64"
X        - Time limit as a number, in minutes.
X
XIn addition, names, events, and places should be spelled the same im all games.
X
XThe following properties may only be present at the root node:
X
X        "GM": game [number] (Go=1, Othello=2, chess=3, Nine Mens Morris=5)
X        "SZ": board size        [number]
X        "VW": partial view      [point list, game-specific]
X        "BS": black species     [number] (human=0, modem=-1, computer>0)
X        "WS": white species     [number]
X
XThe game number helps the program reject games it cannot handle (this
Xproperty was mandatory as long sa an application could play different
Xgames).  The view gives two corner points of a rectangular subsection;
Xan empty list denotes the whole board.  The species denotes the kind of
Xplayer (the source of the more input), with different version of
Xcomputer algorithms denoted by positive numbers (default algorithm =
X1).
X
XComputer algorithms may add the following properties:
X
X        "EL": evaluation of computer move       [number]
X        "EX": expected next move                [move, game-specific]
X
XSome games support markings on the board: selected points,
Xtriangles/crosses, or letters (a sequence of letters is shown on the
Xpoints given in the list, starting with "A"):
X
X        "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
X
XGO-SPECIFIC PROPERTIES
X
XIn my proposal for a standard [Kierul 87b], I intentionally broke with
Xthe tradition of labeling moves (and points) with letters "A"-"T"
X(excluding "i") and numbers 1-19.  Two lowercase letters in the range
X"a"-"s" were used instead, for reasons of simplicity and compactness.
XThis was criticized mainly because it was not human-readable, but as
Xthat is not an important feature of this file format, I continue to use
Xthat notation.
X
X(Hale: diagram omitted)
X
XThe first letter designated the column (left to right), the second the
Xrow (top to bottom).  The upper left part of the board is used for
Xsmaller boards, e.g. letters "a"-"m" for 13*13.  (Column before row
Xfollows the principle "horizontal before vertical" used in x-y
Xcoordinate systems.  The upper left corner as origin of the board
Xcorresponds to the way we read, and most modern computers use it as
Xorigin of the screen coordinates to simplify integration of text and
Xgraphics.)  A pass move is written as "tt".
X
XThe board must be quadratic, no smaller than 2x2, and no larger than
X19x19.
X
XAdditional game info properties are defined for Go:
X
X        "BR": Black's rank              [text]
X        "WR": White's rank              [text]
X        "HA": handicap                  [number]
X        "KM": komi                      [real]
X
XSets of board points can be marked as territory, as secure stones, or
Xjust as a region of the board (e.g. to designate eye space):
X
X        "TB": Black's territory         [point list]
X        "TW": White's territory         [point list]
X        "SC": secure stones             [point list]
X        "RG": region of the board       [point list]
X
END_OF_FILE
if test 10342 -ne `wc -c <'Smart-Go.def'`; then
    echo shar: \"'Smart-Go.def'\" unpacked with wrong size!
fi
# end of 'Smart-Go.def'
fi
if test -f 'Spec.io' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Spec.io'\"
else
echo shar: Extracting \"'Spec.io'\" \(3807 characters\)
sed "s/^X//" >'Spec.io' <<'END_OF_FILE'
X                        INTERFACE SPECIFICATION FOR MGT
X
XIf you wish to add a new interface to mgt, these are the functions you need to 
Xcome up with.
X
Xvoid open()
X        Initialize interface.  Any *interface* specific initialization is done
X        here.
X
Xvoid close()
X        Leave the interface.
X
Xvoid refreshIO()
X        update screen to look like memory image.  Somewhat curses specific.
X        Probably will be a null function null(){} in most interfaces.
X
Xvoid plotPiece(pBoard b, int i, int j)
X        Plots the piece contained in b at i,j on the real screen.
X        Board is read by call boardGet(b, i, j) which returns
X        one of P_NOTHING, P_BLACK, P_WHITE, P_DAME, P_BLACKTERR,
X        or P_WHITETERR. 
X
Xvoid displayComment(char *s)
X        Formats and displays string s as a comment, including variables local
X        to the interface to handle scrolling and partial views of the text.
X        The comment string can contain newlines.  
X
Xvoid clearComment()
X        Clears comment window
X
Xvoid clearBoard(pBoard b)
X        Clears the specified board and displays the new cleared 
X        board.  setPiece(b, i, j, P_NOTHING) is called on all
X        board positions (see 'boardsize') to clear the board.
X
Xvoid clearScreen()
X        clears screen. 
X
Xint idle(nodep n) 
X        Gets the next command.  Acts like an event driven loop.
X        Waits for keystroke.  Returns a command casted to an int
X        to indicate the command for doit.c to process.
X
Xvoid drawTree(nodep n)
X        Show the variations that are available in the var list on 
X        the right when starting at node n. (in Ascii version)
X        Interface-local variables exists to handle scrolling.
X        scrolling should be handled by the interface alone.
X
Xvoid highlightLast(int x, y, movenum, turn)
X        Show last move number, current turn, whose move it is,
X        and the prisoner count.
X        turn==0 means Black just moved.
X        Use these to get current player turn and prisoner count
X        extern int prisoners[black=0,white=1] ;
X        extern int curPlayer;
X
Xvoid readEnv(char **env)
X        Check *env for environment string.  Increment it to point to 
X        the first character not used.
X
Xvoid notifyMessage(char *s)
X        Print single line message someplace.
X
Xvoid notifyClear()
X        Clear notify message area
X
Xint queryStr(char *query, char *dst, int maxLen)
X        Print query out.  Get at most maxLen chars into dst.
X        Return length of the result.
X
Xvoid setCursor(int i, int j)
X        Move cursor (pointer) to position i,j on go board
X
Xvoid plotMark(pBoard b,int i,int j) 
X        Plot mark at position i,j on displayed board.
X        DOES NOT modify *b.
X        Mark is erased by call to plotPiece
X
Xvoid plotLetter(int i, int j, char c)
X        Puts letter c on the screen at board position i,j
X
Xint getPoint()    
X        Allow user to specify a board position (Cursor
X        keys, mouse, etc) Used when scoring the game.
X        Uses globals xcur and ycur to
X        store the position.  The return value 
X        can be C_QUIT to abort score.  C_SCORE to calculate
X        the score.  C_REDRAW to redraw screen, or C_NOTHING
X        to kill the group we're on right now.
X
Xvoid editComment(char *inp, char **out)
X        Edit a comment.  inp contains the input comment to be
X        edited.  THIS MUST BE free()'d.  out contains the return
X        pointer.  It should be allocated to the appropriate size
X        and the new edited comment should be placed in the
X        allocated space.
X
Xint askYN(char *query, int defalt)
X        Prompt user with query.  The query will NOT end in " (y/n)? " 
X        If needed by the interface, this should be added here. 
X        Returns 1 for yes, 0 for no.  defalt contains the default 
X        response (1 for yes, 0 for no).
X
X
X
X
END_OF_FILE
if test 3807 -ne `wc -c <'Spec.io'`; then
    echo shar: \"'Spec.io'\" unpacked with wrong size!
fi
# end of 'Spec.io'
fi
if test -f 'build.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'build.c'\"
else
echo shar: Extracting \"'build.c'\" \(3635 characters\)
sed "s/^X//" >'build.c' <<'END_OF_FILE'
X/* "mgt" Copyright (c) 1991 Shodan  */
X
X#include "mgt.h"
X
Xint lastMoveX, lastMoveY, moveNum, lastTurn;
Xcoord *lastletters = 0, *lastmarks;
Xcoord *marks = 0;
Xcoord *letters = 0;
X
X
XFUNCTION void clearLast()
X{
X   lastMoveX = lastMoveY = -1;
X   moveNum = 0;
X}
X
XFUNCTION void highlightLast()
X{
X   extern Token curPlayer;
X   if (lastMoveX >= 0 && moveNum > 0 && lastTurn != (int) t_EOF)
X      curPlayer = lastTurn ? t_Black : t_White;
X   (*io->highlightLast) (lastMoveX, lastMoveY, moveNum, lastTurn);
X
X}
X
XFUNCTION void doPlace(p, b, t)
X    property *p;
X    pBoard b;
X    piece t;
X{
X   int i, j;
X   for (i = boardsize; i--;)
X      for (j = boardsize; j--;)
X	 if (getCoord(i, j, (coordList *) p->d)) {
X	    placeStone(b, i, j, t);
X	 }
X   if (p->t == t_Black || p->t == t_White)
X      moveNum++;
X}
X
XFUNCTION void doProps(p, b)
X    property *p;
X    pBoard b;
X{
X   letters = NULL;
X   marks = NULL;
X   while (p) {
X      switch (p->t) {
X      case t_White:
X	 BUG("t_White ");
X	 doPlace(p, b, P_WHITE);
X	 break;
X      case t_Black:
X	 BUG("t_Black ");
X	 doPlace(p, b, P_BLACK);
X	 break;
X      case t_AddWhite:
X	 BUG("t_AddWhite ");
X	 doPlace(p, b, P_WHITE);
X	 break;
X      case t_AddBlack:
X	 BUG("t_AddBlack ");
X	 doPlace(p, b, P_BLACK);
X	 break;
X      case t_AddEmpty:
X	 BUG("t_AddEmpty ");
X	 doPlace(p, b, P_NOTHING);
X	 break;
X      case t_Comment:
X	 break;
X      case t_Mark:
X	 marks = (coord *) p->d;
X	 break;
X      case t_Letter:
X	 letters = (coord *) p->d;
X	 BUG("t_Letter ");
X	 break;
X      default:
X	 BUG("default ");
X      }
X      p = p->next;
X   }
X}
X
Xstatic void setLastMovePos(p)
X    property *p;
X{
X   int i, j;
X   lastTurn = p->t == t_White ? 1 : 0;
X   for (i = boardsize; i--;)
X      for (j = boardsize; j--;)
X	 if (getCoord(i, j, (coordList *) p->d)) {
X	    lastMoveX = i;
X	    lastMoveY = j;
X	 }
X}
X
XFUNCTION void doPropComment(n)
X    nodep n;
X{
X   property *p;
X
X   if (p = getprop(n, t_Comment))
X      (*io->displayComment) ((char *) p->d);
X
X   if (p = getprop(n, t_Black))
X      setLastMovePos(p);
X   else if (p = getprop(n, t_White))
X      setLastMovePos(p);
X}
X
XFUNCTION void buildTree0(n, b)
X    nodep n;
X    pBoard b;
X{
X   BUG("parent >");
X   if (n) {
X      buildTree0(n->parent, b);
X      BUG("\nprops:");
X      doProps(n->p, b);
X   }
X}
X
X
X
XFUNCTION void buildTree(n, b)
X    nodep n;
X    pBoard b;
X{
X   extern int prisoners[];
X   prisoners[0] = 0;
X   prisoners[1] = 0;
X   boardClear(b);
X   (*io->clearComment) ();
X   BUG("buildTree:\n");
X   clearLast();
X   buildTree0(n, b);
X   doPropComment(n);
X}
X
X
XFUNCTION void setPiece(b, i, j, p)
X    pBoard b;
X    int i, j;
X    piece p;
X{
X   boardSet(b, i, j, p);
X   (*io->plotPiece) (b, i, j);
X}
X
XFUNCTION void updateBoard(dst, new)
X    pBoard dst, new;		/* update dst to look like new */
X{
X   extern int prisoners[];
X   int i, j;
X
X   if (lastmarks) {
X      for (i = 0; i < MAX_LETTERS && (lastmarks[i].x != -1); i++)
X	 (*io->plotPiece) (new, lastmarks[i].x, lastmarks[i].y);
X   }
X   if (lastletters) {
X      for (i = 0; i < MAX_LETTERS && (lastletters[i].x != -1); i++)
X	 (*io->plotPiece) (new, lastletters[i].x, lastletters[i].y);
X   }
X   lastmarks = marks;
X   lastletters = letters;
X   for (i = boardsize; i--;)
X      for (j = boardsize; j--;) {
X	 if (boardGet(new, i, j) != boardGet(dst, i, j)) {
X	    setPiece(dst, i, j, boardGet(new, i, j));
X	 }
X      }
X   if (marks) {
X      for (i = 0; i < MAX_LETTERS && (marks[i].x != -1); i++)
X	 (*io->plotMark) (new, lastmarks[i].x, lastmarks[i].y);
X      marks = NULL;
X   }
X   if (letters) {
X      for (i = 0; i < MAX_LETTERS && (letters[i].x != -1); i++)
X	 (*io->plotLetter) (letters[i].x, letters[i].y, i + 'a');
X      letters = NULL;
X   }
X}
END_OF_FILE
if test 3635 -ne `wc -c <'build.c'`; then
    echo shar: \"'build.c'\" unpacked with wrong size!
fi
# end of 'build.c'
fi
if test -f 'edit.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'edit.c'\"
else
echo shar: Extracting \"'edit.c'\" \(9788 characters\)
sed "s/^X//" >'edit.c' <<'END_OF_FILE'
X/* "mgt" Copyright (c) 1991 Shodan  */
X
X#include "mgt.h"
X
Xint first;
Xnodep buffer = 0;
X
X
XFUNCTION void writeStrEscaped(output, s)
X    FILE *output;
X    char *s;
X{
X   while (*s) {
X      if (*s == ')' || *s == '(' || *s == ']' || *s == '[')
X	 fputc('\\', output);
X      fputc(*(s++), output);
X   }
X}
X
X
X#define WRITE(short,long) if (saveShort) fputs(short,output);else fputs(long,output)
X
X
XFUNCTION void writeNode(output, n)
X    FILE *output;
X    nodep n;
X{
X   property *prop;
X   char str[1445];
X
X   WRITE(";", ";\n");
X   if (first) {
X      if (saveShort)
X	 fprintf(output, "GM[1]VW[]SZ[%d]", boardsize);
X      else
X	 fprintf(output, "GaMe[1]\nVieW[]\nSiZe[%d]\n", boardsize);
X      first = 0;
X   }
X   prop = n->p;
X   while (prop) {
X      switch (prop->t) {
X      case t_AddBlack:
X	 if (writeCoordList((coordList *) prop->d, str)) {
X	    WRITE("AB", "AddBlack");
X	    fputs(str, output);
X	 }
X	 break;
X      case t_AddWhite:
X	 if (writeCoordList((coordList *) prop->d, str)) {
X	    WRITE("AW", "AddWhite");
X	    fputs(str, output);
X	 }
X	 break;
X      case t_White:
X	 if (writeCoordList((coordList *) prop->d, str)) {
X	    WRITE("W", "White");
X	    fputs(str, output);
X	 }
X	 break;
X      case t_Black:
X	 if (writeCoordList((coordList *) prop->d, str)) {
X	    WRITE("B", "Black");
X	    fputs(str, output);
X	 }
X	 break;
X      case t_AddEmpty:
X	 if (writeCoordList((coordList *) prop->d, str)) {
X	    WRITE("AE", "AddEmpty");
X	    fputs(str, output);
X	 }
X	 break;
X      case t_Mark:
X	 if (writeCoordArray((coord *) prop->d, str)) {
X	    WRITE("M", "Mark");
X	    fputs(str, output);
X	 }
X	 break;
X      case t_Letter:
X	 if (writeCoordArray((coord *) prop->d, str)) {
X	    WRITE("L", "Letter");
X	    fputs(str, output);
X	 }
X	 break;
X      case t_Name:
X	 if (strlen((char *) prop->d)) {
X	    WRITE("N[", "Name[");
X	    writeStrEscaped(output, (char *) prop->d);
X	    WRITE("]", "]\n");
X	 }
X	 break;
X      case t_Comment:
X	 if (strlen((char *) prop->d)) {
X	    WRITE("C[", "Comment[");
X	    writeStrEscaped(output, (char *) prop->d);
X	    WRITE("]", "]\n");
X	 }
X	 break;
X      }
X      prop = prop->next;
X   }
X}
X
X
X
XFUNCTION void WriteSubTree(output, root, sib)
X    FILE *output;
X    nodep root;
X    int sib;
X{
X   WRITE("(", "(\n");
X   do {
X      if (sib && root->nextSibling) {
X	 WriteSubTree(output, root, 0);
X	 while (root->nextSibling) {
X	    root = root->nextSibling;
X	    WriteSubTree(output, root, 0);
X	 }
X	 root = NULL;
X      } else {
X	 writeNode(output, root);
X	 root = root->child;
X	 sib = 1;
X      }
X   }
X   while (root);
X   WRITE(")", ")\n");
X}
X
X
X
XFUNCTION int writeCoordList(list, str)
X    coordList *list;
X    char *str;
X{
X   int x, y;
X   *str = 0;
X   for (x = 0; x < boardsize; x++)
X      for (y = 0; y < boardsize; y++)
X	 if (getCoord(x, y, list))
X	    sprintf(str + strlen(str), "[%c%c]", x + 'a', y + 'a');
X   if (!(strlen(str)))
X      return 0;
X   if (!saveShort)
X      strcat(str, "\n");
X   return 1;
X}
X
X
XFUNCTION int writeCoordArray(co, str)
X    coord *co;
X    char *str;
X{
X   int i = 0;
X   *str = 0;
X   while (co->x != -1 && i < MAX_LETTERS) {
X      sprintf(str + strlen(str), "[%c%c]", co->x + 'a', co->y + 'a');
X      co++, i++;
X   }
X   if (!(strlen(str)))
X      return 0;
X   if (!saveShort)
X      strcat(str, "\n");
X   return 1;
X}
X
X
XFUNCTION int writeTree(name, root)
X    char *name;
X    nodep root;
X{
X   FILE *output;
X
X   if (output = fopen(name, "w")) {
X      first = 1;
X      WriteSubTree(output, root, 1);
X      fclose(output);
X      return 0;
X   } else {
X      char buf[2];
X      (*io->queryStr) ("Error saving file.  Hit return.", buf, 1);
X      return 1;
X   }
X}
X
X
XFUNCTION void clearArray(x, y, co)
X    int x, y;
X    coord *co;
X{
X   int i;
X   for (i = 0; (co->x != -1) && (i < MAX_LETTERS); co++, i++) {
X      if ((co->x == x) && (co->y == y)) {
X	 while ((co->x != -1) && (i < MAX_LETTERS - 1)) {
X	    co->x = (co + 1)->x;
X	    co->y = (co + 1)->y;
X	    co++;
X	    i++;
X	 }
X	 if (i == MAX_LETTERS - 1)
X	    co->x -= 1;
X      }
X   }
X}
X
X
X
Xstatic void clearSpace(prop, x, y)
X    property *prop;
X    int x, y;
X{
X   while (prop) {
X      switch (prop->t) {
X      case t_AddEmpty:
X      case t_AddBlack:
X      case t_AddWhite:
X      case t_Black:
X      case t_White:
X	 clearCoord(x, y, (coordList *) prop->d);
X	 break;
X      case t_Mark:
X      case t_Letter:
X	 clearArray(x, y, (coord *) prop->d);
X	 break;
X      }
X      prop = prop->next;
X   }
X}
X
X
XFUNCTION int addMark(n, t, x, y)
X    nodep n;
X    Token t;
X    int x, y;
X{
X   property *prop;
X   coord *co;
X   int i;
X   if (prop = getprop(n, t)) {
X      co = (coord *) prop->d;
X      for (i = 0; (i < MAX_LETTERS) && (co[i].x != -1); i++)
X	 if ((co[i].x == x) && (co[i].y == y)) {
X	    clearArray(x, y, co);
X	    if (co->x == -1) {
X	       property *point;
X	       point = n->p;
X	       if (point == prop)
X		  n->p = prop->next;
X	       else {
X		  do {
X		     if (point->next == prop) {
X			point->next = prop->next;
X			break;
X		     }
X		     if (point->next)
X			point = point->next;
X		     else
X			break;
X		  } while (1);
X	       }
X	       free(co);
X	       free(prop);
X	    }
X	    return 2;
X	    /* i = MAX_LETTERS + 1; */
X	 }
X      if (i == MAX_LETTERS)
X	 return 0;
X   }
X   if (t == t_Mark) {
X      if (prop = getprop(n, t_Letter))
X	 clearArray(x, y, (coord *) prop->d);
X   } else
X      clearSpace(n->p, x, y);
X   if (!(prop = getprop(n, t))) {
X      prop = (property *) calloc(1, sizeof(property));
X      co = (coord *) calloc(MAX_LETTERS, sizeof(coord));
X      if (!(prop && co))
X	 barf("Memory allocation failure (markStone)");
X      prop->next = n->p;
X      n->p = prop;
X      prop->d = (data *) co;
X      prop->t = t;
X      co->x -= 1;
X   } else
X      co = (coord *) prop->d;
X   for (i = 0; (i < MAX_LETTERS) && (co[i].x != -1); i++);
X   co[i].x = x;
X   co[i].y = y;
X   if (i + 1 != MAX_LETTERS)
X      co[i + 1].x = -1;
X   return 1;
X}
X
X
X
XFUNCTION void addStone(n, t, x, y)
X    nodep n;
X    Token t;
X    int x, y;
X{
X   property *prop;
X   coordListP cl;
X
X   clearSpace(n->p, x, y);
X   if (!(prop = getprop(n, t))) {
X      prop = (property *) calloc(1, sizeof(property));
X      cl = (coordListP) calloc(1, sizeof(coordList));
X      if (!(prop && cl))
X	 barf("Memory allocation failure (addStone)");
X      prop->next = n->p;
X      n->p = prop;
X      prop->d = (data *) cl;
X      prop->t = t;
X   }
X   setCoord(x, y, (coordList *) prop->d);
X
X}
X
XFUNCTION int makeMove(n, t, x, y)
X    nodep n;
X    Token t;
X    int x, y;
X{
X   nodep new;
X   coordListP cl;
X   property *prop;
X   int ret;
X   ret = 0;
X
X   if (!(n->p)) {
X      new = n;
X      ret = 1;
X   } else {
X
X      new = newNode();
X      if (n->child)
X	 n->child->parent = new;
X      new->parent = n;
X      new->child = n->child;
X      n->child = new;
X   }
X
X
X   prop = (property *) calloc(1, sizeof(property));
X   cl = (coordListP) calloc(1, sizeof(coordList));
X   if (!(prop && cl))
X      barf("Memory allocation failure (makeMove)");
X   new->p = prop;
X   prop->d = (data *) cl;
X   prop->t = t;
X
X   setCoord(x, y, (coordList *) prop->d);
X   return ret;
X
X}
X
X
X
XFUNCTION void makeVariation(n)
X    nodep n;
X{
X   nodep new, last;
X
X   if (!(n->child)) {
X      new = newNode();
X      new->parent = n;
X      n->child = new;
X   } else {
X      new = newNode();
X      new->parent = n;
X      last = treeLastSibling(n->child);
X      last->nextSibling = new;
X      new->lastSibling = last;
X   }
X}
X
X
XFUNCTION void cutTree(n)
X    nodep n;
X{
X   freeNode(buffer);
X   if (n->nextSibling)
X      n->nextSibling->lastSibling = n->lastSibling;
X   if (n->lastSibling)
X      n->lastSibling->nextSibling = n->nextSibling;
X   else if (n->parent)
X      n->parent->child = n->nextSibling;
X   n->nextSibling = 0;
X   n->lastSibling = 0;
X   buffer = n;
X}
X
X
XFUNCTION void pasteTree(n)
X    nodep *n;
X{
X   nodep last;
X   if (buffer) {
X      for (last = buffer; last->child; last = last->child);
X      if (last->child = (*n)->child)
X	 (*n)->child->parent = last;
X      (*n)->child = buffer;
X      buffer->parent = (*n);
X      (*n) = buffer;
X   }
X}
X
X
XFUNCTION void edComment(n)
X    nodep n;
X{
X   property *prop;
X
X   if (!(prop = getprop(n, t_Comment))) {
X      prop = (property *) calloc(1, sizeof(property));
X      prop->t = t_Comment;
X      prop->next = n->p;
X      n->p = prop;
X   }
X   (*io->editComment) ((char *) prop->d, &(prop->d));
X   if (!(prop->d)) {
X      n->p = prop->next;
X      free(prop);
X   }
X}
X
X
X
XFUNCTION void deleteNode(n)
X    nodep *n;
X{
X   nodep last;
X   if (!((*n)->child)) {
X      freeProps(*n);
X      (*n)->p = 0;
X   } else {
X      if ((*n)->parent && (*n)->parent->child == *n)
X	 (*n)->parent->child = (*n)->child;
X      if ((*n)->lastSibling) {
X	 (*n)->child->lastSibling = (*n)->lastSibling;
X	 (*n)->lastSibling->nextSibling = (*n)->child;
X      }
X      /* new parent for all of child's sibs */
X
X      for (last = (*n)->child; last->nextSibling; last = last->nextSibling)
X	 last->parent = (*n)->parent;
X      last->parent = (*n)->parent;
X
X      /* Last of child's sibs get's to point to next sib of main node */
X      last->nextSibling = (*n)->nextSibling;
X
X      if ((*n)->nextSibling)
X	 (*n)->nextSibling = last;
X      last = *n;
X      *n = (*n)->child;
X      delNode(last);
X   }
X}
X
X
XFUNCTION void makeName(n)
X    nodep n;
X{
X   char newname[41];
X   property *prop;
X
X   (*io->queryStr) ("Name: ", newname, 40);
X
X   if (prop = getprop(n, t_Name))
X      free(prop->d);
X   else {
X      prop = (property *) calloc(1, sizeof(property));
X      addprop(n, prop);
X      prop->t = t_Name;
X   }
X   prop->d = (data *) dupStr(newname);
X   printf("%s", (char *) prop->d);
X}
X
X
XFUNCTION void replaceComment(n, str)
X    nodep n;
X    char *str;
X{
X   property *prop;
X
X   if (!(prop = getprop(n, t_Comment))) {
X      prop = (property *) calloc(1, sizeof(property));
X      prop->t = t_Comment;
X      prop->next = n->p;
X      n->p = prop;
X   } else
X      free(prop->d);
X   prop->d = (data *) dupStr(str);
X}
END_OF_FILE
if test 9788 -ne `wc -c <'edit.c'`; then
    echo shar: \"'edit.c'\" unpacked with wrong size!
fi
# end of 'edit.c'
fi
if test -f 'mailgo' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'mailgo'\"
else
echo shar: Extracting \"'mailgo'\" \(5050 characters\)
sed "s/^X//" >'mailgo' <<'END_OF_FILE'
X#!/bin/sh
X#
X#  mailgo 1.41    E-Mail go game management program by Adrian Mariano
X#     4/5/91      I place it on the public domain.  Please send improvements
X#                 to me at adrian@milton.u.washington.edu.
X# 
X#  Syntax: mailgo [-r] filename
X#          mailgo -n [filename] 
X# 
X#  Filename should contain a mailgo go game
X#  
X#  -r resends the file to the opponent
X#  -n start a new game, using data in filename to get address
X#
X#  Invokes the game processor in the environment variable MAILGO, or attempts
X#  to run mgt from the inherited path if MAILGO is not set.
X#
X#  System V Unix users should replace references to the 'mail' command
X#  with 'mailx'
X#
Xif [ x$1 = x-n ]
Xthen
X  if [ $# -gt 2 ]
X  then
X    echo Wrong number of parameters
X    exit
X  fi
X  if [ $# -eq 2 ]
X  then
X    if [ ! -s $2 ]
X    then
X      echo File $2 not found.
X      exit
X    fi
X    opponent=`sed -n '2,5s/TO: //p' $2`
X    echo Opponent address: $opponent
X    hisfile=`sed -n '2,5s/TOFILE: //p' $2`
X    echo His game file: $hisfile
X    me=`sed -n '2,5s/FROM: //p' $2`
X    echo Your address: $me
X    myfile=`sed -n '2,5s/FROMFILE: //p' $2`
X    echo Your game file: $myfile
X  else
X    echo -n "Opponent address: "
X    read opponent
X    echo -n "Opponent game filename: "
X    read hisfile
X    echo -n "Your address: "
X    read me
X    echo -n "Your game filename: "
X    read myfile
X  fi
X  echo -n "Black player name: "
X  read bpname
X  echo -n "White player name: "
X  read wpname
X  echo -n "Handicap: "
X  read handicap
X  if grep "VieW\[\]" $myfile >/dev/null 2>&1
X  then
X    echo -n "File $myfile contains game possibly in progress.  Clobber (y/n)? "
X    read res
X    if [ ! \( $res = Y -o $res = y \) ]
X    then
X      echo -n "Your game filename: "
X      read myfile
X    fi
X  fi
X  cat <<END_END1 >$myfile
X---GoGaMeStArT---
XFROM: $me
XFROMFILE: $myfile
XTO: $opponent
XTOFILE: $hisfile
XNEWGAME
XEND_END1
X  date=`date`
X  cat <<END_END2 > MailGo$$
X(
X;
XGaMe[1]
XVieW[]
XSiZe[19]
XComment[ Black: $bpname
X White: $wpname
X Handicap: $handicap
X Started: $date
X Completed:
X Result:
X]
XEND_END2
X  case $handicap in
X    2) echo "AddBlack[dp][pd]" >> MailGo$$ ;;
X    3) echo "AddBlack[dp][pd][pp]" >> MailGo$$ ;;
X    4) echo "AddBlack[dd][dp][pd][pp]" >> MailGo$$ ;;
X    5) echo "AddBlack[dd][dp][jj][pd][pp]" >> MailGo$$ ;;
X    6) echo "AddBlack[dd][dj][dp][pd][pj][pp]" >> MailGo$$ ;;
X    7) echo "AddBlack[dd][dj][dp][jj][pd][pj][pp]" >> MailGo$$ ;;
X    8) echo "AddBlack[dd][dj][dp][jd][jp][pd][pj][pp]" >> MailGo$$ ;;
X    9) echo "AddBlack[dd][dj][dp][jd][jj][jp][pd][pj][pp]" >> MailGo$$ ;;
X  esac
X  echo ")" >> MailGo$$
X  if ${MAILGO-mgt} -m MailOut$$ MailGo$$
X  then
X    if [ -s MailOut$$ ]
X    then
X      cat MailOut$$ >>$myfile
X    else
X      cat MailGo$$ >>$myfile
X    fi
X    rm -f MailOut$$ MailGo$$
X    echo Mailing new game to $opponent, $hisfile
X    echo ---GoGaMeEnD--- >> $myfile
X    mail -s "New Go Game: $hisfile" $opponent <$myfile
X    exit
X  else
X    echo No move made, or mgt error.  NOT mailing new game.
X    rm -f MailGo$$ MailOut$$
X    exit
X  fi
Xfi
Xif [ $# -eq 2 -a x$1 = x-r ]
Xthen
X  if grep "\---GoGaMeEnD---" $2 >/dev/null 2>&1
X  then
X    name=`sed -n '2,5s/TO: //p' $2`
X    hisfile=`sed -n '2,5s/TOFILE: //p' $2`
X    echo Remailing response to $name, $hisfile
X    mail -s "Remailed Go Game: $hisfile" $name < $2
X    exit
X  else
X    echo Invalid input file $2
X    exit
X  fi
Xfi    
Xif [ $# -ne 1 ]
Xthen
X  echo Wrong number of parameters
X  exit
Xfi
Xif [ ! -s $1 ]
Xthen
X  echo File $1 not found
X  exit
Xfi
Xsed -n '/---GoGaMeStArT---/,/---GoGaMeEnD---/{s/---GoGaMe.*---//
Xp
X}' $1 > MailGo$$
Xif [ ! -s MailGo$$ ]
Xthen
X  echo Invalid input file $1
X  exit
Xfi
Xif ${MAILGO-mgt} -m MailOut$$ MailGo$$ 
Xthen
X  echo ---GoGaMeStArT--- > MailFile$$
X  sed -n '1,/(/s/FROM/TO/p' MailGo$$ >> MailFile$$
X  sed -n '1,/(/s/TO/FROM/p' MailGo$$ >> MailFile$$
X  cat MailOut$$ >> MailFile$$
X  echo ---GoGaMeEnD--- >> MailFile$$
X  name=`sed -n '2,5s/FROM: //p' MailGo$$`
X  fileout=`sed -n '2,5s/TOFILE: //p' MailGo$$`
X  tofile=`sed -n '2,5s/FROMFILE: //p' MailGo$$`
X  if sed -n 6p MailGo$$ | grep NEW > /dev/null 2>&1
X  then
X    if [ -s $fileout ]
X    then
X      echo "File $fileout exists.  Clobber (Y/N)?"
X      read res
X      if [ $res = 'Y' -o $res = 'y' ]
X      then
X        rm -f $fileout
X      else
X        echo -n "Output filename: "
X        read newfileout
X        sed s/$fileout/$newfileout/ MailFile$$ > Mfil$$
X        mv Mfil$$ MailFile$$
X        fileout=$newfileout
X      fi
X    fi
X  fi
X  echo Mailing response to $name, $tofile
X  mail -s "Go Game: $tofile" $name < MailFile$$ 
X  rm -f MailGo$$ MailOut$$ $1
X  if grep "\---GoGaMeEnD---" $fileout > /dev/null 2>&1 || test ! -s $fileout
X  then
X    mv MailFile$$ $fileout
X  else
X    echo Save file $fileout doesn\'t look like a mailgo file.  
X    echo "Overwrite it anyway (y/n)?"
X    read res
X    if test $res = Y -o $res = y
X    then
X      mv MailFile$$ $fileout
X    else
X      echo Game record left in MailFile$$
X    fi
X  fi
Xelse
X  echo No move made, or mgt error.  NOT mailing response.
X  rm -f MailGo$$ MailOut$$
Xfi
X
X
X
END_OF_FILE
if test 5050 -ne `wc -c <'mailgo'`; then
    echo shar: \"'mailgo'\" unpacked with wrong size!
fi
chmod +x 'mailgo'
# end of 'mailgo'
fi
if test -f 'play.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'play.c'\"
else
echo shar: Extracting \"'play.c'\" \(5767 characters\)
sed "s/^X//" >'play.c' <<'END_OF_FILE'
X/* "mgt" Copyright (c) 1991 Shodan  */
X
X
X#include "mgt.h"
X
XFUNCTION int legal(b, player, i, j)
X    pBoard b;
X    int i, j;
X    Token player;
X{
X   piece cur;
X
X   cur = (player != t_Black) ? P_BLACK : P_WHITE;
X   if (b->b[i][j] != P_NOTHING) {
X      (*io->displayComment) ("There's already a piece there.");
X      return false;
X   }
X   b->b[i][j] = (player == t_Black) ? P_BLACK : P_WHITE;
X   if (
X	 !(((b->b[i + 1][j] == cur) && !liberties(b, i + 1, j)) ||
X	   ((b->b[i - 1][j] == cur) && !liberties(b, i - 1, j)) ||
X	   ((b->b[i][j + 1] == cur) && !liberties(b, i, j + 1)) ||
X	   ((b->b[i][j - 1] == cur) && !liberties(b, i, j - 1)))
X	 && !liberties(b, i, j)) {
X      (*io->displayComment) ("That move is suicide.");
X      b->b[i][j] = P_NOTHING;
X      return false;
X   }
X   b->b[i][j] = P_NOTHING;
X
X   /* insert Ko code here! */
X
X   return true;
X}
X
X
X
X
XFUNCTION boolean inRange(i, j)
X{
X   return i >= 0 && i < boardsize && j >= 0 && j < boardsize;
X}
X
XFUNCTION int lib0(b, m, i, j, t)
X    pBoard b;
X    pBoard m;
X    int i, j;
X    piece t;
X{
X   piece pt;
X
X   if (!inRange(i, j))
X      return 0;
X   pt = b->b[i][j];
X   if ((pt != P_NOTHING && pt != t) || m->b[i][j] != P_NOTHING)
X      return 0;
X   m->b[i][j] = (pt == t) ? (piece) 1 : (piece) 2;
X   if (pt == P_NOTHING)
X      return 1;
X   return lib0(b, m, i, j + 1, t) + lib0(b, m, i + 1, j, t) + lib0(b, m, i - 1, j, t) +
X      lib0(b, m, i, j - 1, t);
X}
X
XFUNCTION int liberties(b, i, j)	/* count the # of liberties for group at i,j */
X    pBoard b;
X    int i, j;
X{
X   board m;
X
X   boardClear(&m);
X   return lib0(b, &m, i, j, b->b[i][j]);
X}
X
XFUNCTION void removeStones(b, i, j)
X    pBoard b;
X    int i, j;
X{
X   board m;
X   extern int prisoners[];
X   if (b->b[i][j] == P_NOTHING)
X      return;
X   boardClear(&m);
X   lib0(b, &m, i, j, b->b[i][j]);
X   for (i = boardsize; i--;)
X      for (j = boardsize; j--;)
X	 if (m.b[i][j] == (piece) 1) {
X	    prisoners[(int) (b->b[i][j]) - 1]++;
X	    b->b[i][j] = P_NOTHING;
X	 }
X}
X
XFUNCTION boolean tryKill(b, i, j, t)
X    pBoard b;
X    int i, j;
X    piece t;
X{
X   piece w;
X   if (!inRange(i, j))
X      return false;
X   w = b->b[i][j];
X   if (w != P_NOTHING && w != t && !liberties(b, i, j)) {
X      removeStones(b, i, j);
X      return true;
X   }
X   return false;
X}
X
XFUNCTION boolean placeStone(b, i, j, t)
X    pBoard b;
X    int i, j;
X    piece t;
X{
X   if (!inRange(i, j))
X      return false;
X   b->b[i][j] = t;
X   xcur = i;
X   ycur = j;
X   return !(tryKill(b, i, j - 1, t) | tryKill(b, i, j + 1, t) |
X	    tryKill(b, i - 1, j, t) | tryKill(b, i + 1, j, t));
X}
X
XFUNCTION void boardSet(b, i, j, p)
X    pBoard b;
X    int i, j;
X    piece p;
X{
X   b->b[i][j] = p;
X}
X
XFUNCTION piece boardGet(b, i, j)
X    pBoard b;
X    int i, j;
X{
X   return b->b[i][j];
X}
X
X
XFUNCTION void boardClear(b)
X    pBoard b;
X{
X   int i, j;
X   for (i = boardsize; i--;)
X      for (j = boardsize; j--;)
X	 b->b[i][j] = P_NOTHING;
X}
X
XFUNCTION void copyBoard(a, b)
X    pBoard a, b;
X{
X   int i, j;
X   for (i = boardsize; i--;)
X      for (j = boardsize; j--;)
X	 b->b[i][j] = a->b[i][j];
X}
X
X
Xint look(stone, array, index, i)
X    int stone, array[], *index, i;
X{
X   if (stone == P_NOTHING)
X      array[(*index)++] = i;
X   else if (stone == P_BLACK)
X      return 1;
X   else if (stone == P_WHITE)
X      return 2;
X   return 0;
X}
X
X
Xint fillregion(b, x, y)
X    pBoard b;
X    int x, y;
X{
X   int goup[19], godown[19], up = 0, down = 0, found = 0, i;
X
X   for (i = x; i < boardsize && b->b[i][y] == P_NOTHING; i++) {
X      b->b[i][y] = P_CHECKED;
X      if (y > 0)
X	 found |= look(b->b[i][y - 1], goup, &up, i);
X      if (y < boardsize - 1)
X	 found |= look(b->b[i][y + 1], godown, &down, i);
X   }
X   if (i != boardsize) {
X      if (b->b[i][y] == P_BLACK)
X	 found |= 1;
X      if (b->b[i][y] == P_WHITE)
X	 found |= 2;
X   }
X   for (i = x - 1; i >= 0 && b->b[i][y] == P_NOTHING; i--) {
X      b->b[i][y] = P_CHECKED;
X      if (y > 0)
X	 found |= look(b->b[i][y - 1], goup, &up, i);
X      if (y < boardsize - 1)
X	 found |= look(b->b[i][y + 1], godown, &down, i);
X   }
X   if (i != -1) {
X      if (b->b[i][y] == P_BLACK)
X	 found |= 1;
X      if (b->b[i][y] == P_WHITE)
X	 found |= 2;
X   }
X   while (up)
X      found |= fillregion(b, goup[--up], y - 1);
X   while (down)
X      found |= fillregion(b, godown[--down], y + 1);
X   return found;
X}
X
X
XFUNCTION void scoreBoard(b, score)
X    pBoard b;
X    int score[];
X{
X   int x, y, i, j, owner;
X   piece newval;
X
X   score[0] = 0;
X   score[1] = 0;
X   for (i = 0; i < boardsize; i++)
X      for (j = 0; j < boardsize; j++) {
X	 owner = fillregion(b, i, j);
X	 if (!owner)
X	    owner = 3;
X	 switch (owner) {
X	 case 3:
X	    newval = P_DAME;
X	    break;
X	 case 2:
X	    newval = P_WHITETERR;
X	    break;
X	 case 1:
X	    newval = P_BLACKTERR;
X	    break;
X	 }
X	 for (x = 0; x < boardsize; x++)
X	    for (y = 0; y < boardsize; y++)
X	       if (b->b[x][y] == P_CHECKED) {
X		  b->b[x][y] = newval;
X		  if (owner != 3)
X		     score[owner - 1]++;
X	       }
X      }
X}
X
X
X
X#if 0
Xint MARX[19][19];
X
XFUNCTION piece Owner(b, x, y)
X    pBoard b;
X    int x, y;
X{
X   int o, i, j;
X   for (i = 0; i < boardsize; i++)
X      for (j = 0; j < boardsize; j++)
X	 MARX[i][j] = 0;
X   o = Owner0(b, x, y);
X   return (piece) (o == -1 ? 3 : o);
X}
X
XFUNCTION int Owner0(b, x, y)
X    pBoard b;
X    int x, y;
X{
X   if (MARX[x][y] || !inRange(x, y))
X      return 3;
X   MARX[x][y] = 1;
X   if (b->b[x][y] != P_NOTHING)
X      return ((int) b->b[x][y] + 3);
X   return (New(b, New(b, New(b, New(b, 3, x - 1, y), x + 1, y), x, y - 1), x, y + 1));
X
X}
X
XFUNCTION int New(b, o, x2, y2)	/* 3= undetermined, 4=p1, 5=p2, -1=shared */
X    pBoard b;
X    int o;
X    int x2, y2;
X{
X   int n;			/* old, new */
X   n = Owner0(b, x2, y2);
X   if (o == 3)
X      return n;
X   if (n == 3)
X      return o;
X   if (o < 0)
X      return o;
X   return (n == o ? o : -1);
X}
X#endif
END_OF_FILE
if test 5767 -ne `wc -c <'play.c'`; then
    echo shar: \"'play.c'\" unpacked with wrong size!
fi
# end of 'play.c'
fi
if test -f 'tree.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'tree.c'\"
else
echo shar: Extracting \"'tree.c'\" \(4677 characters\)
sed "s/^X//" >'tree.c' <<'END_OF_FILE'
X/* "mgt" Copyright (c) 1991 Shodan  */
X
X#include "mgt.h"
X
X
Xstatic char bitmask[] =
X{
X   1 << 0, 1 << 1, 1 << 2, 1 << 3, 1 << 4, 1 << 5, 1 << 6, 1 << 7, 1 << 8
X};
X
X
X#define byteNumXY(x,y) (((x)+(y)*19)/8)
X#define bitNumXY(x,y) (((x)+(y)*19)%8)
X
X
Xstatic int newNodeNum;
X
X
XFUNCTION boolean getCoord(x, y, c)
X    int x, y;
X    coordListP c;
X{
X   return c->b[byteNumXY(x, y)] & bitmask[bitNumXY(x, y)];
X}
X
XFUNCTION void setCoord(x, y, c)
X    int x, y;
X    coordListP c;
X{
X   int bytenum, bitnum;
X   bytenum = byteNumXY(x, y);
X   bitnum = bitNumXY(x, y);
X   c->b[bytenum] |= bitmask[bitnum];
X}
X
XFUNCTION void clearCoord(x, y, c)
X    int x, y;
X    coordListP c;
X{
X   int bytenum;
X   bytenum = byteNumXY(x, y);
X   c->b[bytenum] &= (~bitmask[bitNumXY(x, y)]);
X}
X
XFUNCTION void initNodes()
X{
X   newNodeNum = 0;
X}
X
XFUNCTION nodep newNode()
X{
X   nodep new;
X#ifdef DEBUG
X   totalmemory += sizeof(node);
X   fprintf(debug, "%ld %ld\n", totalmemory, coreleft());
X#endif
X   new = (nodep) calloc(1, sizeof(node));
X   if (!new)
X      barf("Memory allocation failure (newnode)");
X   new->nodeNum = newNodeNum++;
X   return new;
X}
X
XFUNCTION void freeNode(n)
X    nodep n;
X{
X   if (n) {
X      freeNode(n->nextSibling);
X      freeNode(n->child);
X      delNode(n);
X   }
X}
X
XFUNCTION char *dupStr(s)
X    char *s;
X{
X   char *c;
X#ifdef DEBUG
X   totalmemory += strlen(s) + 1;
X   fprintf(debug, "%ld %ld\n", totalmemory, coreleft());
X#endif
X   c = (char *) malloc((unsigned) strlen(s) + 1);
X   if (!c)
X      barf("Memory allocation failure (dupstr)");
X   strcpy(c, s);
X   return c;
X}
X
X
XFUNCTION void freeProps(n)
X    nodep n;
X{
X   property *prop;
X   prop = n->p;
X   while (prop) {
X      free(prop->d);
X      prop = prop->next;
X   }
X}
X
X
XFUNCTION void delNode(n)
X    nodep n;
X{
X   freeProps(n);
X   free(n);
X}
X
XFUNCTION void addprop(n, p)
X    nodep n;
X    property *p;
X{
X   p->next = n->p;
X   n->p = p;
X}
X
XFUNCTION property *getprop(n, t)
X    nodep n;
X    Token t;
X{
X   property *p;
X   p = n->p;
X   while (p && p->t != t)
X      p = p->next;
X   return p;
X}
X
XFUNCTION int treeCountSiblings(n)
X    nodep n;
X{
X   int i;
X   nodep n1;
X
X   n1 = n->child;
X   i = 0;
X   while (n1) {
X      n1 = n1->nextSibling;
X      i++;
X   }
X   return i;
X}
X
XFUNCTION nodep nthChild(n, c)	/* nodep, int */
X    nodep n;
X    int c;
X{
X
X   if (n->child) {
X      n = child(n);
X      while (c-- && n)
X	 n = nextSibling(n);
X   } else {
X      n = 0;
X   }
X   return n;
X}
X
X/* TREE WALK functions KEEP TRACK OF DEPTH AS WELL */
X
XFUNCTION nodep parent(n)
X    nodep n;
X{
X   return n->parent;
X}
X
XFUNCTION nodep child(n)
X    nodep n;
X{
X   return n->child;
X}
X
XFUNCTION nodep lastSibling(n)
X    nodep n;
X{
X   return n->lastSibling;
X}
X
XFUNCTION nodep nextSibling(n)
X    nodep n;
X{
X   return n->nextSibling;
X}
X
XFUNCTION nodep treeLastSibling(n)
X    nodep n;
X{
X   while (n->nextSibling) {
X      n = n->nextSibling;
X   }
X   return n;
X}
X
X/* go to next node down the tree. Stop if at bottom. */
XFUNCTION nodep treeDown(n)
X    nodep n;
X{
X   if (n->child) {
X      BUG("treeDown: going down\n");
X      return child(n);
X   } else {
X      BUG("treeDown: stop\n");
X      return n;
X   }
X}
X
X/* backup, stop if at top */
XFUNCTION nodep treeUp(n)
X    nodep n;
X{
X   if (n->parent) {
X      BUG("treeUp: going up\n");
X      return parent(n);
X   } else {
X      BUG("treeUp: staying\n");
X      return n;
X   }
X}
X
X
X/* go to next node backing up the tree only */
XFUNCTION nodep treeNextUp(n)
X    nodep n;
X{
X   if (n->nextSibling) {
X      BUG("nextSibling ");
X      return nextSibling(n);
X   } else if (n->parent) {
X      BUG("nextup-parent ");
X      while (n->parent && !n->nextSibling)
X	 n = parent(n);
X      if (n->nextSibling)
X	 return nextSibling(n);
X      else
X	 return n;
X   } else if (n->child) {
X      BUG("child ");
X      return child(n);
X   } else {
X      BUG("current ");
X      return n;
X   }
X}
X
X
X/* go to next node, backup if neccessary */
XFUNCTION nodep treeNext(n)
X    nodep n;
X{
X   nodep r;
X
X   BUG("treeNext:");
X   if (n != (r = treeDown(n))) {
X      BUG("going down ");
X   } else {
X      BUG("going up ");
X      r = treeNextUp(n);
X   }
X   BUG("\n");
X   return r;
X}
X
X
X
XFUNCTION nodep lastChildOfLastSibling(n)
X    nodep n;
X{
X
X   while (n->nextSibling)
X      n = nextSibling(n);
X   if (n->child)
X      return lastChildOfLastSibling(child(n));
X   else
X      return n;
X}
X
X/* go to next node, backup if neccessary */
XFUNCTION nodep treeLast(n)
X    nodep n;
X{
X   nodep r;
X
X   if (n->lastSibling) {
X      n = lastSibling(n);
X      if (n->child)
X	 r = lastChildOfLastSibling(child(n));
X      else
X	 r = n;
X   } else if (n->parent) {
X      r = parent(n);
X   } else if (n->child) {
X      r = lastChildOfLastSibling(child(n));
X   } else {
X      r = n;
X   }
X   return r;
X}
END_OF_FILE
if test 4677 -ne `wc -c <'tree.c'`; then
    echo shar: \"'tree.c'\" unpacked with wrong size!
fi
# end of 'tree.c'
fi
echo shar: End of archive 3 \(of 4\).
cp /dev/null ark3isdone
MISSING=""
for I in 1 2 3 4 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 4 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0