[comp.sources.games] v03i100: go - go board manager sources, Part04/05

games-request@tekred.TEK.COM (03/10/88)

Submitted by: Fred Hansen <wjh+@andrew.cmu.edu>
Comp.sources.games: Volume 3, Issue 100
Archive-name: go/Part04



#! /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 4 (of 5)."
# Contents:  go.pas goMgr.pas
# Wrapped by billr@saab on Wed Mar  9 09:14:46 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f go.pas -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"go.pas\"
else
echo shar: Extracting \"go.pas\" \(26299 characters\)
sed "s/^X//" >go.pas <<'END_OF_go.pas'
X{---------------------------------------------------------------}
X{ Go Game Manager                                               }
X{ Copyright (c) 1982 by Three Rivers Computer Corp.             }
X{                                                               }
X{ Written: June 3, 1982 by Stoney Ballard                       }
X{ Edit History:                                                 }
X{    June  3, 1982 Started                                      }
X{    June  4, 1982 Add dead group removal                       }
X{    June 10, 1982 Use new go file manager                      }
X{    Nov  10, 1982 Extensively Hacked Up                        }
X{    Dec  29, 1982 Changed "Erase Branch" to "Prune Branches"   }
X{    Jan   6, 1983 Added ^C escape from all readlns             }
X{---------------------------------------------------------------}
X
Xprogram Go;
X
Xexports
X
Ximports stream from stream;
X
Xprocedure resetInput;
X
Xprivate
X
Ximports system from System;
Ximports raster from raster;
Ximports screen from screen;
Ximports popUp from popUp;
Ximports IO_Others from IO_Others;
Ximports goCom from goCom;
Ximports goMgr from goMgr;
Ximports goTree from goTree;
Ximports goBoard from goBoard;
Ximports goMenu from goMenu; 
Ximports memory from memory;
Ximports perq_string from perq_string;
Ximports goPlayer from goPlayer;
X
Xlabel
X  99;       (* the fatal error point *)
X
Xvar
X  oCurPosX, oCurPosY: integer;
X  oScreenPtr: rasterPtr;
X
X  procedure resetInput;
X  begin { resetInput }
X    streamKeyboardReset(input);
X  end { resetInput };
X
X  procedure newTitle;
X  var
X    ts: string[128];
X    fn: string;
X    fl, fPos, tPos, i: integer;
X  begin { newTitle }
X    ts := 'Go  Version ';
X    ts := concat(ts, version);
X    getFNameString(fn);
X    fl := length(fn);
X    if fl > 0 then
X      begin
X        fPos := 81 - fl;
X        tPos := length(ts) + 1;
X        adjust(ts, 80);
X        for i := tPos to 80 do
X          ts[i] := ' ';
X        for i := fPos to fPos + fl - 1 do
X          ts[i] := fn[i - fPos + 1];
X      end;
X    changeTitle(ts);
X  end { newTitle };
X
X  procedure initialize;
X  var
X    sseg: integer;
X
X    procedure setupWindows;
X    var
X      ts: string;
X    begin { setupWindows }
X      createWindow(boardWin, bWinX, bWinY, bWinW, bWinH, ' ');
X      createWindow(menuWin, mWinX, mWinY, mWinW, mWinH, '');
X      createWindow(statWin, sWinX, sWinY, sWinW, sWinH, '');      
X      changeWindow(0);
X      gameFName := '';
X      newTitle;
X    end { setupWindows };
X
X  begin { initialize }
X    createSegment(sseg, 192, 1, 192);
X    oScreenPtr := makePtr(sseg, 0, rasterPtr);
X    SReadCursor(oCurPosX, oCurPosY);
X    rasterop(rRpl, 768, 1024, 0, 0, SScreenW, oScreenPtr,
X                              0, 0, SScreenW, SScreenP);
X    IOSetFunction(CTCursCompl);
X    rasterop(RAndNot, 768, 1024, 0, 0, SScreenW, SScreenP,
X                                 0, 0, SScreenW, SScreenP);
X    setupWindows;
X    initMenu;
X    captures[black] := 0;
X    captures[white] := 0;
X    initGoTree;
X    initGoBoard;
X    makeGoTree;
X    initGoMgr;
X    gameFName := '';
X    numbEnabled := false;
X    treeDirty := false;
X    playLevel := 0;
X    debug := false;
X    printLarge := true;
X    initGoPlayer;
X  end { initialize };
X  
X  procedure doit;
X  var
X    done, foundIt, endLoop, gbg: boolean;
X    CtlCseen, playMyself, lastWasPass: boolean;
X    whoseTurn, whoWasLast: sType;
X    i, xi, yi, xs, ys: integer;
X    numDead, numHC, cmd: integer;
X    lastBuM: integer;
X    thisTag: tagPtr;
X    lastMove: pMRec;
X
X    function getLine(var l: string): boolean;
X    label
X      1;
X    var
X      i, j, cx, cy: integer;
X
X      handler ctlC;
X      begin { ctlC }
X        IOKeyClear;
X        streamKeyboardReset(input);
X        beep(error);
X        prompt('');
X        l := '';
X        getLine := false;
X        exit(getLine); 
X      end { ctlC }; 
X
X      handler pastEOF(fn: pathName);
X      begin { pastEOF }
X        reset(input, fn);
X        sSetCursor(cx, cy);
X        write('    ');
X        sSetCursor(cx, cy);
X        goto 1;
X      end { pastEOF };
X
X    begin { getLine }
X      sReadCursor(cx, cy);
X    1:
X      readln(l);
X      getLine := true;
X      j := 0;
X      for i := 1 to length(l) do
X        if ord(l[i]) >= 32 then
X          begin
X            j := j + 1;
X            l[j] := l[i];
X          end;
X      adjust(l, j);
X    end { getLine };
X
X    procedure resetGame;
X    begin { resetGame }
X      clearBoard;
X      koX := -1;
X      koY := -1;
X      moveNum := 0;
X      curMove := treeRoot;
X      captures[black] := 0;
X      captures[white] := 0; 
X      showCaptures;
X      whoseTurn := black;
X      turnIs(black);
X      gameFname := '';
X      newTitle;
X      gameOver := false;
X      initGoMgr;
X    end { resetGame };
X
X    procedure switchWho;
X    begin { switchWho }
X      if curMove = treeRoot then
X        whoseTurn := black
X      else if curMove^.id = remove then
X        whoseTurn := curMove^.who
X      else if curMove^.id = hcPlay then
X        whoseTurn := white
X      else if curMove^.who = black then
X        whoseTurn := white
X      else
X        whoseTurn := black;
X      turnIs(whoseTurn);
X    end { switchWho };
X
X    procedure updateStatus;
X    begin { updateStatus }
X      dotLast;
X      showCaptures;
X      showComment;
X      showTag;
X      switchWho;
X    end { updateStatus };
X
X    procedure doReadGame;
X    var
X      fName: pathName;
X
X      handler badFileVersion;
X      begin { badFileVersion }
X        beep(error);
X        prompt('');
X        write(gameFName, ' is not compatable with this version of GO');
X        resetGame;
X        exit(doReadGame);
X      end { badFileVersion };
X
X    begin { doReadGame }
X      if menuGoFile(fName) then
X        begin
X          prompt('Reading ');
X          write(fName, '.Go ...');
X          readTree(concat(fName, '.GO'));
X          resetGame;
X          gameFName := fName;
X          if treeRoot^.lastMove <> nil then
X            switchBranch(treeRoot^.lastMove);
X          treeDirty := false;
X          prompt('');
X          newTitle;
X        end;
X    end { doReadGame };
X
X    procedure doWriteGame;
X    var
X      fs: string;
X      procedure addExt(var nam: string);
X      var
X        es: string;
X      begin { addExt }
X        if length(nam) > 3 then
X          begin
X            es := substr(nam, length(nam) - 2, 3);
X            convUpper(es);
X            if es <> '.GO' then
X              nam := concat(nam, '.Go');
X          end
X        else
X          nam := concat(nam, '.Go');
X      end { addExt };
X
X      handler badGoWrite;
X      begin { badGoWrite };
X        beep(error);
X        prompt('Unable to write file ');
X        write(fs);
X        exit(doWriteGame);
X      end { badGoWrite };
X
X    begin { doWriteGame }
X      IOKeyClear;
X      streamKeyboardReset(input);
X      if gameFName <> '' then
X        begin
X          prompt('Game File Name [');
X          write(gameFName, ']? ');
X        end
X      else
X        prompt('Game File Name? ');
X      if not getLine(fs) then
X        exit(doWriteGame);
X      if fs = '' then
X        if gameFName = '' then
X          begin
X            beep(error);
X            prompt('');
X            exit(doWriteGame);
X          end
X        else
X          fs := gameFName;
X      gameFName := fs;
X      addExt(fs);
X      prompt('Writing ');
X      write(fs, ' ...');
X      writeTree(fs, curMove);
X      treeDirty := false;
X      prompt('');
X      newTitle;
X    end { doWriteGame };
X
X    function chooseAlt: boolean;
X    label
X      10;
X    var
X      bx, by, xs, ys: integer;
X      tm: pMRec;
X      hc0There: boolean;
X      hcMenu: pNameDesc;
X      res: resres;
X      numHC, i, j, numNHC: integer;
X
X      handler outside;
X      begin { outside }
X        destroyNameDesc(hcMenu);
X        chooseAlt := false;
X        beep(error);
X        restoreCursor;
X        exit(chooseAlt);
X      end { outside };
X
X    begin { chooseAlt }
X      chooseAlt := false;
X      switchWho;
X      waitNoButton;
X      tm := curMove^.flink;
X      numHC := 0;
X      numNHC := 0;
X      hc0There := false;
X      while tm <> nil do
X        begin
X          if tm^.id = hcPlay then
X            numHC := numHC + 1
X          else
X            begin
X              hc0There := true;
X              numNHC := numNHC + 1;
X            end;
X          tm := tm^.slink;
X        end;
X      if numHC > 0 then
X        begin
X          if hc0There then
X            numHC := numHC + 1;
X          allocNameDesc(numHC, 0, hcMenu);
X          hcMenu^.header := 'Handicap Alternates';
X          j := 1;
X          if hc0There then
X            begin
X              hcMenu^.commands[1] := '0';
X              j := 2;
X            end;
X          tm := curMove^.flink;
X          for i := j to numHC do
X            begin
X              while tm^.id <> hcPlay do
X                tm := tm^.slink;
X    {$R-}
X              hcMenu^.commands[i] := ' ';
X              hcMenu^.commands[i][1] := chr(tm^.hcNum + ord('0'));
X    {$R=}
X              tm := tm^.slink;
X            end;
X          menu(hcMenu, false, 1, numHC, -1, -1, -1, res);
X          restoreCursor;
X          destroyNameDesc(hcMenu);
X          i := res^.indices[1];
X          destroyRes(res);
X          if hc0There then
X            if i = 1 then
X              begin
X                if numNHC > 1 then
X                  goto 10;
X                tm := curMove^.flink;
X                while tm^.id <> move do
X                  tm := tm^.slink;
X                forwardTo(tm);
X                chooseAlt := true;
X                exit(chooseAlt);
X              end
X            else
X              i := i - 1;
X          tm := curMove^.flink;
X          j := 0;
X          repeat
X            while tm^.id <> hcPlay do
X              tm := tm^.slink;
X            j := j + 1;
X            if j <> i then
X              tm := tm^.slink;
X          until j = i;
X          forwardTo(tm);
X          chooseAlt := true;
X        end
X      else
X        begin
X  10:
X          showAlts;
X          waitButton;
X          if passLocCur(tabRelX, tabRelY) then
X            begin
X              if passIsAlt then
X                begin
X                  selPass;
X                  chooseAlt := true;
X                  waitNoButton;
X                  exit(chooseAlt);
X                end;
X            end
X          else if bLocCur(tabRelX, tabRelY, bx, by, xs, ys) then
X            if board[bx][by].val = alternate then
X              begin
X                selAlt(bx, by);
X                chooseAlt := true;
X                waitNoButton;
X                exit(chooseAlt);
X              end;
X          remAlts;
X          beep(error);
X        end;
X      waitNoButton;
X    end { chooseAlt };
X
X    procedure mForward;
X    var
X      gbg: boolean;
X    begin { mForward }
X      if gameOver then
X        restoreDead;
X      if atLeaf(curMove) then
X        beep(error)
X      else if atBranch(curMove) then
X        gbg := chooseAlt
X      else
X        forwardTo(curMove^.flink);
X    end { mForward };
X
X    procedure doBkToS;
X    var
X      bx, by, sx, sy: integer;
X    begin { doBkToS }
X      prompt('Point at stone to backup to');
X      waitButton;
X      if bLocCur(tabRelX, tabRelY, bx, by, xs, ys) then
X        if board[bx][by].val <> empty then
X          begin
X            while not lastPlayAt(bx, by) do
X              backup1;
X            exit(doBkToS);
X          end;
X      beep(error);
X      waitNoButton;
X    end { doBkToS };
X
X    procedure doPutTag;
X    var
X      ts: tagStr;
X      cm: pMRec;
X    begin { doPutTag }
X      if curMove = treeRoot then
X        beep(error)
X      else
X        begin
X          IOKeyClear;
X          streamKeyboardReset(input);
X          prompt('Tag String: ');
X          if not getLine(ts) then
X            exit(doPutTag);
X          if length(ts) > maxTagLen then
X            begin
X              beep(error);
X              prompt('Tags may be no longer than ');
X              write(maxTagLen:0, ' characters');
X            end
X          else if length(ts) = 0 then
X            begin
X              if curMove^.tag = nil then
X                begin
X                  beep(error);
X                  prompt('');
X                end
X              else
X                begin
X                  delTag(curMove^.tag);
X                  prompt('Tag Deleted');
X                end;
X            end
X          else if tagExists(ts) then
X            begin
X              beep(error);
X              prompt('That tag already exists');
X            end
X          else
X            begin
X              tagMove(curMove, ts);
X            end;
X        end;
X    end { doPutTag };
X
X    procedure doGoToTag;
X    var
X      thisTag: tagPtr;
X    begin { doGoToTag }
X      thisTag := getTagMenu;
X      if thisTag <> nil then  
X        switchBranch(thisTag^.mPtr);
X    end { doGoToTag };
X
X    procedure doPutCmt;
X    var
X      cs, curCmt: string;
X    begin { doPutCmt }
X      IOKeyClear;
X      streamKeyboardReset(input);
X      prompt('Comment: ');
X      if not getLine(cs) then
X        exit(doPutCmt);
X      if length(cs) = 0 then
X        if getComment(curMove, curCmt) then
X          prompt('Comment Deleted')
X        else
X          begin
X            beep(error);
X            prompt('');
X          end;
X      commentMove(curMove, cs);
X    end { doPutCmt };
X
X    procedure doScore;
X    var
X      wScore, bScore, wr, br: integer;
X      done: boolean;
X      bx, by, xs, ys: integer;
X    begin { doScore }
X      putEnd;
X      done := false;
X      prompt('Point at dead groups, Press outside of board to stop');
X      repeat
X        waitButton;
X        if bLocCur(tabRelX, tabRelY, bx, by, xs, ys) then
X          begin
X            if board[bx, by].val <> empty then
X              delGroup(bx, by);
X          end
X        else
X          done := true;
X        showCaptures;
X        waitNoButton;
X      until done;
X      prompt('Counting Score ...');
X      scoreGame(wScore, bScore);
X      wScore := wScore - captures[black];
X      bScore := bScore - captures[white];
X      if wScore < 0 then
X        begin
X          wr := -wScore;
X          wScore := 0;
X        end
X      else
X        wr := 0;
X      if bScore < 0 then
X        begin
X          br := -bScore;
X          bScore := 0;
X        end
X      else
X        br := 0;
X      bScore := bScore + wr;
X      wScore := wScore + br;
X      prompt('Score is: ');
X      write('White = ', wScore:0, ', Black = ', bScore:0);
X      if wScore = bScore then
X        write(' - A Tie!')
X      else if wScore > bScore then
X        write(' - White Wins by ', (wScore - bScore):0)
X      else
X        write(' - Black Wins by ', (bScore - wScore):0)
X    end { doScore };
X
X    procedure doEraseMove;
X    var
X      lm: pMRec;
X    begin { doEraseMove }
X      if gameOver then
X        restoreDead;
X      if curMove = treeRoot then
X        beep(error)
X      else
X        begin
X          lm := curMove;
X          backup1;
X          lm := delBranch(lm);
X          treeDirty := true;
X        end;
X    end { doEraseMove };
X
X    procedure doPruneBranches;
X    var
X      lm, sm, tm: pMRec;
X      tp: tagPtr;
X      didPrune: boolean;
X    begin { doPruneBranches }
X      if gameOver then
X        restoreDead;
X      if not isBranch(curMove) then
X        beep(error)
X      else if not confirmed then
X        beep(error)
X      else
X        begin
X          didPrune := false;
X          wipeTreeMarks;
X          lm := curMove;
X          while lm <> treeRoot do
X            begin
X              lm^.mark := true;
X              lm := lm^.blink;
X            end;
X          tp := treeRoot^.lastTag;
X          while tp <> nil do
X            begin
X              lm := tp^.mPtr;
X              while lm <> treeRoot do
X                begin
X                  lm^.mark := true;
X                  lm := lm^.blink;
X                end;
X              tp := tp^.nextTag;
X            end;
X          lm := curMove;
X          while lm <> treeRoot do
X            begin
X              if lm^.blink^.flink^.slink <> nil then
X                begin
X                  sm := lm^.blink^.flink;
X                  while sm <> nil do
X                    if not sm^.mark then
X                      begin
X                        tm := sm;
X                        sm := sm^.slink;
X                        tm := delBranch(tm);
X                        didPrune := true;
X                        treeDirty := true;
X                      end
X                    else
X                      sm := sm^.slink;
X                end;
X              lm := lm^.blink;
X            end;
X          if not didPrune then
X            prompt('All Branches Were Tagged');
X        end;
X    end { doPruneBranches };
X
X    handler ctlC;
X    begin { ctlC }
X      IOKeyClear;
X      CtlCseen := true;
X    end { ctlC }; 
X
X  begin { doit }
X    resetGame;
X    done := false;
X    lastMove := nil;
X    CtlCseen := false;
X    playMyself := false;
X    lastWasPass := false;
X    IOSetModeTablet(relTablet);
X    IOCursorMode(trackCursor);
X    activate(mReadFile, true);
X    activate(mTogNums, true);
X    activate(mQuit, true);
X    activate(mPutCmt, true);
X    activate(mAutoPlay, true);
X    activate(mPlayMyself, true);
X    activate(mSetPlayLevel, true);
X    activate(mDebug, true);
X    activate(mRefBoard, true);
X    activate(mShoState, true);
X    activate(mBoardSize, true);
X    repeat
X      if curMove <> lastMove then
X        checkAtari(curMove);
X      updateStatus;
X      lastMove := curMove;
X      if not playMyself then
X        begin
X          activate(mPrintBoard, curMove <> treeRoot);
X          activate(mPrintDiag, curMove <> treeRoot);
X          activate(mStepToTag, stepTagPossible);
X          activate(mSetStepTag, treeRoot^.lastTag <> nil);
X          activate(mGotoTag, treeRoot^.lastTag <> nil);
X          activate(mInit, treeRoot^.flink <> nil);
X          activate(mWriteFile, treeRoot^.flink <> nil);
X          activate(mSetHc, curMove = treeRoot);
X          activate(mPass, curMove <> treeRoot);
X          activate(mScore, curMove <> treeRoot);
X          activate(mForToBr, hasBranch(curMove));
X          activate(mBackToBr, isBranch(curMove));
X          activate(mBackToStone, curMove <> treeRoot);
X          activate(mForToLeaf, curMove^.flink <> nil);
X          activate(mPutTag, curMove <> treeRoot);
X          activate(mGotoRoot, curMove <> treeRoot);
X          activate(mEraseMove, curMove <> treeRoot);
X          activate(mPruneBranches, isBranch(curMove));
X          activate(mBackOne, curMove <> treeRoot);
X          activate(mForOne, curMove^.flink <> nil);
X        end;
X      if CtlCseen then
X        cmd := mCtlC
X      else if playMyself then
X        cmd := mAutoPlay
X      else
X        repeat
X          cmd := getMenuCmd;
X        until cmd <> none;
X      prompt('');
X      case cmd of
X        mCtlC:
X          begin
X            playMyself := false;
X            CtlCseen := false;
X          end;
X        mPlaceStone:
X          begin
X            if gameOver then
X              restoreDead;
X            if bLocCur(tabRelX, tabRelY, xi, yi, xs, ys) then
X              begin
X                if board[xi, yi].val <> empty then
X                  beep(error)
X                else if (xi = koX) and (yi = koY) then
X                  beep(koV)
X                else
X                  doMove(whoseTurn, xi, yi, xs, ys);
X              end
X            else
X              beep(error);
X            waitNoButton;
X          end;
X        mAutoPlay:
X          begin
X            if gameOver then
X              restoreDead;
X            prompt('Thinking...');
X            if curMove = treeRoot then
X              lastWasPass := false
X            else
X              lastWasPass := curMove^.id = pass;
X            if playMove(whoseTurn, xi, yi) then
X              begin
X                if board[xi, yi].val <> empty then
X                  begin
X                    beep(error);
X                    prompt('Bad move at ');
X                    write((xi + 1):0, ', ', (yi + 1):0);
X                    playMyself := false;
X                    write(' - Generated by ', playreason);
X                  end
X                else if (xi = koX) and (yi = koY) then
X                  begin
X                    beep(koV);
X                    prompt('ko violation at ');
X                    write((xi + 1):0, ', ', (yi + 1):0);
X                    write(' - Generated by ', playreason);
X                    playMyself := false;
X                  end
X                else
X                  begin
X                    doMove(whoseTurn, xi, yi, 0, 0);
X                    if board[xi, yi].val = empty then
X                      begin
X                        prompt('self kill at ');
X                        write((xi + 1):0, ', ', (yi + 1):0);
X                        write(' - Generated by ', playreason);
X                        playMyself := false;
X                      end
X                    else
X                      commentMove(curMove, playReason);
X                  end;
X              end
X            else
X              begin
X                doPass(whoseTurn);
X                if lastWasPass then
X                  playMyself := false;
X              end;
X            waitNoButton;
X            prompt('');
X          end;
X        mPlayMyself:
X          playMyself := true;
X        mSetPlayLevel:
X          menuPlayLevel(playLevel, maxPlayLevel);
X        mShoState:
X          showPlayState(whoseTurn);
X        mInit:
X          if confirmed then
X            begin
X              makeGoTree;
X              resetGame;
X              treeDirty := false;
X            end
X          else
X            beep(error);
X        mSetHc:
X          if moveNum = 0 then
X            begin
X              if gameOver then
X                restoreDead;
X              numHC := getHCMenu;
X              if numHC > 0 then
X                doHCPlay(numHC)
X              else
X                beep(error);
X            end
X          else
X            beep(error);
X        mPass:
X          begin
X            if gameOver then
X              restoreDead;
X            doPass(whoseTurn);
X          end;
X        mScore:
X          doScore;
X        mForToBr:
X          begin
X            if gameOver then
X              restoreDead;
X            if atLeaf(curMove) then
X              beep(error)
X            else if not atBranch(curMove) then
X               forwToBr;
X            if not atLeaf(curMove) then
X              gbg := chooseAlt;
X          end;
X        mBackToBr:
X          begin
X            if gameOver then
X              restoreDead;
X            if curMove = treeRoot then
X              beep(error)
X            else
X              backToBr;
X            if atBranch(curMove) then
X              gbg := chooseAlt;
X          end;
X        mBackToStone:
X          begin
X            if gameOver then
X              restoreDead;
X            if curMove = treeRoot then
X              beep(error)
X            else
X              doBkToS;
X          end;
X        mForToLeaf:
X          begin
X            if gameOver then
X              restoreDead;
X            if atLeaf(curMove) then
X              beep(error)
X            else
X              begin
X                endLoop := false;
X                repeat
X                  if atLeaf(curMove) then
X                    endLoop := true
X                  else if atBranch(curMove) then
X                    begin
X                      if not chooseAlt then
X                        begin
X                          endLoop := true;
X                          beep(error);
X                        end;
X                    end
X                  else
X                    forwToBr;                    
X                until endLoop;
X              end;
X          end;
X        mPutTag:
X          doPutTag;
X        mGotoTag:
X          doGoToTag;
X        mGotoRoot:
X          switchBranch(treeRoot);
X        mPutCmt:
X          doPutCmt;
X        mReadFile:
X          if confirmed then
X            doReadGame;
X        mWriteFile:
X          doWriteGame;
X        mEraseMove:
X          doEraseMove;
X        mPruneBranches:
X          doPruneBranches;
X        mTogNums:
X          if not numbEnabled then
X            begin
X              numbEnabled := true;
X              showAllStones;
X              dotSX := -1;
X              putMString(mTogNums, 'Erase Numbers');
X            end
X          else
X            begin
X              numbEnabled := false;
X              showAllStones;
X              dotSX := -1;
X              dotLast;
X              putMString(mTogNums, 'Show Stone Numbers');
X            end;
X        mDebug:
X          if debug then
X            begin
X              debug := false;
X              putMString(mDebug, 'Turn Debug On');
X            end
X          else
X            begin
X              debug := true;
X              putMString(mDebug, 'Turn Debug Off');
X            end;
X        mBoardSize:
X          begin
X            printLarge := not printLarge;
X            if printLarge then
X              begin
X                prompt('Will Print on Large Board Now');
X                putMString(mBoardSize, 'Use Small Board');
X              end
X            else
X              begin
X                prompt('Will Print on Small Board Now');
X                putMString(mBoardSize, 'Use Large Board');
X              end;
X          end;
X        mPrintBoard:
X          printBoard(false);
X        mPrintDiag:
X          printBoard(true);
X        mStepToTag:
X          begin
X            if gameOver then
X              restoreDead;
X            if stepTag = nil then
X              stepTag := getTagMenu;
X            if stepTag <> nil then
X              doStepTag
X            else
X              beep(error);
X          end;
X        mSetStepTag:
X          begin
X            thisTag := getTagMenu;
X            if thisTag <> nil then
X              stepTag := thisTag;
X          end;
X        mQuit:
X          if confirmed then
X            done := true;
X        mBackOne:
X          begin
X            if gameOver then
X              restoreDead
X            else if curMove = treeRoot then
X              beep(error)
X            else
X              backUp1;
X          end;
X        mForOne:
X          begin
X            if gameOver then
X              restoreDead;
X            mForward;
X          end;
X        mRefBoard:
X          refreshBoard;
X      end { case };
X      if not playMyself then
X        endCmd;
X    until done;
X  end { doit };
X
X  procedure cleanup;
X  begin { cleanup }
X    screenReset;
X    rasterOp(rRpl, 768, 1024, 0, 0, SScreenW, SScreenP,
X                              0, 0, SScreenW, oScreenPtr);
X    SSetCursor(oCurPosX, oCurPosY);
X  end { cleanup };
X
X  handler ctlC;
X  begin { ctlC }
X    IOKeyClear; 
X  end { ctlC };
X 
Xbegin { Go } 
X  initialize;
X  doit;
X99:
X  cleanUp;
Xend { Go }.
END_OF_go.pas
if test 26299 -ne `wc -c <go.pas`; then
    echo shar: \"go.pas\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f goMgr.pas -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"goMgr.pas\"
else
echo shar: Extracting \"goMgr.pas\" \(20985 characters\)
sed "s/^X//" >goMgr.pas <<'END_OF_goMgr.pas'
X{---------------------------------------------------------------}
X{ GoMgr.Pas                                                     }
X{                                                               }
X{ Go Game Manager                                               }
X{ Copyright (c) 1982 by Three Rivers Computer Corp.             }
X{                                                               }
X{ Written: June 3, 1982 by Stoney Ballard                       }
X{ Edit History:                                                 }
X{    June  3, 1982  Started                                     }
X{    June  4, 1982  Add dead group removal                      }
X{    June 10, 1982  Use new go file manager                     }
X{    Nov   9, 1982  Extracted from GO.PAS                       }
X{---------------------------------------------------------------}
X
Xmodule goMgr;
X
Xexports
X
Ximports goCom from goCom;
Ximports goTree from goTree;
X
Xvar
X  curMove: pMRec;
X  gameOver: boolean;
X  passIsAlt: boolean;
X
Xprocedure initGoMgr;
Xprocedure backUp1;
Xprocedure doMove(which: sType; ix, iy, pox, poy: integer);
Xprocedure doPass(which: sType);
Xprocedure doHCPlay(num: integer);
Xprocedure forwardTo(m: pMRec);
Xprocedure forwToBr;
Xprocedure backToBr;
Xprocedure showAlts;
Xprocedure remAlts;
Xprocedure selAlt(lx, ly: integer);
Xprocedure selPass;
Xfunction atBranch(cm: pMRec): boolean;
Xfunction atLeaf(cm: pMRec): boolean;
Xprocedure checkAtari(cm: pMRec);
Xprocedure switchBranch(bm: pMRec);
Xprocedure scoreGame(var ws, bs: integer);
Xprocedure putEnd;
Xprocedure delGroup(bx, by: integer);
Xprocedure restoreDead;
Xprocedure dotLast;
Xfunction lastPlayAt(bx, by: integer): boolean;
Xprocedure doStepTag;
Xfunction stepTagPossible: boolean;
Xprocedure wipeTreeMarks;
X
Xprivate
X
Ximports goBoard from goBoard;
Ximports goMenu from goMenu;
Ximports screen from screen;
X
Xtype
X  deadRec = record
X              dx, dy, dox, doy, mn: integer;
X              whoDead: sType;
X            end;
X
Xvar
X  killX, killY: integer;
X  endDead: array[1..361] of deadRec;
X  numEndDead: integer;
X
Xprocedure wipeMarks;
Xvar
X  i, j: integer;
Xbegin { wipeMarks }
X  for i := 0 to maxPoint do
X    for j := 0 to maxPoint do
X      board[i, j].marked := false;
Xend { wipeMarks };
X
Xprocedure wipeTreeMarks;
X
X  procedure recWipe(m: pMRec);
X  begin { recWipe }
X    while m <> nil do
X      begin
X        recWipe(m^.slink);
X        m^.mark := false;
X        m := m^.flink;
X      end;
X  end { recWipe };
X
Xbegin { wipeTreeMarks }
X  treeRoot^.mark := false;
X  if treeRoot^.flink <> nil then
X    recWipe(treeRoot^.flink);
Xend { wipeTreeMarks };
X
Xprocedure spanGroup(s: sType; xi, yi: integer; var libs, size: integer);
Xbegin { spanGroup }
X  if (xi >= 0) and (xi <= maxPoint) and
X     (yi >= 0) and (yi <= maxPoint) then
X    with board[xi, yi] do
X      if not marked then
X        if val = empty then
X          begin
X            libs := libs + 1;
X            marked := true;
X          end
X        else if val = s then
X          begin
X            marked := true;
X            size := size + 1;
X            spanGroup(s, xi - 1, yi, libs, size);
X            spanGroup(s, xi + 1, yi, libs, size);
X            spanGroup(s, xi, yi - 1, libs, size);
X            spanGroup(s, xi, yi + 1, libs, size);
X          end;
Xend { spanGroup };
X
Xfunction libertyCount(xi, yi: integer): integer;
Xvar
X  libs, size: integer;
Xbegin { libertyCount }
X  wipeMarks;
X  libs := 0; 
X  size := 0;
X  spanGroup(board[xi, yi].val, xi, yi, libs, size);
X  libertyCount := libs;
Xend { libertyCount };
X
Xfunction groupSize(xi, yi: integer): integer;
Xvar
X  gbg, size: integer;
Xbegin { groupSize }
X  wipeMarks;
X  size := 0;
X  gbg := 0;
X  spanGroup(board[xi, yi].val, xi, yi, gbg, size); 
X  groupSize := size;
Xend { groupSize };
X
Xprocedure killGroup(s: sType; xi, yi: integer);
Xbegin { killGroup }
X  if (xi >= 0) and (xi <= maxPoint) and
X     (yi >= 0) and (yi <= maxPoint) then
X    with board[xi, yi] do
X      if val = s then
X        begin
X          remStone(xi, yi);
X          curMove := newMove(curMove);
X          with curMove^ do
X            begin
X              mx := xi;
X              my := yi;
X              ox := board[xi, yi].xOfs;
X              oy := board[xi, yi].yOfs;
X              moveN := board[xi, yi].mNum;
X              who := s;
X              id := remove;
X            end;
X          curMove := mergeMove(curMove);
X          killGroup(s, xi - 1, yi);
X          killGroup(s, xi + 1, yi);
X          killGroup(s, xi, yi - 1);
X          killGroup(s, xi, yi + 1);
X        end;
Xend { killGroup };
X
Xprocedure remDead(xi, yi: integer; var numDead: integer);
Xvar
X  i, j, libs, size: integer;
X  s, other: bVal;
X
Xbegin { remDead }
X  numDead := 0;
X  s := board[xi, yi].val;
X  if s = white then
X    other := black
X  else
X    other := white;
X  if xi > 0 then
X    if (board[xi - 1, yi].val = other) then
X      begin
X        wipeMarks;
X        libs := 0;
X        size := 0;
X        spanGroup(other, xi - 1, yi, libs, size);
X        if libs = 0 then
X          begin
X            killGroup(other, xi - 1, yi);
X            numDead := numDead + size;
X            killX := xi - 1;
X            killY := yi;
X          end;
X      end;
X  if xi < maxPoint then
X    if (board[xi + 1, yi].val = other) then
X      begin
X        wipeMarks;
X        libs := 0;
X        size := 0;
X        spanGroup(other, xi + 1, yi, libs, size);
X        if libs = 0 then
X          begin
X            killGroup(other, xi + 1, yi);
X            numDead := numDead + size;
X            killX := xi + 1;
X            killY := yi;
X          end;
X      end;
X  if yi > 0 then 
X    if (board[xi, yi - 1].val = other) then
X      begin
X        wipeMarks;
X        libs := 0;
X        size := 0;
X        spanGroup(other, xi, yi - 1, libs, size);
X        if libs = 0 then
X          begin
X            killGroup(other, xi, yi - 1);
X            numDead := numDead + size;
X            killX := xi;
X            killY := yi - 1;
X          end;
X      end;
X  if yi < maxPoint then
X    if (board[xi, yi + 1].val = other) then
X      begin
X        wipeMarks;
X        libs := 0;
X        size := 0;
X        spanGroup(other, xi, yi + 1, libs, size);
X        if libs = 0 then
X          begin
X            killGroup(other, xi, yi + 1);
X            numDead := numDead + size;
X            killX := xi;
X            killY := yi + 1;
X          end;
X      end;
X  if numDead > 0 then
X    beep(die);
Xend { remDead };
X
Xfunction lastPlayAt(bx, by: integer): boolean;
Xvar
X  tm: pMRec;
Xbegin { lastPlayAt }
X  lastPlayAt := false;
X  tm := curMove;
X  while tm <> treeRoot do
X    with tm^ do
X      if id = move then
X        begin
X          lastPlayAt := (mx = bx) and (my = by);
X          exit(lastPlayAt);
X        end
X      else if id = pass then
X        exit(lastPlayAt)
X      else if id = hcPlay then
X        exit(lastPlayAt)
X      else
X        tm := tm^.blink;
Xend { lastPlayAt };
X
Xprocedure findAtari(xi, yi: integer);
Xvar
X  i, j, libs, num, size: integer;
X  s, other: bVal;
Xbegin { findAtari }
X  size := 0;
X  s := board[xi, yi].val;
X  if s = white then
X    other := black
X  else
X    other := white;
X  wipeMarks;
X  libs := 0;
X  spanGroup(s, xi, yi, libs, size);
X  if libs = 1 then
X    begin
X      beep(atari);
X      exit(findAtari);
X    end;
X  if xi > 0 then
X    if (board[xi - 1, yi].val = other) and
X       (not board[xi - 1, yi].marked) then
X      begin
X        wipeMarks;
X        libs := 0;
X        spanGroup(other, xi - 1, yi, libs, size);
X        if libs = 1 then
X          begin
X            beep(atari);
X            exit(findAtari);
X          end;
X      end;
X  if xi < maxPoint then
X    if (board[xi + 1, yi].val = other) and
X       (not board[xi + 1, yi].marked) then
X      begin
X        wipeMarks;
X        libs := 0;
X        spanGroup(other, xi + 1, yi, libs, size);
X        if libs = 1 then
X          begin
X            beep(atari);
X            exit(findAtari);
X          end;
X      end;
X  if yi > 0 then 
X    if (board[xi, yi - 1].val = other) and
X       (not board[xi, yi - 1].marked) then
X      begin
X        wipeMarks;
X        libs := 0;
X        spanGroup(other, xi, yi - 1, libs, size);
X        if libs = 1 then
X          begin
X            beep(atari);
X            exit(findAtari);
X          end;
X      end;
X  if yi < maxPoint then
X    if (board[xi, yi + 1].val = other) and
X       (not board[xi, yi + 1].marked) then
X      begin
X        wipeMarks;
X        libs := 0;
X        spanGroup(other, xi, yi + 1, libs, size);
X        if libs = 1 then
X          beep(atari);
X      end;
Xend { findAtari };
X
Xprocedure checkAtari(cm: pMRec);
Xbegin { checkAtari }
X  if cm <> treeRoot then
X    if cm^.id <> hcPlay then
X      if cm^.id <> pass then
X        begin
X          while cm^.id = remove do
X            cm := cm^.blink;
X          with cm^ do
X            findAtari(mx, my);
X      end;
Xend { checkAtari };
X
Xprocedure restoreDead;
Xvar
X  i: integer;
X  other: sType;
Xbegin { restoreDead }
X  for i := 1 to numEndDead do
X    with endDead[i] do
X      begin
X        placeStone(whoDead, dx, dy, dox, doy, mn);
X        if whoDead = white then
X          other := black
X        else
X          other := white;
X        captures[other] := captures[other] - 1;
X      end;
X  numEndDead := 0;
X  gameOver := false;
Xend { restoreDead };
X
Xprocedure backUp1;
Xvar
X  moveT: mType;
X  prevMove, tm: pMRec;
Xbegin { backUp1 }
X  if dotSX >= 0 then
X    begin
X      dotStone(dotSX, dotSY);
X      dotSX := -1;
X    end;
X  if gameOver then
X    restoreDead;
X  if curMove <> treeRoot then
X    repeat
X      with curMove^ do
X        begin
X          prevMove := blink;
X          moveT := id;
X          if id = move then
X            remStone(mx, my)
X          else if id = remove then
X            begin 
X              placeStone(who, mx, my, ox, oy, moveN);
X              if who = black then
X                captures[white] := captures[white] - 1
X              else
X                captures[black] := captures[black] - 1;
X            end
X          else if id = pass then
X            remPass
X          else { hcPlay }
X            clearBoard;
X        end;
X      curMove := prevMove;
X   until (curMove = treeRoot) or (moveT = move) or (moveT = pass); 
X   if curMove = treeRoot then
X     begin
X       koX := -1;
X       koY := -1;
X       moveNum := 0;
X     end
X   else if curMove^.id = move then
X     with curMove^ do
X       begin
X         koX := kx;
X         koY := ky;
X         moveNum := moveN;
X       end
X   else if curMove^.id = pass then
X     with curMove^ do
X       begin
X         koX := -1;
X         koY := -1;
X         moveNum := moveN;
X         showPass(who);
X       end
X   else if curMove^.id = hcPlay then
X     begin
X       koX := -1;
X       koY := -1;
X       moveNum := 1;
X     end
X   else
X     begin
X       tm := curMove^.blink;
X       while tm^.id <> move do
X         tm := tm^.blink;
X       with tm^ do
X         begin
X           koX := kx;
X           koY := ky;
X           moveNum := moveN;
X         end;
X     end;
Xend { backUp1 };
X
Xprocedure doMove(which: sType; ix, iy, pox, poy: integer);
Xvar
X  numDead: integer;
X  cm: pMRec;
Xbegin { doMove }
X  if dotSX >= 0 then
X    begin
X      dotStone(dotSX, dotSY);
X      dotSX := -1;
X    end;
X  if gameOver then
X    restoreDead;
X  curMove := newMove(curMove);
X  moveNum := moveNum + 1;
X  with curMove^ do
X    begin
X      mx := ix;
X      my := iy;
X      ox := pox;
X      oy := poy;
X      kx := koX;
X      ky := koY;
X      who := which;
X      id := move;
X      moveN := moveNum;
X    end;
X  curMove := mergeMove(curMove);
X  cm := curMove;
X  placeStone(which, ix, iy, pox, poy, moveNum);
X  remDead(ix, iy, numDead);
X  if libertyCount(ix, iy) < 1 then
X    begin
X      curMove := delBranch(curMove);
X      moveNum := moveNum + 1;
X      remStone(ix, iy);
X      beep(error);
X    end
X  else
X    begin
X      captures[which] := captures[which] + numDead;
X      if (numDead = 1) and (groupSize(ix, iy) = 1) then
X        begin
X          koX := killX;
X          koY := killY;
X        end
X      else
X        begin
X          koX := -1;
X          koY := -1;
X        end;  
X      with cm^ do
X        begin
X          kx := koX;
X          ky := koY;
X        end;
X    end;
Xend { doMove };
X
Xprocedure doPass(which: sType);
Xbegin { doPass }
X  if dotSX >= 0 then
X    begin
X      dotStone(dotSX, dotSY);
X      dotSX := -1;
X    end;
X  if gameOver then
X    restoreDead;
X  curMove := newMove(curMove);
X  moveNum := moveNum + 1;
X  with curMove^ do
X    begin
X      who := which;
X      id := pass;
X      moveN := moveNum;
X    end;
X  curMove := mergeMove(curMove);
X  showPass(which);
Xend { doPass };
X
Xprocedure doHCPlay(num: integer);
Xbegin { doHCPlay }
X  moveNum := 1;
X  curMove := newMove(treeRoot);
X  with curMove^ do
X    begin
X      who := black;
X      id := hcPlay;
X      hcNum := num;
X    end;
X  addHCStones(num);
Xend { doHCPlay };
X
Xprocedure forwardTo(m: pMRec);
Xbegin { forwardTo }
X  if dotSX >= 0 then
X    begin
X      dotStone(dotSX, dotSY);
X      dotSX := -1;
X    end;
X  curMove := m;
X  if passShowing then
X    remPass;
X  with curMove^ do
X    if id = hcPlay then
X      begin
X        addHCStones(hcNum);
X        moveNum := 1;
X      end
X    else if id = pass then
X      begin
X        moveNum := moveN;
X        koX := -1;
X        koY := -1;
X        showPass(who);
X      end
X    else
X      begin
X        moveNum := moveN;
X        placeStone(who, mx, my, ox, oy, moveNum);
X        koX := kx;
X        koY := ky;
X        while curMove^.flink <> nil do
X          if curMove^.flink^.id = remove then
X            begin
X              curMove := curMove^.flink;
X              with curMove^ do
X                remStone(mx, my);
X              if curMove^.who = white then
X                captures[black] := captures[black] + 1
X              else
X                captures[white] := captures[white] + 1
X            end
X          else
X            exit(forwardTo);
X      end;
Xend { forwardTo };
X
Xprocedure forwToBr;
Xvar
X  atBr: boolean;
Xbegin { forwToBr }
X  if dotSX >= 0 then
X    begin
X      dotStone(dotSX, dotSY);
X      dotSX := -1;
X    end;
X  atBr := false;
X  repeat
X    if curMove^.flink = nil then
X      atBr := true
X    else if curMove^.flink^.slink <> nil then
X      atBr := true
X    else
X      forwardTo(curMove^.flink);
X  until atBr;
Xend { forwToBr };
X
Xprocedure backToBr;
Xvar
X  na: integer;
X  tm: pMRec;
X  endLoop: boolean;
Xbegin { backToBr }
X  if dotSX >= 0 then
X    begin
X      dotStone(dotSX, dotSY);
X      dotSX := -1;
X    end;
X  if curMove <> treeRoot then
X    begin
X      if not hasAlts(curMove) then
X        repeat
X          backUp1;
X          if curMove = treeRoot then
X            endLoop := true
X          else
X            endLoop := hasAlts(curMove);
X        until endLoop;
X      if curMove <> treeRoot then
X        backUp1;
X    end
X  else
X    beep(error);
Xend { backToBr };
X
Xfunction atBranch(cm: pMRec): boolean;
Xbegin { atBranch }
X  if cm^.flink <> nil then
X    atBranch := cm^.flink^.slink <> nil
X  else
X    atBranch := false;
Xend { atBranch };
X
Xfunction atLeaf(cm: pMRec): boolean;
Xbegin { atLeaf }
X  atLeaf := cm^.flink = nil;
Xend { atLeaf };
X
Xprocedure showAlts;
Xvar
X  tm: pMRec;
Xbegin { showAlts }
X  setMenuCursor;
X  tm := curMove^.flink;
X  passIsAlt := false;
X  while tm <> nil do
X    begin
X      with tm^ do
X        begin
X          if id = move then
X            placeAlt(who, mx, my, ox, oy)
X          else if id = pass then
X            begin
X              SChrFunc(ord(rNot));
X              showPass(who);
X              SChrFunc(ord(rRpl));
X              passIsAlt := true;
X            end;
X          tm := tm^.slink;
X        end;
X    end;
Xend { showAlts };
X
Xprocedure remAlts;
Xvar
X  tm: pMRec;
Xbegin { remAlts }
X  tm := curMove^.flink;
X  while tm <> nil do
X    begin
X      with tm^ do
X        begin
X          if id = move then
X            remStone(mx, my)
X          else if id = pass then
X            remPass;
X          tm := tm^.slink;
X        end;
X    end;
Xend { remAlts };
X
Xprocedure selAlt(lx, ly: integer);
Xbegin { selAlt }
X  remAlts;
X  curMove := curMove^.flink;
X  repeat
X    while curMove^.id <> move do
X      curMove := curMove^.slink;
X    if (curMove^.mx = lx) and (curMove^.my = ly) then
X      begin
X        forwardTo(curMove);
X        exit(selAlt);
X      end
X    else
X      curMove := curMove^.slink;
X  until false;
Xend { selAlt };
X
Xprocedure selPass;
Xbegin { selPass }
X  remAlts;
X  curMove := curMove^.flink;
X  while curMove^.id <> pass do
X    curMove := curMove^.slink;
X  forwardTo(curMove);
Xend { selPass };
X
Xprocedure switchBranch(bm: pMRec);
Xvar
X  tm: pMRec;
Xbegin { switchBranch }
X  if dotSX >= 0 then
X    begin
X      dotStone(dotSX, dotSY);
X      dotSX := -1;
X    end;
X  if gameOver then
X    restoreDead;
X  wipeTreeMarks;
X  tm := bm;
X  while tm <> treeRoot do
X    begin
X      tm^.mark := true;
X      tm := tm^.blink;
X    end;
X  treeRoot^.mark := true;
X  while not curMove^.mark do
X    backup1;
X  while curMove <> bm do
X    begin
X      tm := curMove^.flink;
X      while not tm^.mark do
X        tm := tm^.slink;
X      forwardTo(tm);
X    end;
Xend { switchBranch };
X
Xfunction stepTagPossible: boolean;
Xbegin { stepTagPossible }
X  if treeRoot^.lastTag = nil then
X    stepTagPossible := false
X  else if stepTag = nil then
X    stepTagPossible := true
X  else if curMove = treeRoot then
X    stepTagPossible := true
X  else if curMove^.tag = stepTag then
X    stepTagPossible := false
X  else
X    stepTagPossible := true;
Xend { stepTagPossible };
X
Xprocedure doStepTag;
Xvar
X  tm: pMRec;
Xbegin { doStepTag }
X  if stepTag = nil then
X    exit(doStepTag);
X  if dotSX >= 0 then
X    begin
X      dotStone(dotSX, dotSY);
X      dotSX := -1;
X    end;
X  if gameOver then
X    restoreDead;
X  tm := stepTag^.mPtr;
X  if curMove = tm then
X    exit(doStepTag);
X  wipeTreeMarks;
X  while tm <> treeRoot do
X    begin
X      tm^.mark := true;
X      tm := tm^.blink;
X    end;
X  treeRoot^.mark := true;
X  if not curMove^.mark then
X    begin
X      prompt('Backed up to proper branch');
X      repeat
X        backup1;
X      until curMove^.mark;
X    end
X  else 
X    begin
X      tm := curMove^.flink;
X      while not tm^.mark do
X        tm := tm^.slink;
X      forwardTo(tm);
X    end;
Xend { doStepTag };
X
Xprocedure scoreGame(var ws, bs: integer);
Xvar
X  i, j, size: integer;
X  bSeen, wSeen: boolean;
X
X  procedure spanEmpties(bx, by: integer);
X  begin { spanEmpties }
X    if (bx >= 0) and (bx <= maxPoint) and
X       (by >= 0) and (by <= maxPoint) then
X      begin
X        if board[bx, by].val = white then
X          wSeen := true
X        else if board[bx, by].val = black then
X          bSeen := true
X        else if not board[bx, by].marked then
X          begin
X            board[bx, by].marked := true;
X            size := size + 1;
X            spanEmpties(bx - 1, by);
X            spanEmpties(bx + 1, by);
X            spanEmpties(bx, by - 1);
X            spanEmpties(bx, by + 1);
X          end;
X      end;
X  end { spanEmpties };
X
Xbegin { scoreGame }
X  ws := 0;
X  bs := 0;
X  wipeMarks;
X  for j := 0 to maxPoint do
X    for i := 0 to maxPoint do
X      if (not board[i, j].marked) and
X         (board[i, j].val = empty) then
X        begin
X          bSeen := false;
X          wSeen := false;
X          size := 0;
X          spanEmpties(i, j);
X          if bSeen and not wSeen then
X            bs := bs + size
X          else if wSeen and not bSeen then
X            ws := ws + size;
X        end;
Xend { scoreGame };
X
Xprocedure putEnd;
Xbegin { putEnd }
X  if not gameOver then
X    begin
X      gameOver := true;
X      numEndDead := 0;
X    end;
Xend { putEnd };
X
Xprocedure delGroup(bx, by: integer);
Xvar
X  sto, other: sType;
X  size: integer;
X
X  procedure dumpDead(bx, by: integer);
X  begin { dumpDead }
X    if (bx >= 0) and (bx <= maxPoint) and
X       (by >= 0) and (by <= maxPoint) then
X      if board[bx, by].val = sto then
X        begin
X          remStone(bx, by);
X          numEndDead := numEndDead + 1;
X          with endDead[numEndDead] do
X            begin
X              dx := bx;
X              dy := by;
X              with board[bx, by] do
X                begin
X                  dox := xOfs;
X                  doy := yOfs;
X                  mn := mNum;
X                end;
X              whoDead := sto;
X            end;
X          size := size + 1;
X          dumpDead(bx - 1, by);
X          dumpDead(bx + 1, by);
X          dumpDead(bx, by - 1);
X          dumpDead(bx, by + 1);
X        end;
X  end { dumpDead };
X
Xbegin { delGroup }
X  sto := board[bx, by].val;
X  size := 0;
X  dumpDead(bx, by);
X  if sto = white then
X    other := black
X  else
X    other := white;
X  captures[other] := captures[other] + size;
Xend { delGroup };
X
Xprocedure dotLast;
Xvar
X  tm: pMRec;
Xbegin { dotLast }
X  if numbEnabled then
X    exit(dotLast);
X  if dotSX >= 0 then
X    dotStone(dotSX, dotSY);
X  dotSX := -1;
X  tm := curMove;
X  while tm <> treeRoot do
X    if tm^.id = pass then
X      exit(dotLast)
X    else if tm^.id = move then
X      with tm^ do
X        begin
X          dotSX := mx;
X          dotSY := my;
X          dotStone(mx, my);
X          exit(dotLast);
X        end
X    else
X      tm := tm^.blink;
Xend { dotLast };
X
Xprocedure initGoMgr;
Xbegin { initGoMgr }
X  moveNum := 0;
X  curMove := treeRoot;
X  gameOver := false;
X  numEndDead := 0;
X  dotSX := -1;
X  dotSY := -1;
X  passShowing := false;
Xend. { initGoMgr }
END_OF_goMgr.pas
if test 20985 -ne `wc -c <goMgr.pas`; then
    echo shar: \"goMgr.pas\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 4 \(of 5\).
cp /dev/null ark4isdone
MISSING=""
for I in 1 2 3 4 5 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 5 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