games-request@tekred.TEK.COM (03/10/88)
Submitted by: Fred Hansen <wjh+@andrew.cmu.edu>
Comp.sources.games: Volume 3, Issue 98
Archive-name: go/Part02
#! /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 2 (of 5)."
# Contents: goPlayer.pas
# Wrapped by billr@saab on Wed Mar 9 09:14:44 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f goPlayer.pas -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"goPlayer.pas\"
else
echo shar: Extracting \"goPlayer.pas\" \(58639 characters\)
sed "s/^X//" >goPlayer.pas <<'END_OF_goPlayer.pas'
X{---------------------------------------------------------------}
X{ GoPlayer.Pas }
X{ }
X{ Go Move Generator }
X{ Copyright (c) 1983 by Three Rivers Computer Corp. }
X{ }
X{ Written: January 17, 1983 by Stoney Ballard }
X{ Edit History: }
X{---------------------------------------------------------------}
X
Xmodule goPlayer;
X
Xexports
X
Ximports goCom from goCom;
X
X{ returns true if a move was generated, false for a pass }
Xfunction playMove(who: sType; var xLoc, yLoc: integer): boolean;
Xprocedure showPlayState(who: sType);
Xprocedure initGoPlayer;
X
Xvar
X playReason: string;
X playLevel: integer;
X maxPlayLevel: integer;
X
Xprivate
X
Ximports goPlayUtils from goPlayUtils;
Ximports popUp from popUp;
Ximports goBoard from goBoard;
Ximports perq_string from perq_string;
Ximports io_others from io_others;
X
Xvar
X saveNLibs: boolean;
X stateMenu: pNameDesc;
X
Xexception broken;
X
Xprocedure blek(var moveX, moveY: integer);
Xlabel
X 1; { done }
X
Xvar
X x, y: integer;
X dapList1, dapList2, dapList3: pointList;
X
X {
X Checks out a move.
X If my stone is not killable then true.
X }
X function safeMove(x, y: integer): boolean;
X var
X gbx, gby: integer;
X begin { safeMove }
X plei(x, y, 1); { try playing at point }
X if killFlag then { I shouldn't kill if lookForKill didn't }
X safeMove := false
X else if gList[groupIDs[x, y]].libC < 2 then
X begin { if it is in atari or dead }
X safeMove := false; { reject it }
X end
X else if gList[groupIDs[x, y]].libC <= treeLibLim then { see if killable }
X if playLevel > 0 then
X safeMove := not killable(x, y, gbx, gby)
X else
X safeMove := true
X else
X safeMove := true;
X restoreState;
X end { safeMove };
X
X function heCanCut(x, y: integer): boolean;
X var
X gx, gy: integer;
X begin { heCanCut }
X if playLevel > 3 then
X begin
X plei(x, y, -1); { try his cut }
X heCanCut := not killable(x, y, gx, gy);
X restoreState;
X end
X else
X heCanCut := true;
X end { heCanCut };
X
X {
X Plays on a corner point if possible
X returns true if so
X }
X function takeCorner(var x, y: integer): boolean;
X var
X field, i: integer;
X
X {
X checks a point for no influence and no neighbors
X sets up return vars and exits takeCorner if ok
X }
X procedure checkPos(tx, ty, field: integer);
X var
X ok: boolean;
X begin { checkPos }
X ok := (((field = 0) and (kleim[tx, ty] = 0)) or { if in field limits }
X ((field > 0) and
X (kleim[tx, ty] >= 0) and (kleim[tx, ty] <= field)) or
X ((field < 0) and
X (kleim[tx, ty] <= 0) and (kleim[tx, ty] >= field))) and
X (bord[tx - 1, ty] = 0) and { and no neighbors }
X (bord[tx + 1, ty] = 0) and
X (bord[tx, ty - 1] = 0) and
X (bord[tx, ty + 1] = 0);
X if ok then
X begin
X x := tx;
X y := ty;
X takeCorner := true;
X exit(takeCorner);
X end;
X end { checkPos };
X
X begin { takeCorner }
X playReason := 'takeCorner';
X i := maxPoint - 3;
X field := -1;
X repeat
X if field = -1 then
X field := 0
X else if field = 0 then
X field := 4
X else
X field := -4;
X checkPos(2, 3, field);
X checkPos(3, 2, field);
X checkPos(2, i, field);
X checkPos(3, i + 1, field);
X checkPos(i, i + 1, field);
X checkPos(i + 1, i, field);
X checkPos(i, 2, field);
X checkPos(i + 1, 3, field);
X checkPos(2, 4, field);
X checkPos(4, 2, field);
X checkPos(2, i - 1, field);
X checkPos(4, i + 1, field);
X checkPos(i - 1, i + 1, field);
X checkPos(i + 1, i - 1, field);
X checkPos(i + 1, 4, field);
X checkPos(i - 1, 2, field);
X until field = -4;
X takeCorner := false;
X end { takeCorner };
X
X {
X first phase of 3-line extentions
X }
X function extend(var x, y: integer): boolean;
X var
X i: integer;
X begin { extend }
X playReason := 'extend';
X for i := 2 to maxPoint - 2 do { look along a three line }
X if (kleim[2, i] = 0) and
X (bord[1, i] = 0) and
X (bord[3, i] = 0) and
X (bord[2, i - 1] = 0) and
X (bord[2, i + 1] = 0) then
X begin
X x := 2; { return the first point that there's nothing around }
X y := i;
X extend := true;
X exit(extend);
X end;
X for i := 2 to maxPoint - 2 do { another 3-line extention }
X if (kleim[i, maxPoint - 2] = 0) and
X (bord[i - 1, maxPoint - 2] = 0) and
X (bord[i + 1, maxPoint - 2] = 0) and
X (bord[i, maxPoint - 1] = 0) and
X (bord[i, maxPoint - 3] = 0) then
X begin
X x := i;
X y := maxPoint - 2;
X extend := true;
X exit(extend);
X end;
X for i := maxPoint - 2 downto 2 do { another 3-line extention }
X if (kleim[maxPoint - 2, i] = 0) and
X (bord[maxPoint - 1, i] = 0) and
X (bord[maxPoint - 3, i] = 0) and
X (bord[maxPoint - 2, i - 1] = 0) and
X (bord[maxPoint - 2, i + 1] = 0) then
X begin
X x := maxPoint - 2;
X y := i;
X extend := true;
X exit(extend);
X end;
X for i := maxPoint - 2 downto 2 do { another 3-line extention }
X if (kleim[i, 2] = 0) and
X (bord[i - 1, 2] = 0) and
X (bord[i + 1, 2] = 0) and
X (bord[i, 1] = 0) and
X (bord[i, 3] = 0) then
X begin
X x := i;
X y := 2;
X extend := true;
X exit(extend);
X end;
X extend := false;
X end { extend };
X
X {
X second phase of extentions - plays in my lowest influence spots on
X the 3-lines, so long as they are not touching anything
X }
X function extend2(var x, y: integer): boolean;
X var
X i, rekrd, veliu: integer;
X begin { extend2 }
X playReason := 'extend2';
X rekrd := iNil;
X x := iNil;
X y := iNil;
X for i := 3 to maxPoint - 3 do { scan a 3-line }
X if legal[2, i] then { if there is nobody there }
X begin
X veliu := kleim[2, i]; { get influence }
X if (veliu < 7) and { a reasonable hole in my wall }
X (veliu > -5) and { or a reasonable gap in his }
X (bord[2, i + 1] = 0) and { not in contact with any stones }
X (bord[2, i - 1] = 0) then
X if (rekrd <> iNil) and
X (veliu < rekrd) then
X begin
X rekrd := veliu; { rekrd gets the smallest value }
X x := 2; { that was seen along all the 3-lines }
X y := i; { x and y save that location }
X end
X else if rekrd = iNil then
X begin
X rekrd := veliu;
X x := 2;
X y := i;
X end;
X end;
X for i := 3 to maxPoint - 3 do
X if legal[i, 2] then
X begin
X veliu := kleim[i, 2];
X if (veliu < 7) and
X (veliu > -5) and
X (bord[i + 1, 2] = 0) and
X (bord[i - 1, 2] = 0) then
X if (rekrd <> iNil) and
X (veliu < rekrd) then
X begin
X rekrd := veliu;
X x := i;
X y := 2;
X end
X else if rekrd = iNil then
X begin
X rekrd := veliu;
X x := i;
X y := 2;
X end;
X end;
X for i := maxPoint - 3 downto 3 do
X if legal[maxPoint - 2, i] then
X begin
X veliu := kleim[maxPoint - 2, i];
X if (veliu < 7) and
X (veliu > -5) and
X (bord[maxPoint - 2, i + 1] = 0) and
X (bord[maxPoint - 2, i - 1] = 0) then
X if (rekrd <> iNil) and
X (veliu < rekrd) then
X begin
X rekrd := veliu;
X x := maxPoint - 2;
X y := i;
X end
X else if rekrd = iNil then
X begin
X rekrd := veliu;
X x := maxPoint - 2;
X y := i;
X end;
X end;
X for i := maxPoint - 3 downto 3 do
X if legal[i, maxPoint - 2] then
X begin
X veliu := kleim[i, maxPoint - 2];
X if (veliu < 7) and
X (veliu > -5) and
X (bord[i + 1, maxPoint - 2] = 0) and
X (bord[i - 1, maxPoint - 2] = 0) then
X if (rekrd <> iNil) and
X (veliu < rekrd) then
X begin
X rekrd := veliu;
X x := i;
X y := maxPoint - 2;
X end
X else if rekrd = iNil then
X begin
X rekrd := veliu;
X x := i;
X y := maxPoint - 2;
X end;
X end;
X extend2 := x <> iNil;
X end { extend2 };
X
X {
X connects against enemy cuts
X }
X function connectCut(var x, y: integer): boolean;
X var
X i, j, nap, gid, infl: integer;
X
X begin { connectCut }
X playreason := 'connectCut';
X connectCut := true;
X for i := 0 to maxPoint do
X for j := 0 to maxPoint do
X if legal[i, j] and
X (protPoints[i, j] = 0) then { not a protected point }
X begin
X nap := 0; { how many of my stones am I adjacent to? }
X if (i > 0) and (bord[i - 1, j] = 1) then
X begin
X nap := nap + 1;
X pList.p[nap].px := i - 1;
X pList.p[nap].py := j;
X end;
X if (j > 0) and (bord[i, j - 1] = 1) then
X begin
X nap := nap + 1;
X pList.p[nap].px := i;
X pList.p[nap].py := j - 1;
X end;
X if (i < maxPoint) and (bord[i + 1, j] = 1) then
X begin
X nap := nap + 1;
X pList.p[nap].px := i + 1;
X pList.p[nap].py := j;
X end;
X if (j < maxPoint) and (bord[i, j + 1] = 1) then
X begin
X nap := nap + 1;
X pList.p[nap].px := i;
X pList.p[nap].py := j + 1;
X end;
X if nap = 1 then { possible knight's or 2-point extention }
X with pList.p[1] do
X begin
X gid := groupIDs[px, py];
X if (i > 0) and (i < maxPoint) and
X (ndbord[i - 1, j] = 1) and
X (ndbord[i + 1, j] = 0) then { contact on left }
X begin
X if ((j > 0) and (ndbord[i, j - 1] = -1) and
X (ndbord[i + 1, j - 1] = 1) and
X (gid <> groupIDs[i + 1, j - 1])) or
X ((j < maxPoint) and (ndbord[i, j + 1] = -1) and
X (ndbord[i + 1, j + 1] = 1) and
X (gid <> groupIDs[i + 1, j + 1])) or
X ((((j > 0) and (ndbord[i, j - 1] = -1)) or
X ((j < maxPoint) and (ndbord[i, j + 1] = -1))) and
X (i < (maxPoint - 1)) and
X (ndbord[i + 2, j] = 1) and
X (gid <> groupIDs[i + 2, j])) then
X begin
X x := i;
X y := j;
X if safeMove(x, y) then
X exit(connectCut);
X end;
X end
X else if (i < maxPoint) and (i > 0) and
X (ndbord[i + 1, j] = 1) and
X (ndbord[i - 1, j] = 0) then { r }
X begin
X if ((j > 0) and (ndbord[i, j - 1] = -1) and
X (ndbord[i - 1, j - 1] = 1) and
X (gid <> groupIDs[i - 1, j - 1])) or
X ((j < maxPoint) and (ndbord[i, j + 1] = -1) and
X (ndbord[i - 1, j + 1] = 1) and
X (gid <> groupIDs[i - 1, j + 1])) or
X ((((j > 0) and (ndbord[i, j - 1] = -1)) or
X ((j < maxPoint) and (ndbord[i, j + 1] = -1))) and
X (i > 1) and
X (ndbord[i - 2, j] = 1) and
X (gid <> groupIDs[i - 2, j])) then
X begin
X x := i;
X y := j;
X if safeMove(x, y) then
X exit(connectCut);
X end;
X end
X else if (j > 0) and (j < maxPoint) and
X (ndbord[i, j - 1] = 1) and
X (ndbord[i, j + 1] = 0) then { top }
X begin
X if ((i > 0) and (ndbord[i - 1, j] = -1) and
X (ndbord[i - 1, j + 1] = 1) and
X (gid <> groupIDs[i - 1, j + 1])) or
X ((i < maxPoint) and (ndbord[i + 1, j] = -1) and
X (ndbord[i + 1, j + 1] = 1) and
X (gid <> groupIDs[i + 1, j + 1])) or
X ((((i > 0) and (ndbord[i - 1, j] = -1)) or
X ((i < maxPoint) and (ndbord[i + 1, j] = -1))) and
X (j < (maxPoint - 1)) and
X (ndbord[i, j + 2] = 1) and
X (gid <> groupIDs[i, j + 2])) then
X begin
X x := i;
X y := j;
X if safeMove(x, y) then
X exit(connectCut);
X end;
X end
X else if (j > 0) and (j < maxPoint) and
X (ndbord[i, j + 1] = 1) and
X (ndbord[i, j - 1] = 0) then { bottom }
X begin
X if ((i > 0) and (ndbord[i - 1, j] = -1) and
X (ndbord[i - 1, j - 1] = 1) and
X (gid <> groupIDs[i - 1, j - 1])) or
X ((i < maxPoint) and (ndbord[i + 1, j] = -1) and
X (ndbord[i + 1, j - 1] = 1) and
X (gid <> groupIDs[i + 1, j - 1])) or
X ((((i > 0) and (ndbord[i - 1, j] = -1)) or
X ((i < maxPoint) and (ndbord[i + 1, j] = -1))) and
X (j > 1) and
X (ndbord[i, j - 2] = 1) and
X (gid <> groupIDs[i, j - 2])) then
X begin
X x := i;
X y := j;
X if safeMove(x, y) then
X exit(connectCut);
X end;
X end;
X end
X else if nap = 2 then { diagonal or 1-point extention }
X begin
X if groupIDs[pList.p[1].px, pList.p[1].py] <>
X groupIDs[pList.p[2].px, pList.p[2].py] then
X begin
X if (pList.p[1].px <> pList.p[2].px) and
X (pList.p[1].py <> pList.p[2].py) then { diag }
X begin
X spanGroup(pList.p[1].px,
X pList.p[1].py, pList1);
X spanGroup(pList.p[2].px,
X pList.p[2].py, pList2);
X intersectPlist(pList1, pList2, pList3);
X if pList3.indx = 1 then
X if (i > 0) and (ndbord[i - 1, j] = -1) or
X (i < maxPoint) and (ndbord[i + 1, j] = -1) or
X (j > 0) and (ndbord[i, j - 1] = -1) or
X (j < maxPoint) and (ndbord[i, j + 1] = -1) then
X begin { must make direct connection }
X x := i;
X y := j;
X if heCanCut(x, y) then
X if safeMove(x, y) then
X exit(connectCut);
X end
X else if heCanCut(i, j) then
X begin { protect point if possible }
X infl := 1000;
X if (i > 0) and legal[i - 1, j] and
X ((i = 1) or (ndbord[i - 2, j] = 0)) and
X ((j = 0) or (ndbord[i - 1, j - 1] = 0)) and
X ((j = maxPoint) or
X (ndbord[i - 1, j + 1] = 0)) then
X if safeMove(i - 1, j) then
X if kleim[i - 1, j] < infl then
X begin
X x := i - 1;
X y := j;
X infl := kleim[i - 1, j];
X end;
X if (j > 0) and legal[i, j - 1] and
X ((j = 1) or (ndbord[i, j - 2] = 0)) and
X ((i = 0) or (ndbord[i - 1, j - 1] = 0)) and
X ((i = maxPoint) or
X (ndbord[i + 1, j - 1] = 0)) then
X if safeMove(i, j - 1) then
X if kleim[i, j - 1] < infl then
X begin
X x := i;
X y := j - 1;
X infl := kleim[i, j - 1];
X end;
X if (i < maxPoint) and legal[i + 1, j] and
X ((i = (maxPoint - 1)) or
X (ndbord[i + 2, j] = 0)) and
X ((j = 0) or (ndbord[i + 1, j - 1] = 0)) and
X ((j = maxPoint) or
X (ndbord[i + 1, j + 1] = 0)) then
X if safeMove(i + 1, j) then
X if kleim[i + 1, j] < infl then
X begin
X x := i + 1;
X y := j;
X infl := kleim[i + 1, j];
X end;
X if (j < maxPoint) and legal[i, j + 1] and
X ((j = (maxPoint - 1)) or
X (ndbord[i, j + 2] = 0)) and
X ((i = 0) or (ndbord[i - 1, j + 1] = 0)) and
X ((i = maxPoint) or
X (ndbord[i + 1, j + 1] = 0)) then
X if safeMove(i, j + 1) then
X if kleim[i, j + 1] < infl then
X begin
X x := i;
X y := j + 1;
X infl := kleim[i, j + 1];
X end;
X if infl < 1000 then
X exit(connectCut);
X x := i; { direct connection }
X y := j;
X if safeMove(x, y) then
X exit(connectCut);
X end;
X end
X else { 1-point extension, only protect if threatened }
X begin
X if (i > 0) and (ndbord[i - 1, j] = -1) or
X (j > 0) and (ndbord[i, j - 1] = -1) or
X (i < maxPoint) and (ndbord[i + 1, j] = -1) or
X (j < maxPoint) and (ndbord[i, j + 1] = -1) then
X begin
X x := i;
X y := j;
X if heCanCut(x, y) then
X if safeMove(x, y) then
X exit(connectCut);
X end;
X end;
X end;
X end
X else if nap = 3 then { unprotected, but me on 3 sides }
X begin
X if (groupIDs[pList.p[1].px, pList.p[1].py] <>
X groupIDs[pList.p[2].px, pList.p[2].py]) or
X (groupIDs[pList.p[1].px, pList.p[1].py] <>
X groupIDs[pList.p[3].px, pList.p[3].py]) or
X (groupIDs[pList.p[3].px, pList.p[3].py] <>
X groupIDs[pList.p[2].px, pList.p[2].py]) then
X begin
X spanGroup(pList.p[1].px, pList.p[1].py, pList1);
X spanGroup(pList.p[2].px, pList.p[2].py, pList2);
X intersectPlist(pList1, pList2, pList3);
X spanGroup(pList.p[3].px, pList.p[3].py, pList2);
X intersectPlist(pList2, pList3, pList1);
X if pList1.indx = 1 then { a common connect point }
X if heCanCut(i, j) then
X if safeMove(i, j) then
X begin
X x := i;
X y := j;
X exit(connectCut);
X end;
X end;
X end;
X end;
X connectCut := false;
X end { connectCut };
X
X {
X cuts the enemy
X }
X function cutHim(var x, y: integer): boolean;
X var
X i, j, nap, gid: integer;
X begin { cutHim }
X playreason := 'cutHim';
X cutHim := true;
X for i := 0 to maxPoint do
X for j := 0 to maxPoint do
X if legal[i, j] then
X begin
X nap := 0; { how many of his stones am I adjacent to? }
X if (i > 0) and (ndbord[i - 1, j] = -1) then
X begin
X nap := nap + 1;
X pList.p[nap].px := i - 1;
X pList.p[nap].py := j;
X end;
X if (j > 0) and (ndbord[i, j - 1] = -1) then
X begin
X nap := nap + 1;
X pList.p[nap].px := i;
X pList.p[nap].py := j - 1;
X end;
X if (i < maxPoint) and (ndbord[i + 1, j] = -1) then
X begin
X nap := nap + 1;
X pList.p[nap].px := i + 1;
X pList.p[nap].py := j;
X end;
X if (j < maxPoint) and (ndbord[i, j + 1] = -1) then
X begin
X nap := nap + 1;
X pList.p[nap].px := i;
X pList.p[nap].py := j + 1;
X end;
X if nap = 1 then { possible knight's or 2-point extention }
X with pList.p[1] do
X begin
X gid := groupIDs[px, py];
X if (i > 0) and (i < maxPoint) and
X (ndbord[i - 1, j] = -1) and
X (connectMap[i, j] > 0) then { contact on left }
X begin
X if ((j > 0) and
X (ndbord[i + 1, j - 1] = -1) and
X (gid <> groupIDs[i + 1, j - 1])) or
X ((j < maxPoint) and
X (ndbord[i + 1, j + 1] = -1) and
X (gid <> groupIDs[i + 1, j + 1])) or
X ((i < (maxPoint - 1)) and
X (ndbord[i + 1, j] = 0) and
X (ndbord[i + 2, j] = -1) and
X (gid <> groupIDs[i + 2, j])) then
X begin
X x := i;
X y := j;
X if safeMove(x, y) then
X exit(cutHim);
X end;
X end
X else if (i < maxPoint) and (i > 0) and
X (ndbord[i + 1, j] = -1) and
X (connectMap[i, j] > 0) then { r }
X begin
X if ((j > 0) and
X (ndbord[i - 1, j - 1] = -1) and
X (gid <> groupIDs[i - 1, j - 1])) or
X ((j < maxPoint) and
X (ndbord[i - 1, j + 1] = -1) and
X (gid <> groupIDs[i - 1, j + 1])) or
X ((i > 1) and
X (ndbord[i - 1, j] = 0) and
X (ndbord[i - 2, j] = -1) and
X (gid <> groupIDs[i - 2, j])) then
X begin
X x := i;
X y := j;
X if safeMove(x, y) then
X exit(cutHim);
X end;
X end
X else if (j > 0) and (j < maxPoint) and
X (ndbord[i, j - 1] = -1) and
X (connectMap[i, j] > 0) then { top }
X begin
X if ((i > 0) and
X (ndbord[i - 1, j + 1] = -1) and
X (gid <> groupIDs[i - 1, j + 1])) or
X ((i < maxPoint) and
X (ndbord[i + 1, j + 1] = -1) and
X (gid <> groupIDs[i + 1, j + 1])) or
X ((j < (maxPoint - 1)) and
X (ndbord[i, j + 1] = 0) and
X (ndbord[i, j + 2] = -1) and
X (gid <> groupIDs[i, j + 2])) then
X begin
X x := i;
X y := j;
X if safeMove(x, y) then
X exit(cutHim);
X end;
X end
X else if (j > 0) and (j < maxPoint) and
X (ndbord[i, j + 1] = -1) and
X (connectMap[i, j] > 0) then { bottom }
X begin
X if ((i > 0) and
X (ndbord[i - 1, j - 1] = -1) and
X (gid <> groupIDs[i - 1, j - 1])) or
X ((i < maxPoint) and
X (ndbord[i + 1, j - 1] = -1) and
X (gid <> groupIDs[i + 1, j - 1])) or
X ((j > 1) and
X (ndbord[i, j - 1] = 0) and
X (ndbord[i, j - 2] = -1) and
X (gid <> groupIDs[i, j - 2])) then
X begin
X x := i;
X y := j;
X if safeMove(x, y) then
X exit(cutHim);
X end;
X end;
X end
X else if nap = 2 then { diagonal or 1-point extention }
X begin
X if groupIDs[pList.p[1].px, pList.p[1].py] <>
X groupIDs[pList.p[2].px, pList.p[2].py] then
X begin
X if (pList.p[1].px <> pList.p[2].px) and
X (pList.p[1].py <> pList.p[2].py) then { diag }
X begin
X spanGroup(pList.p[1].px,
X pList.p[1].py, pList1);
X spanGroup(pList.p[2].px,
X pList.p[2].py, pList2);
X intersectPlist(pList1, pList2, pList3);
X if pList3.indx = 1 then
X begin
X x := i;
X y := j;
X if safeMove(x, y) then
X exit(cutHim);
X end;
X end
X else { 1-point extension, only cut if connected }
X begin
X if connectMap[i, j] > 0 then
X begin
X x := i;
X y := j;
X if safeMove(x, y) then
X exit(cutHim);
X end;
X end;
X end;
X end
X else if nap = 3 then { unprotected, but him on 3 sides }
X begin
X if (groupIDs[pList.p[1].px, pList.p[1].py] <>
X groupIDs[pList.p[2].px, pList.p[2].py]) or
X (groupIDs[pList.p[1].px, pList.p[1].py] <>
X groupIDs[pList.p[3].px, pList.p[3].py]) or
X (groupIDs[pList.p[3].px, pList.p[3].py] <>
X groupIDs[pList.p[2].px, pList.p[2].py]) then
X begin
X spanGroup(pList.p[1].px, pList.p[1].py, pList1);
X spanGroup(pList.p[2].px, pList.p[2].py, pList2);
X intersectPlist(pList1, pList2, pList3);
X spanGroup(pList.p[3].px, pList.p[3].py, pList2);
X intersectPlist(pList2, pList3, pList1);
X if pList1.indx = 1 then { a common connect point }
X if safeMove(i, j) then
X begin
X x := i;
X y := j;
X exit(cutHim);
X end;
X end;
X end;
X end;
X cutHim := false;
X end { cutHim };
X
X {
X blocks enemy cuts thru 1-point extensions
X }
X function blockCut(var x, y: integer): boolean;
X var
X i, j: integer;
X begin { blockCut }
X playReason := 'blockCut';
X blockCut := true;
X for i := 0 to maxPoint do
X for j := 0 to maxPoint do
X if legal[i, j] then
X begin
X if (i > 0) and (j > 0) and (j < maxPoint) then
X begin
X if (ndbord[i - 1, j] = -1) and
X (ndbord[i - 1, j - 1] = 1) and
X (ndbord[i - 1, j + 1] = 1) and
X (groupIDs[i - 1, j - 1] <> groupIDs[i - 1, j + 1]) then
X begin
X x := i;
X y := j;
X if heCanCut(x, y) then
X if safeMove(x, y) then
X exit(blockCut);
X end;
X end;
X if (i < maxPoint) and (j > 0) and (j < maxPoint) then
X begin
X if (ndbord[i + 1, j] = -1) and
X (ndbord[i + 1, j - 1] = 1) and
X (ndbord[i + 1, j + 1] = 1) and
X (groupIDs[i + 1, j - 1] <> groupIDs[i + 1, j + 1]) then
X begin
X x := i;
X y := j;
X if heCanCut(x, y) then
X if safeMove(x, y) then
X exit(blockCut);
X end;
X end;
X if (j > 0) and (i > 0) and (i < maxPoint) then
X begin
X if (ndbord[i, j - 1] = -1) and
X (ndbord[i - 1, j - 1] = 1) and
X (ndbord[i + 1, j - 1] = 1) and
X (groupIDs[i - 1, j - 1] <> groupIDs[i + 1, j - 1]) then
X begin
X x := i;
X y := j;
X if heCanCut(x, y) then
X if safeMove(x, y) then
X exit(blockCut);
X end;
X end;
X if (j < maxPoint) and (i > 0) and (i < maxPoint) then
X begin
X if (ndbord[i, j + 1] = -1) and
X (ndbord[i - 1, j + 1] = 1) and
X (ndbord[i + 1, j + 1] = 1) and
X (groupIDs[i - 1, j + 1] <> groupIDs[i + 1, j + 1]) then
X begin
X x := i;
X y := j;
X if heCanCut(x, y) then
X if safeMove(x, y) then
X exit(blockCut);
X end;
X end;
X end;
X blockCut := false;
X end { blockCut };
X
X {
X drops to the edge of the board if threatened
X }
X function dropToEdge(var x, y: integer): boolean;
X var
X i: integer;
X begin { dropToEdge }
X dropToEdge := true;
X playReason := 'dropToEdge';
X for i := 1 to maxPoint - 1 do
X begin
X if legal[1, i] then
X if (ndbord[2, i] = 1) and
X (ndbord[0, i] = 0) and
X (ndbord[1, i - 1] < 1) and
X (ndbord[1, i + 1] < 1) and
X ((ndbord[2, i - 1] = -1) or
X (ndbord[2, i + 1] = -1) or
X (ndbord[1, i - 1] = -1) or
X (ndbord[1, i + 1] = -1)) then
X begin
X x := 1;
X y := i;
X if safeMove(x, y) then
X exit(dropToEdge);
X end;
X if legal[maxPoint - 1, i] then
X if (ndbord[maxPoint - 2, i] = 1) and
X (ndbord[maxPoint, i] = 0) and
X (ndbord[maxPoint - 1, i - 1] < 1) and
X (ndbord[maxPoint - 1, i + 1] < 1) and
X ((ndbord[maxPoint - 2, i - 1] = -1) or
X (ndbord[maxPoint - 2, i + 1] = -1) or
X (ndbord[maxPoint - 1, i - 1] = -1) or
X (ndbord[maxPoint - 1, i + 1] = -1)) then
X begin
X x := maxPoint - 1;
X y := i;
X if safeMove(x, y) then
X exit(dropToEdge);
X end;
X if legal[i, 1] then
X if (ndbord[i, 2] = 1) and
X (ndbord[i, 0] = 0) and
X (ndbord[i - 1, 1] < 1) and
X (ndbord[i + 1, 1] < 1) and
X ((ndbord[i - 1, 2] = -1) or
X (ndbord[i + 1, 2] = -1) or
X (ndbord[i - 1, 1] = -1) or
X (ndbord[i + 1, 1] = -1)) then
X begin
X x := i;
X y := 1;
X if safeMove(x, y) then
X exit(dropToEdge);
X end;
X if legal[i, maxPoint - 1] then
X if (ndbord[i, maxPoint - 2] = 1) and
X (ndbord[i, maxPoint] = 0) and
X (ndbord[i - 1, maxPoint - 1] < 1) and
X (ndbord[i + 1, maxPoint - 1] < 1) and
X ((ndbord[i - 1, maxPoint - 2] = -1) or
X (ndbord[i + 1, maxPoint - 2] = -1) or
X (ndbord[i - 1, maxPoint - 1] = -1) or
X (ndbord[i + 1, maxPoint - 1] = -1)) then
X begin
X x := i;
X y := maxPoint - 1;
X if safeMove(x, y) then
X exit(dropToEdge);
X end;
X if legal[0, i] then
X if (ndbord[1, i] = 1) and
X (ndbord[0, i - 1] < 1) and
X (ndbord[0, i + 1] < 1) and
X (((ndbord[1, i - 1] = -1) and
X (ndbord[1, i + 1] = -1)) or
X (ndbord[0, i - 1] = -1) or
X (ndbord[0, i + 1] = -1)) then
X begin
X x := 0;
X y := i;
X if safeMove(x, y) then
X exit(dropToEdge);
X end;
X if legal[maxPoint, i] then
X if (ndbord[maxPoint - 1, i] = 1) and
X (ndbord[maxPoint, i - 1] < 1) and
X (ndbord[maxPoint, i + 1] < 1) and
X (((ndbord[maxPoint - 1, i - 1] = -1) and
X (ndbord[maxPoint - 1, i + 1] = -1)) or
X (ndbord[maxPoint, i - 1] = -1) or
X (ndbord[maxPoint, i + 1] = -1)) then
X begin
X x := maxPoint;
X y := i;
X if safeMove(x, y) then
X exit(dropToEdge);
X end;
X if legal[i, 0] then
X if (ndbord[i, 1] = 1) and
X (ndbord[i - 1, 0] < 1) and
X (ndbord[i + 1, 0] < 1) and
X (((ndbord[i - 1, 1] = -1) and
X (ndbord[i + 1, 1] = -1)) or
X (ndbord[i - 1, 0] = -1) or
X (ndbord[i + 1, 0] = -1)) then
X begin
X x := i;
X y := 0;
X if safeMove(x, y) then
X exit(dropToEdge);
X end;
X if legal[i, maxPoint] then
X if (ndbord[i, maxPoint - 1] = 1) and
X (ndbord[i - 1, maxPoint] < 1) and
X (ndbord[i + 1, maxPoint] < 1) and
X (((ndbord[i - 1, maxPoint - 1] = -1) and
X (ndbord[i + 1, maxPoint - 1] = -1)) or
X (ndbord[i - 1, maxPoint] = -1) or
X (ndbord[i + 1, maxPoint] = -1)) then
X begin
X x := i;
X y := maxPoint;
X if safeMove(x, y) then
X exit(dropToEdge);
X end;
X end;
X dropToEdge := false;
X end { dropToEdge };
X
X {
X Plays a move that requires a response on the opponent's part
X }
X function threaten(var x, y: integer): boolean;
X var
X i, j, gx, gy, tNum: integer;
X begin { threaten }
X playReason := 'threaten';
X initArray(threatBord);
X for i := 1 to maxGroupID do
X with gList[i] do
X if (not isLive) and
X (ndBord[lx, ly] = -1) then
X begin
X spanGroup(lx, ly, pList);
X for j := 1 to pList.indx do
X with pList.p[j] do
X if legal[px, py] then
X begin
X plei(px, py, 1);
X if gList[groupIDs[px, py]].libC > 1 then
X if killable(lx, ly, gx, gy) then
X threatBord[px, py] := threatBord[px, py] + 1;
X restoreState;
X end;
X end;
X tNum := 0;
X for i := 0 to maxPoint do
X for j := 0 to maxPoint do
X if (threatBord[i, j] > tNum) and
X ((threatBord[i, j] > 1) or
X (connectMap[i, j] > 0)) then
X begin
X tNum := threatBord[i, j];
X x := i;
X y := j;
X end;
X threaten := tNum > 0;
X end { threaten };
X
X {
X Extends walls in a connected fashion.
X Finds the lowest influence (mine) point that is connected to one
X of my groups.
X Only looks in the center of the board.
X }
X function extendWall(var x, y: integer): boolean;
X var
X infl, i, j: integer;
X begin { extendWall }
X playReason := 'extendWall';
X x := iNil;
X y := iNil;
X infl := 11;
X for i := 2 to maxPoint - 2 do
X for j := 2 to maxPoint - 2 do
X if legal[i, j] then
X if connectMap[i, j] > 0 then
X if (kleim[i, j] < infl) and
X (ndbord[i - 1, j] < 1) and
X (ndbord[i + 1, j] < 1) and
X (ndbord[i, j - 1] < 1) and
X (ndbord[i, j + 1] < 1) and
X ((kleim[i - 1, j] < 0) or
X (kleim[i + 1, j] < 0) or
X (kleim[i, j - 1] < 0) or
X (kleim[i, j + 1] < 0)) then
X if safeMove(i, j) then
X begin
X infl := kleim[i, j];
X x := i;
X y := j;
X end;
X extendWall := x <> iNil;
X end { extendWall };
X
X {
X Pushes walls in a tightly connected fashion.
X Finds the lowest influence (mine) point that is connected to one
X of my groups.
X }
X function pushWall(var x, y: integer): boolean;
X var
X infl, i, j, na: integer;
X begin { pushWall }
X playReason := 'pushWall';
X x := iNil;
X y := iNil;
X infl := 11;
X for i := 0 to maxPoint do
X for j := 0 to maxPoint do
X if legal[i, j] then
X if connectMap[i, j] > 0 then
X if (kleim[i, j] < infl) and
X (((i > 0) and (ndbord[i - 1, j] = 1)) or
X ((i < maxPoint) and (ndbord[i + 1, j] = 1)) or
X ((j > 0) and (ndbord[i, j - 1] = 1)) or
X ((j < maxPoint) and (ndbord[i, j + 1] = 1)) or
X ((i > 0) and (j > 0) and (ndbord[i - 1, j - 1] = 1)) or
X ((i < maxPoint) and (j > 0) and (ndbord[i + 1, j - 1] = 1)) or
X ((i > 0) and (j < maxPoint) and (ndbord[i - 1, j + 1] = 1)) or
X ((i < maxPoint) and (j < maxPoint) and
X (ndbord[i + 1, j + 1] = 1))) and
X (((i > 0) and (kleim[i - 1, j] < 0)) or
X ((i < maxPoint) and (kleim[i + 1, j] < 0)) or
X ((j > 0) and (kleim[i, j - 1] < 0)) or
X ((j < maxPoint) and (kleim[i, j + 1] < 0))) then
X begin
X na := 0;
X if (i > 0) and (ndbord[i - 1, j] <> 0) then
X na := na + 1;
X if (i < maxPoint) and (ndbord[i + 1, j] <> 0) then
X na := na + 1;
X if (j > 0) and (ndbord[i, j - 1] <> 0) then
X na := na + 1;
X if (j < maxPoint) and (ndbord[i, j + 1] <> 0) then
X na := na + 1;
X if na < 3 then
X if safeMove(i, j) then
X begin
X infl := kleim[i, j];
X x := i;
X y := j;
X end;
X end;
X pushWall := x <> iNil;
X end { pushWall };
X
X {
X check to see if I can kill anything
X }
X function lookForKill(var x, y: integer): boolean;
X var
X i: integer;
X begin { lookForKill }
X playReason := 'lookForKill';
X lookForKill := true;
X for i := 1 to maxGroupID do { scan the group list }
X with gList[i] do
X if (libC = 1) and
X (ndbord[lx, ly] = -1) then
X begin { we found a live enemy group with one liberty }
X spanGroup(lx, ly, pList); { find the liberty }
X x := pList.p[1].px;
X y := pList.p[1].py;
X if legal[x, y] then
X exit(lookForKill);
X end;
X lookForKill := false;
X end { lookForKill };
X
X {
X check to see if I can save anything in atari
X }
X function lookForSave(var x, y: integer): boolean;
X var
X i: integer;
X begin { lookForSave }
X playReason := 'lookForSave';
X lookForSave := true;
X for i := 1 to maxGroupID do { scan the group list }
X with gList[i] do
X if (libC = 1) and
X (ndbord[lx, ly] = 1) then
X begin
X if saveable(lx, ly, x, y) then { see if I can save it }
X exit(lookForSave);
X end;
X lookForSave := false;
X end { lookForSave };
X
X {
X check to see if I can save anything with n libs
X }
X function lookForSaveN(var x, y: integer): boolean;
X var
X i: integer;
X begin { lookForSaveN }
X if saveNLibs then
X begin
X playReason := 'lookForSaveN';
X lookForSaveN := true;
X for i := 1 to maxGroupID do { scan the group list }
X with gList[i] do
X if (libC > 1) and
X (libC <= treeLibLim) and
X (ndbord[lx, ly] = 1) then
X begin
X if killable(lx, ly, x, y) then
X if saveable(lx, ly, x, y) then { see if I can save it }
X exit(lookForSaveN);
X end;
X end;
X lookForSaveN := false;
X end { lookForSaveN };
X
X {
X check to see if I can attack one of his groups
X }
X function lookForAttack(var x, y: integer): boolean;
X var
X tx, ty, i: integer;
X begin { lookForAttack }
X playReason := 'lookForAttack';
X lookForAttack := true;
X for i := 1 to maxGroupID do { scan the group list }
X with gList[i] do
X if (not isLive) and
X (libC > 1) and
X (libC <= (treeLibLim + 1)) and
X (ndbord[lx, ly] = -1) then
X begin
X if killable(lx, ly, tx, ty) then { can we kill it? }
X begin
X x := tx; { yep - do so }
X y := ty;
X exit(lookForAttack);
X end;
X end;
X lookForAttack := false;
X end { lookForAttack };
X
X {
X check to see if I can attack one of his groups
X uses limited depth search so that it can work on larger lib counts
X }
X function findAttack2(var x, y: integer): boolean;
X var
X tx, ty, i, otll: integer;
X begin { findAttack2 }
X if playLevel < 7 then
X begin
X findAttack2 := false;
X exit(findAttack2);
X end;
X playReason := 'findAttack2';
X findAttack2 := true;
X depthLimit := 8;
X otll := treeLibLim;
X for i := 1 to maxGroupID do { scan the group list }
X with gList[i] do
X if (not isLive) and
X (ndBord[lx, ly] = -1) and
X (libC > 1) then
X begin
X treeLibLim := 6;
X if killable(lx, ly, tx, ty) then { can we kill it? }
X begin
X x := tx; { yep - do so }
X y := ty;
X exit(findAttack2);
X end;
X treeLibLim := otll;
X end;
X findAttack2 := false;
X depthLimit := 100;
X end { findAttack2 };
X
X function doubleAtari(var x, y: integer): boolean;
X var
X i, j: integer;
X begin { doubleAtari }
X playReason := 'doubleAtari';
X doubleAtari := true;
X for i := 1 to maxGroupID - 1 do
X with gList[i] do
X if (libC = 2) and
X (ndbord[lx, ly] = -1) then { found an atariable group of his }
X begin
X spanGroup(lx, ly, dapList1);
X for j := i + 1 to maxGroupID do
X with gList[j] do
X if (libC = 2) and
X (ndbord[lx, ly] = -1) then
X begin
X spanGroup(lx, ly, dapList2);
X intersectPlist(dapList1, dapList2, dapList3);
X if dapList3.indx > 0 then
X with dapList3.p[1] do
X if legal[px, py] then
X begin
X plei(px, py, 1);
X if gList[groupIDs[px, py]].libC > 1 then
X begin
X x := px;
X y := py;
X restoreState;
X exit(doubleAtari);
X end;
X restoreState;
X end;
X end;
X end;
X doubleAtari := false;
X end { doubleAtari };
X
X {
X ataris a group just for the hell of it
X }
X function atariAnyway(var x, y: integer): boolean;
X var
X i: integer;
X begin { atariAnyway }
X playReason := 'atariAnyway';
X atariAnyway := true;
X for i := 1 to maxGroupID do { scan the group list }
X with gList[i] do
X if (libC = 2) and
X (ndbord[lx, ly] = -1) then
X begin
X spanGroup(lx, ly, pList);
X with pList.p[1] do
X if legal[px, py] and
X ((connectMap[px, py] > 0) or
X ((px > 0) and (connectMap[px - 1, py] > 0)) or
X ((px < maxPoint) and (connectMap[px + 1, py] > 0)) or
X ((py > 0) and (connectMap[px, py - 1] > 0)) or
X ((py < maxPoint) and (connectMap[px, py + 1] > 0))) then
X if safeMove(px, py) then
X begin
X x := px;
X y := py;
X exit(atariAnyway);
X end;
X with pList.p[2] do
X if legal[px, py] and
X ((connectMap[px, py] > 0) or
X ((px > 0) and (connectMap[px - 1, py] > 0)) or
X ((px < maxPoint) and (connectMap[px + 1, py] > 0)) or
X ((py > 0) and (connectMap[px, py - 1] > 0)) or
X ((py < maxPoint) and (connectMap[px, py + 1] > 0))) then
X if safeMove(px, py) then
X begin
X x := px;
X y := py;
X exit(atariAnyway);
X end;
X end;
X atariAnyway := false;
X end { atariAnyway };
X
X {
X undercuts his groups
X }
X function underCut(var x, y: integer): boolean;
X var
X i, j: integer;
X begin { underCut }
X playReason := 'underCut';
X underCut := true;
X for i := 1 to maxPoint - 1 do
X begin
X if legal[0, i] then
X begin
X if ndbord[1, i] = -1 then
X if safeMove(0, i) then
X begin
X x := 0;
X y := i;
X exit(underCut);
X end;
X end;
X if legal[maxPoint, i] then
X begin
X if ndbord[maxPoint - 1, i] = -1 then
X if safeMove(maxPoint, i) then
X begin
X x := maxPoint;
X y := i;
X exit(underCut);
X end;
X end;
X if legal[i, 0] then
X begin
X if ndbord[i, 1] = -1 then
X if safeMove(i, 0) then
X begin
X x := i;
X y := 0;
X exit(underCut);
X end;
X end;
X if legal[i, maxPoint] then
X begin
X if ndbord[i, maxPoint - 1] = -1 then
X if safeMove(i, maxPoint) then
X begin
X x := i;
X y := maxPoint;
X exit(underCut);
X end;
X end;
X end;
X underCut := false;
X end { underCut };
X
X {
X reduces the liberty count of one of his groups
X }
X function reduceHisLiberties(var x, y: integer): boolean;
X var
X i, j: integer;
X begin { reduceHisLiberties }
X playReason := 'reduceHisLiberties';
X reduceHisLiberties := true;
X sortLibs;
X for i := 1 to maxGroupID do
X with gList[sGList[i]] do
X if (not isLive) and
X (libC > 2) and
X (ndbord[lx, ly] = -1) then
X begin
X spanGroup(lx, ly, pList);
X for j := 1 to pList.indx do
X with pList.p[j] do
X if legal[px, py] and
X (connectMap[px, py] > 0) then
X if safeMove(px, py) then
X begin
X x := px;
X y := py;
X exit(reduceHisLiberties);
X end;
X end;
X reduceHisLiberties := false;
X end { reduceHisLiberties };
X
X {
X connects a group to the edge
X }
X function dropToEdge2(var x, y: integer): boolean;
X var
X i: integer;
X begin { dropToEdge2 }
X playReason := 'dropToEdge2';
X dropToEdge2 := true;
X for i := 1 to maxPoint - 1 do
X begin
X if legal[i, 0] then
X begin
X if (ndbord[i, 1] = 1) and
X ((ndbord[i - 1, 0] < 1) or
X (groupIDs[i - 1, 0] <> groupIDs[i, 1])) and
X ((ndbord[i + 1, 0] < 1) or
X (groupIDs[i + 1, 0] <> groupIDs[i, 1])) and
X ((ndbord[i - 1, 1] = -1) or
X (ndbord[i + 1, 1] = -1)) then
X begin
X x := i;
X y := 0;
X if safeMove(x, y) then
X exit(dropToEdge2);
X end;
X end;
X if legal[0, i] then
X begin
X if (ndbord[1, i] = 1) and
X ((ndbord[0, i - 1] < 1) or
X (groupIDs[0, i - 1] <> groupIDs[1, i])) and
X ((ndbord[0, i + 1] < 1) or
X (groupIDs[0, i + 1] <> groupIDs[1, i])) and
X ((ndbord[1, i - 1] = -1) or
X (ndbord[1, i + 1] = -1)) then
X begin
X x := 0;
X y := i;
X if safeMove(x, y) then
X exit(dropToEdge2);
X end;
X end;
X if legal[i, maxPoint] then
X begin
X if (ndbord[i, maxPoint - 1] = 1) and
X ((ndbord[i - 1, maxPoint] < 1) or
X (groupIDs[i - 1, maxPoint] <> groupIDs[i, maxPoint - 1])) and
X ((ndbord[i + 1, maxPoint] < 1) or
X (groupIDs[i + 1, maxPoint] <> groupIDs[i, maxPoint - 1])) and
X ((ndbord[i - 1, maxPoint - 1] = -1) or
X (ndbord[i + 1, maxPoint - 1] = -1)) then
X begin
X x := i;
X y := maxPoint;
X if safeMove(x, y) then
X exit(dropToEdge2);
X end;
X end;
X if legal[maxPoint, i] then
X begin
X if (ndbord[maxPoint - 1, i] = 1) and
X ((ndbord[maxPoint, i - 1] < 1) or
X (groupIDs[maxPoint, i - 1] <> groupIDs[maxPoint - 1, i])) and
X ((ndbord[maxPoint, i + 1] < 1) or
X (groupIDs[maxPoint, i + 1] <> groupIDs[maxPoint - 1, i])) and
X ((ndbord[maxPoint - 1, i - 1] = -1) or
X (ndbord[maxPoint - 1, i + 1] = -1)) then
X begin
X x := maxPoint;
X y := i;
X if safeMove(x, y) then
X exit(dropToEdge2);
X end;
X end;
X end;
X dropToEdge2 := false;
X end { dropToEdge2 };
X
Xbegin { blek }
X saveState; { save state of the world }
X if takeCorner(x, y) then
X goto 1;
X if lookForSave(x, y) then
X goto 1;
X if lookForSaveN(x, y) then
X goto 1;
X if extend(x, y) then { check for possible 3-line extentions }
X goto 1;
X if lookForKill(x, y) then
X goto 1;
X if doubleAtari(x, y) then
X goto 1;
X if lookForAttack(x, y) then
X goto 1;
X if threaten(x, y) then
X goto 1;
X if extend2(x, y) then
X goto 1;
X if connectCut(x, y) then
X goto 1;
X if blockCut(x, y) then
X goto 1;
X if cutHim(x, y) then
X goto 1;
X if extendWall(x, y) then
X goto 1;
X if findAttack2(x, y) then
X goto 1;
X if atariAnyway(x, y) then
X goto 1;
X if underCut(x, y) then
X goto 1;
X if dropToEdge(x, y) then
X goto 1;
X if pushWall(x, y) then
X goto 1;
X if reduceHisLiberties(x, y) then
X goto 1;
X if dropToEdge2(x, y) then
X goto 1;
X moveX := iNil; { pass }
X moveY := iNil;
X exit(blek);
X1: { done }
X moveX := x;
X moveY := y;
Xend { blek };
X
Xprocedure genBord(who: sType);
Xvar
X i, j: integer;
X noMoves: boolean;
Xbegin { genBord }
X utilPlayLevel := playLevel;
X showTrees := debug;
X depthLimit := 100;
X mySType := who;
X if playLevel < 2 then
X treeLibLim := 2
X else
X treeLibLim := 3;
X noMoves := true;
X for i := 0 to maxPoint do
X for j := 0 to maxPoint do
X if board[i, j].val = who then
X begin
X bord[i, j] := 1;
X legal[i, j] := false;
X noMoves := false;
X end
X else if board[i, j].val = empty then
X begin
X bord[i, j] := 0;
X legal[i, j] := true;
X end
X else
X begin
X bord[i, j] := -1;
X legal[i, j] := false;
X noMoves := false;
X end;
X if koX >= 0 then
X legal[koX, koY] := false;
X if noMoves then
X initState
X else
X genState;
Xend { genBord };
X
Xfunction playMove(who: sType; var xLoc, yLoc: integer): boolean;
Xvar
X i, j: integer;
X noMoves: boolean;
Xbegin { playMove }
X saveNLibs := playLevel > 2;
X genBord(who);
X blek(xLoc, yLoc);
X playMove := xLoc <> iNil;
Xend { playMove };
X
Xprocedure showPlayState(who: sType);
Xvar
X res: resres;
X shown: boolean;
X cx, cy: integer;
X
X handler outside;
X begin { outside }
X write(''); {control-G}
X if shown then
X refreshBoard;
X exit(showPlayState);
X end { outside };
X
X procedure showIntBord(ib: intBoard);
X var
X i, j: integer;
X s: string;
X begin { showIntBord }
X for i := 0 to maxPoint do
X for j := 0 to maxPoint do
X if ib[i, j] <> 0 then
X begin
X s := intToStr(ib[i, j]);
X putBString(i, j, s);
X end;
X end { showIntBord };
X
X procedure showGroupState(sn: integer);
X var
X g: integer;
X s: string;
X
X procedure span(x, y: integer);
X begin { span }
X markBoard[x, y] := marker;
X putBString(x, y, s);
X if (x > 0) and
X (groupIDs[x - 1, y] = g) and
X (markBoard[x - 1, y] <> marker) then
X span(x - 1, y);
X if (x < maxPoint) and
X (groupIDs[x + 1, y] = g) and
X (markBoard[x + 1, y] <> marker) then
X span(x + 1, y);
X if (y > 0) and
X (groupIDs[x, y - 1] = g) and
X (markBoard[x, y - 1] <> marker) then
X span(x, y - 1);
X if (y < maxPoint) and
X (groupIDs[x, y + 1] = g) and
X (markBoard[x, y + 1] <> marker) then
X span(x, y + 1);
X end { span };
X
X begin { showGroupState }
X marker := marker + 1;
X if marker = 0 then
X begin
X initArray(markBoard);
X marker := 1;
X end;
X if sn < 3 then
X s := '*';
X for g := 1 to maxGroupID do
X with gList[g] do
X begin
X case sn of
X 1: { isLive }
X if isLive then
X span(lx, ly);
X 2: { isDead }
X if isDead then
X span(lx, ly);
X 3: { libertyCount }
X begin
X s := intToStr(libC);
X span(lx, ly);
X end;
X end; { case }
X end;
X end { showGroupState };
X
Xbegin { showPlayState }
X genBord(who);
X shown := false;
X cx := tabRelX;
X cy := tabRelY;
X repeat
X menu(stateMenu, false, 1, 11, cx, cy, -1, res);
X if shown then
X refreshBoard;
X case res^.indices[1] of
X 1: { bord }
X showIntBord(bord);
X 2: { ndBord }
X showIntBord(ndBord);
X 3: { kleim }
X showIntBord(kleim);
X 4: { sGroups }
X showIntBord(sGroups);
X 5: { groupIDs }
X showIntBord(groupIDs);
X 6: { connectMap }
X showIntBord(connectMap);
X 7: { protPoints }
X showIntBord(protPoints);
X 8: { isLive }
X showGroupState(1);
X 9: { isDead }
X showGroupState(2);
X 10: { libC }
X showGroupState(3);
X 11: { done }
X exit(showPlayState);
X end; { case }
X shown := true;
X destroyRes(res);
X until false;
Xend { showPlayState };
X
Xprocedure initGoPlayer;
Xbegin { initGoPlayer }
X initGPUtils;
X maxPlayLevel := 7;
X allocNameDesc(11, 0, stateMenu);
X with stateMenu^ do
X begin
X header := 'State to Display?';
X{$R-}
X commands[1] := 'Bord';
X commands[2] := 'NdBord';
X commands[3] := 'Influence';
X commands[4] := 'Space Groups';
X commands[5] := 'Group IDs';
X commands[6] := 'Connect Map';
X commands[7] := 'Protected Points';
X commands[8] := 'Live Groups';
X commands[9] := 'Dead Groups';
X commands[10] := 'Liberty Counts';
X commands[11] := 'Done';
X{$R=}
X end;
Xend. { initGoPlayer }
END_OF_goPlayer.pas
echo shar: 1 control character may be missing from \"goPlayer.pas\"
if test 58639 -ne `wc -c <goPlayer.pas`; then
echo shar: \"goPlayer.pas\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 2 \(of 5\).
cp /dev/null ark2isdone
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