home *** CD-ROM | disk | FTP | other *** search
- const
- (* 'CONSTANT' VARIABLES USED TO REFERENCE COLS OF BOARD *)
- RLEFT = 0; (* STONES IN RED'S LEFT PIT *)
- RRIGHT = 1; (* STONES IN RED'S RIGHT PIT *)
- RKAL = 2; (* STONES IN RED'S KALAH *)
- BLEFT = 3; (* STONES IN BLUE'S LEFT PIT *)
- BRIGHT = 4; (* STONES IN BLUE'S RIGHT PIT *)
- BKAL = 5; (* STONES IN BLUE'S KALAH *)
- TURN = 6; (* -1 MEANS RED'S TURN, 1 MEANS BLUE'S TURN *)
- LSON = 7; (* ROW NUMBER OF LEFT SON *)
- RSON = 8; (* ROW NUMBER OF RIGHT SON *)
- BESPAT = 9; (* 1 MEANS ON BEST PATH, 0 IF NOT *)
- OUTCOM = 10; (* 0 MEANS blue WIN, 1 MEANS DRAW, 2 MEANS red WIN *)
- ncols = 11; (* number of columns in bd matrix *)
- rwin = 2; (* outcom value for red win *)
- draw = 1; (* outcom value for draw *)
- bwin = 0; (* outcom value for blue win *)
- rturn = 0; (* turn value for red's turn *)
- bturn = 1; (* turn value for blue's turn *)
- left = 0; (* move from left pit *)
- right = 1; (* move from right pit *)
- offbespat = 0; (* bespat value if node is off best path *)
- onbespat = 1; (* bespat value if node is on best path *)
-
-
- type
- ary = array[0..1000] of integer;
- boolean = (false, true);
-
- var
- ch : integer;
- bd : ary;
- next : integer; (* row number of next "free" row in array board *)
-
- function board(row, col : integer);
-
- begin
- board := bd[row*ncols + col]
- end; (* function board *)
-
- procedure setbd(row, col, val : integer);
-
- begin
- bd[row*ncols + col] := val
- end; (* procedure setbd *)
-
- function min(x, y : integer);
-
- begin
- if (x<y)
- then
- min:=x
- else
- min:=y
- end; (* function min *)
-
- function max(x, y : integer);
-
- begin
- if (x>y)
- then
- max:=x
- else
- max:=y
- end; (* function max *)
-
- procedure getroot;
-
- begin
- get#0(ch); setbd(1, rleft ,ch-'0');
- get#0(ch); setbd(1, rright ,ch-'0');
- get#0(ch); setbd(1, rkal ,ch-'0');
- get#0(ch); setbd(1, bleft ,ch-'0');
- get#0(ch); setbd(1, bright ,ch-'0');
- get#0(ch); setbd(1, bkal ,ch-'0');
- get#0(ch); setbd(1, turn ,ch-'0');
- setbd(1, outcom , draw);
- setbd(1, bespat , offbespat)
- end; (* procedure getroot *)
-
- procedure prtrow(row : integer);
-
- begin
- put#0(13,10);
- put#0(' ', ' ', board(row, bright)#,
- ' ', ' ', board(row, bleft )#, 13,10);
-
- put#0(board(row, bkal)#, ' ');
- if board(row, outcom)=rwin
- then put#0('r', 'e', 'd', ' ')
- else if board(row, outcom)=draw
- then put#0('d', 'r', 'a', 'w')
- else put#0('b', 'l', 'u', 'e');
- put#0(' ', board(row, rkal)#, ' ');
-
- if (board(row, bespat)=onbespat)
- then
- put#0('this boa',
- 'rd is on',
- ' the bes',
- 't possib',
- 'le path.');
- put#0(13,10);
-
- put#0(' ', ' ', board(row, rleft )#,
- ' ', ' ', board(row, rright)#, 13,10)
- end; (* procedure prtrow *)
-
- procedure compconf(father, son, sourcpit : integer);
-
- var
- sowopp,
- moving : boolean;
- frompit,
- topit,
- sowston,
- pturn, (* rturn if red players turn, bturn otherwise *)
- i : integer;
-
- begin
- pturn:=board(father, turn);
- if (pturn=bturn) then
- if (sourcpit=left) then
- frompit:=bleft
- else
- frompit:=bright
- else (* must be red's turn *)
- if (sourcpit=left) then
- frompit:=rleft
- else
- frompit:=rright;
- (* put#0('frompit=',frompit#,13,10);
- *)
- for i:=rleft to outcom do (* copy father board to son *)
- setbd(son, i, board(father, i));
-
- (* test if able to move *)
- if (board(father, frompit)=0) (* if frompit has no stones *)
- or (board(father, bkal)>6) (* or blue has won *)
- or (board(father, rkal)>6) (* or red has won *)
- then (* unable to move *)
- setbd(son, turn, board(father, turn))
- else (* still have move left *)
- if (board(father, turn)=rturn)
- then setbd(son, turn, bturn)
- else setbd(son, turn, rturn);
-
- moving:=true;
- while (moving=true) do begin
- sowston:=board(son, frompit);
- (* put#0('sowston=',sowston#,13,10);
- *) setbd(son, frompit, 0);
- topit:=frompit;
- sowopp:=false;
-
- while (sowston>0) do begin
- topit:=topit+1;
- (* put#0('topit= ',topit#,13,10);
- *) if (topit>bkal) then
- topit:=rleft;
- if (topit=rkal) and (pturn=bturn) then
- topit:=bleft;
- if (topit=bkal) and (pturn=rturn) then
- topit:=rleft;
-
- (* put#0('topit= ',topit#,13,10);
- *)
- (* set sowopp to true if sowing into opponents pits *)
- if (pturn=bturn) then
- if (topit=rleft) or (topit=rright) then
- sowopp:=true;
- if (pturn=rturn) then
- if (topit=bleft) or (topit=bright) then
- sowopp:=true;
-
- setbd(son, topit, board(son,topit)+1); (* sow a stone *)
- sowston:=sowston-1 (* number to sow is one less now *)
- end; (* while sowston>0 *)
-
- (* check for go again, set moving *)
- if (sowopp=true) and (board(son, topit) > 1) then
- if ( (pturn=bturn) and ((topit=bleft) or (topit=bright)) )
- or ( (pturn=rturn) and ((topit=rleft) or (topit=rright)) )
- then (* a go again move *)
- begin
- moving:=true;
- frompit:=topit
- end
- else
- moving:=false (* not a go again move *)
- else (* not a go again move *)
- moving:=false;
-
- (* check for capture *)
- if (board(son, topit)=2) or (board(son ,topit)=3)
- then (* capture possible *)
- begin
- if (pturn=bturn) and ((topit=rleft) or (topit=rright))
- then
- begin
- setbd(son, bkal, board(son, bkal)+board(son, topit));
- setbd(son, topit, 0);
- if (topit=rright) and
- ((board(son, rleft)=2) or (board(son, rleft)=3))
- then
- begin
- setbd(son, bkal, board(son, bkal)+board(son, rleft));
- setbd(son, rleft, 0)
- end
- end;
- if (pturn=rturn) and ((topit=bleft) or (topit=bright))
- then
- begin
- setbd(son, rkal, board(son, rkal)+board(son, topit));
- setbd(son, topit, 0);
- if (topit=bright) and
- ((board(son, bleft)=2) or (board(son, bleft)=3))
- then
- begin
- setbd(son, rkal, board(son, rkal)+board(son, bleft));
- setbd(son, bleft, 0)
- end
- end
- end
- end (* while moving=true *)
- end; (* procedure compconf *)
-
- procedure growtree(root : integer);
-
- begin
- (* put#0('growtree',root#,13,10);
- *) compconf(root, next, left); (* attempt to grow left son *)
- if (board(root, turn)<>board(next, turn))
- then (* there is a left son *)
- begin
- (* put#0('leftson ',13,10);
- prtrow(next);
- *) setbd(root, lson, next); (* link son to father *)
- next:=next+1;
- growtree(next-1)
- end
- else (* there is not left son *)
- setbd(root, lson, 0);
-
- compconf(root, next, right); (* attempt to grow right son *)
- if (board(root, turn)<>board(next, turn))
- then (* there is a right son *)
- begin
- (* put#0('rightson',13,10);
- prtrow(next);
- *) setbd(root, rson, next); (* link son to father *)
- next:=next+1;
- growtree(next-1)
- end
- else (* there is no right son *)
- setbd(root, rson, 0)
- end; (* procedure growtree *)
-
- procedure prttree(root : integer);
-
- begin
- if (root<>0)
- then
- begin
- prttree(board(root, lson)); (* print left subtree *)
- prtrow (root); (* print the node *)
- prttree(board(root, rson)) (* print right subtree *)
- end
- end; (* procedure prttree *)
-
- procedure findout(root : integer);
-
- begin
- if (root<>0)
- then
- begin
-
- (* init all nodes to "off best path" *)
- setbd(root, outcom, offbespat);
-
- findout(board(root, lson)); (* find outcome of left subtree *)
- findout(board(root, rson)); (* find outcome of right subtree *)
-
- (* determine outcome of father *)
- (* first, see if he has any sons *)
- if (board(root, lson)=0) and (board(root, rson)=0)
- then (* he has no sons *)
- (* determine outcome from pits *)
- if (board(root, bkal)>6)
- then (* blue has won *)
- setbd(root, outcom, bwin)
- else (* either red win or draw *)
- if (board(root, rkal)>6)
- then (* red has won *)
- setbd(root, outcom, rwin)
- else (* neither won, therefore draw *)
- setbd(root, outcom, draw)
-
- else (* he has at least one son *)
- (* determine outcome from sons *)
- if (board(root, lson)=0) (* if no left son *)
- then (* outcome is from right son *)
- setbd(root, outcom,
- board( board(root, rson), outcom)
- )
- else (* he has a left son *)
- if (board(root, rson)=0) (* if no right son *)
- then (* outcome is from left son *)
- setbd(root, outcom,
- board( board(root, lson), outcom)
- )
- else (* he has both sons *)
- if (board(root, turn)=bturn)
- then (* outcome is minimum of sons' outcomes *)
- setbd(root, outcom,
- min(board( board(root, lson), outcom),
- board( board(root, rson), outcom)
- )
- )
- else (* outcome is maximum of sons' outcomes *)
- setbd(root, outcom,
- max(board (board(root, lson), outcom),
- board (board(root, rson), outcom)
- )
- )
- end (* if root<>0 *)
- end; (* procedure findout *)
-
- procedure findbespat;
-
- var
- p : integer; (* work pointer used to traverse tree *)
-
- begin
- p:=1;
- (* loop unitl leaf is found *)
- while (board(p, lson)<>0) or (board(p, rson)<>0) do
- begin
- setbd(p, bespat, onbespat);
- if (board(p, lson)=0)
- then (* root has no left son *)
- p:=board(p, rson) (* move on right son *)
- else
- if (board(p, rson)=0)
- then (* root has no right son *)
- p:=board(p, lson) (* move on to left son *)
- else (* root has both sons *)
- if (board(p, turn)=bturn) (* if blue's turn *)
- then (* see if left outcom is better than right *)
- if ( board( board(p, lson), outcom)
- <= board( board(p, rson), outcom)
- )
- then (* left is better or = *)
- p:=board(p, lson) (* go left *)
- else (* right is better *)
- p:=board(p, rson) (* go right *)
- else (* it must be red's turn *)
- if ( board( board(p, lson), outcom)
- >= board( board(p, rson), outcom)
- )
- then (* left is better or = *)
- p:=board(p, lson) (* go left *)
- else (* right is better ro = *)
- p:=board(p, rson) (* go right *)
- end; (* while not a leaf *)
- setbd(p, bespat, onbespat) (* final leaf is on best path *)
- end; (* procedure findbespat *)
-
- begin (* main line *)
- getroot;
- while (ch-'0'<>2) do (* do while not eof *)
-
- begin
- put#0(13,10,13,10);
- put#0('root boa',
- 'rd is ');
- prtrow(1);
-
- next:=2; (* row 2 is first free row *)
- growtree(1);
- findout(1);
- findbespat;
- put#0(13,10,13,10);
- put#0('output t',
- 'ree ');
- prttree(1);
- getroot
- end
-
- end.