home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / PASCAL / VALZAH.ZIP / PLAYKAL.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1987-01-11  |  12.3 KB  |  391 lines

  1. const
  2.    (* 'CONSTANT' VARIABLES USED TO REFERENCE COLS OF BOARD *)
  3.    RLEFT  = 0; (* STONES IN RED'S LEFT PIT *)
  4.    RRIGHT = 1; (* STONES IN RED'S RIGHT PIT *)
  5.    RKAL   = 2; (* STONES IN RED'S KALAH *)
  6.    BLEFT  = 3; (* STONES IN BLUE'S LEFT PIT *)
  7.    BRIGHT = 4; (* STONES IN BLUE'S RIGHT PIT *)
  8.    BKAL   = 5; (* STONES IN BLUE'S KALAH *)
  9.    TURN   = 6; (* -1 MEANS RED'S TURN, 1 MEANS BLUE'S TURN *)
  10.    LSON   = 7; (* ROW NUMBER OF LEFT SON *)
  11.    RSON   = 8; (* ROW NUMBER OF RIGHT SON *)
  12.    BESPAT = 9; (* 1 MEANS ON BEST PATH, 0 IF NOT *)
  13.    OUTCOM = 10; (* 0 MEANS blue WIN, 1 MEANS DRAW, 2 MEANS red WIN *)
  14.    ncols  = 11; (* number of columns in bd matrix *)
  15.    rwin   = 2;  (* outcom value for red  win *)
  16.    draw   = 1;  (* outcom value for draw *)
  17.    bwin   = 0;  (* outcom value for blue win *)
  18.    rturn  = 0;  (* turn value for red's  turn *)
  19.    bturn  = 1;  (* turn value for blue's turn *)
  20.    left   = 0;  (* move from left  pit *)
  21.    right  = 1;  (* move from right pit *)
  22.    offbespat = 0; (* bespat value if node is off best path *)
  23.    onbespat  = 1; (* bespat value if node is on  best path *)
  24.  
  25.  
  26. type
  27.    ary = array[0..1000] of integer;
  28.    boolean = (false, true);
  29.  
  30. var
  31.    ch : integer;
  32.    bd : ary;
  33.    next : integer; (* row number of next "free" row in array board *)
  34.  
  35. function board(row, col : integer);
  36.  
  37.    begin
  38.    board := bd[row*ncols + col]
  39.    end; (* function board *)
  40.  
  41. procedure setbd(row, col, val : integer);
  42.  
  43.    begin
  44.    bd[row*ncols + col] := val
  45.    end; (* procedure setbd *)
  46.  
  47. function min(x, y : integer);
  48.  
  49.    begin
  50.    if (x<y)
  51.    then
  52.       min:=x
  53.    else
  54.       min:=y
  55.    end; (* function min *)
  56.  
  57. function max(x, y : integer);
  58.  
  59.    begin
  60.    if (x>y)
  61.    then
  62.       max:=x
  63.    else
  64.       max:=y
  65.    end; (* function max *)
  66.  
  67. procedure getroot;
  68.  
  69.    begin
  70.    get#0(ch); setbd(1, rleft  ,ch-'0');
  71.    get#0(ch); setbd(1, rright ,ch-'0');
  72.    get#0(ch); setbd(1, rkal   ,ch-'0');
  73.    get#0(ch); setbd(1, bleft  ,ch-'0');
  74.    get#0(ch); setbd(1, bright ,ch-'0');
  75.    get#0(ch); setbd(1, bkal   ,ch-'0');
  76.    get#0(ch); setbd(1, turn   ,ch-'0');
  77.    setbd(1, outcom , draw);
  78.    setbd(1, bespat , offbespat)
  79.    end; (* procedure getroot *)
  80.  
  81. procedure prtrow(row : integer);
  82.  
  83.    begin
  84.    put#0(13,10);
  85.    put#0(' ', ' ', board(row, bright)#,
  86.          ' ', ' ', board(row, bleft )#, 13,10);
  87.  
  88.    put#0(board(row, bkal)#, ' ');
  89.    if board(row, outcom)=rwin
  90.       then put#0('r', 'e', 'd', ' ')
  91.       else if board(row, outcom)=draw
  92.               then put#0('d', 'r', 'a', 'w')
  93.               else put#0('b', 'l', 'u', 'e');
  94.    put#0(' ', board(row, rkal)#, ' ');
  95.  
  96.    if (board(row, bespat)=onbespat)
  97.    then
  98.       put#0('this boa',
  99.             'rd is on',
  100.             ' the bes',
  101.             't possib',
  102.             'le path.');
  103.    put#0(13,10);
  104.  
  105.    put#0(' ', ' ', board(row, rleft )#,
  106.          ' ', ' ', board(row, rright)#, 13,10)
  107.    end; (* procedure prtrow *)
  108.  
  109. procedure compconf(father, son, sourcpit : integer);
  110.  
  111.    var
  112.       sowopp,
  113.       moving : boolean;
  114.       frompit,
  115.       topit,
  116.       sowston,
  117.       pturn,  (* rturn if red players turn, bturn otherwise *)
  118.       i      : integer;
  119.  
  120.    begin
  121.    pturn:=board(father, turn);
  122.    if (pturn=bturn) then
  123.       if (sourcpit=left) then
  124.          frompit:=bleft
  125.       else
  126.          frompit:=bright
  127.    else  (* must be red's turn *)
  128.       if (sourcpit=left) then
  129.          frompit:=rleft
  130.       else
  131.          frompit:=rright;
  132. (* put#0('frompit=',frompit#,13,10);
  133. *)
  134.    for i:=rleft to outcom do  (* copy father board to son *)
  135.       setbd(son, i, board(father, i));
  136.  
  137.    (* test if able to move *)
  138.    if (board(father, frompit)=0) (* if frompit has no stones *)
  139.    or (board(father, bkal)>6)    (* or blue has won *)
  140.    or (board(father, rkal)>6)    (* or red has won *)
  141.    then                       (* unable to move *)
  142.       setbd(son, turn, board(father, turn))
  143.    else                       (* still have move left *)
  144.       if (board(father, turn)=rturn)
  145.       then setbd(son, turn, bturn)
  146.       else setbd(son, turn, rturn);
  147.  
  148.    moving:=true;
  149.    while (moving=true) do begin
  150.       sowston:=board(son, frompit);
  151. (*    put#0('sowston=',sowston#,13,10);
  152. *)    setbd(son, frompit, 0);
  153.       topit:=frompit;
  154.       sowopp:=false;
  155.  
  156.       while (sowston>0) do begin
  157.          topit:=topit+1;
  158. (*       put#0('topit= ',topit#,13,10);
  159. *)       if (topit>bkal) then
  160.             topit:=rleft;
  161.          if (topit=rkal) and (pturn=bturn) then
  162.             topit:=bleft;
  163.          if (topit=bkal) and (pturn=rturn) then
  164.             topit:=rleft;
  165.  
  166. (*       put#0('topit= ',topit#,13,10);
  167. *)
  168.          (* set sowopp to true if sowing into opponents pits *)
  169.          if (pturn=bturn) then
  170.             if (topit=rleft) or (topit=rright) then
  171.                sowopp:=true;
  172.          if (pturn=rturn) then
  173.             if (topit=bleft) or (topit=bright) then
  174.                sowopp:=true;
  175.  
  176.          setbd(son, topit, board(son,topit)+1); (* sow a stone *)
  177.          sowston:=sowston-1  (* number to sow is one less now *)
  178.          end; (* while sowston>0 *)
  179.  
  180.       (* check for go again, set moving *)
  181.       if (sowopp=true) and (board(son, topit) > 1) then
  182.          if ( (pturn=bturn) and ((topit=bleft) or (topit=bright)) )
  183.          or ( (pturn=rturn) and ((topit=rleft) or (topit=rright)) )
  184.             then (*  a go again move *)
  185.                begin
  186.                   moving:=true;
  187.                   frompit:=topit
  188.                end
  189.             else
  190.                moving:=false (* not a go again move *)
  191.          else (* not a go again move *)
  192.             moving:=false;
  193.  
  194.       (* check for capture *)
  195.       if (board(son, topit)=2) or (board(son ,topit)=3)
  196.       then  (* capture possible *)
  197.          begin
  198.          if (pturn=bturn) and ((topit=rleft) or (topit=rright))
  199.          then
  200.             begin
  201.             setbd(son, bkal, board(son, bkal)+board(son, topit));
  202.             setbd(son, topit, 0);
  203.             if (topit=rright) and
  204.                ((board(son, rleft)=2) or (board(son, rleft)=3))
  205.             then
  206.                begin
  207.                setbd(son, bkal, board(son, bkal)+board(son, rleft));
  208.                setbd(son, rleft, 0)
  209.                end
  210.             end;
  211.          if (pturn=rturn) and ((topit=bleft) or (topit=bright))
  212.          then
  213.             begin
  214.             setbd(son, rkal, board(son, rkal)+board(son, topit));
  215.             setbd(son, topit, 0);
  216.             if (topit=bright) and
  217.                ((board(son, bleft)=2) or (board(son, bleft)=3))
  218.             then
  219.                begin
  220.                setbd(son, rkal, board(son, rkal)+board(son, bleft));
  221.                setbd(son, bleft, 0)
  222.                end
  223.             end
  224.          end
  225.       end (* while moving=true *)
  226.    end; (* procedure compconf *)
  227.  
  228. procedure growtree(root : integer);
  229.  
  230.    begin
  231. (* put#0('growtree',root#,13,10);
  232. *) compconf(root, next, left); (* attempt to grow left son *)
  233.    if (board(root, turn)<>board(next, turn))
  234.    then (* there is a left son *)
  235.       begin
  236. (*    put#0('leftson ',13,10);
  237.       prtrow(next);
  238. *)    setbd(root, lson, next); (* link son to father *)
  239.       next:=next+1;
  240.       growtree(next-1)
  241.       end
  242.    else (* there is not left son *)
  243.       setbd(root, lson, 0);
  244.  
  245.    compconf(root, next, right); (* attempt to grow right son *)
  246.    if (board(root, turn)<>board(next, turn))
  247.    then (* there is a right son *)
  248.       begin
  249. (*    put#0('rightson',13,10);
  250.       prtrow(next);
  251. *)    setbd(root, rson, next); (* link son to father *)
  252.       next:=next+1;
  253.       growtree(next-1)
  254.       end
  255.    else (* there is no right son *)
  256.       setbd(root, rson, 0)
  257.    end; (* procedure growtree *)
  258.  
  259. procedure prttree(root : integer);
  260.  
  261.    begin
  262.    if (root<>0)
  263.    then
  264.       begin
  265.       prttree(board(root, lson)); (* print left  subtree *)
  266.       prtrow (root); (* print the node *)
  267.       prttree(board(root, rson))  (* print right subtree *)
  268.       end
  269.    end; (* procedure prttree *)
  270.  
  271. procedure findout(root : integer);
  272.  
  273.    begin
  274.    if (root<>0)
  275.    then
  276.       begin
  277.  
  278.       (* init all nodes to "off best path" *)
  279.       setbd(root, outcom, offbespat);
  280.  
  281.       findout(board(root, lson)); (* find outcome of left  subtree *)
  282.       findout(board(root, rson)); (* find outcome of right subtree *)
  283.  
  284.       (* determine outcome of father *)
  285.       (* first, see if he has any sons *)
  286.       if (board(root, lson)=0) and (board(root, rson)=0)
  287.       then                   (* he has no sons *)
  288.                              (* determine outcome from pits *)
  289.          if (board(root, bkal)>6)
  290.          then                (* blue has won *)
  291.             setbd(root, outcom, bwin)
  292.          else (* either red win or draw *)
  293.             if (board(root, rkal)>6)
  294.             then              (* red has won *)
  295.                setbd(root, outcom, rwin)
  296.             else              (* neither won, therefore draw *)
  297.                setbd(root, outcom, draw)
  298.  
  299.       else                    (* he has at least one son *)
  300.                               (* determine outcome from sons *)
  301.          if (board(root, lson)=0)  (* if no left son *)
  302.          then                 (* outcome is from right son *)
  303.             setbd(root, outcom,
  304.                board( board(root, rson), outcom)
  305.                  )
  306.          else                      (* he has a left son *)
  307.             if (board(root, rson)=0) (* if no right son *)
  308.             then            (* outcome is from left son *)
  309.                setbd(root, outcom,
  310.                   board( board(root, lson), outcom)
  311.                     )
  312.             else                   (* he has both sons *)
  313.                if (board(root, turn)=bturn)
  314.                then    (* outcome is minimum of sons' outcomes *)
  315.                   setbd(root, outcom,
  316.                      min(board( board(root, lson), outcom),
  317.                          board( board(root, rson), outcom)
  318.                         )
  319.                        )
  320.                else    (* outcome is maximum of sons' outcomes *)
  321.                   setbd(root, outcom,
  322.                      max(board (board(root, lson), outcom),
  323.                          board (board(root, rson), outcom)
  324.                         )
  325.                        )
  326.       end (* if root<>0 *)
  327.    end; (* procedure findout *)
  328.  
  329. procedure findbespat;
  330.  
  331.    var
  332.       p : integer;  (* work pointer used to traverse tree *)
  333.  
  334.    begin
  335.    p:=1;
  336.    (* loop unitl leaf is found *)
  337.    while (board(p, lson)<>0) or (board(p, rson)<>0) do
  338.       begin
  339.       setbd(p, bespat, onbespat);
  340.       if (board(p, lson)=0)
  341.       then (* root has no left son *)
  342.          p:=board(p, rson)    (* move on right son *)
  343.       else
  344.          if (board(p, rson)=0)
  345.          then (* root has no right son *)
  346.             p:=board(p, lson)   (* move on to left son *)
  347.          else (* root has both sons *)
  348.             if (board(p, turn)=bturn)  (* if blue's turn *)
  349.             then (* see if left outcom is better than right *)
  350.                if (    board( board(p, lson), outcom)
  351.                     <= board( board(p, rson), outcom)
  352.                   )
  353.                then                 (* left  is better or = *)
  354.                   p:=board(p, lson) (* go left              *)
  355.                else                 (* right is better      *)
  356.                   p:=board(p, rson) (* go right             *)
  357.             else (* it must be red's turn *)
  358.                if (    board( board(p, lson), outcom)
  359.                     >= board( board(p, rson), outcom)
  360.                   )
  361.                then                 (* left  is better or = *)
  362.                   p:=board(p, lson) (* go left              *)
  363.                else                 (* right is better ro = *)
  364.                   p:=board(p, rson) (* go right             *)
  365.       end; (* while not a leaf *)
  366.    setbd(p, bespat, onbespat)  (* final leaf is on best path *)
  367.    end; (* procedure findbespat *)
  368.  
  369. begin (* main line *)
  370. getroot;
  371. while (ch-'0'<>2) do  (* do while not eof *)
  372.  
  373.    begin
  374.    put#0(13,10,13,10);
  375.    put#0('root boa',
  376.          'rd is   ');
  377.    prtrow(1);
  378.  
  379.    next:=2; (* row 2 is first free row *)
  380.    growtree(1);
  381.    findout(1);
  382.    findbespat;
  383.    put#0(13,10,13,10);
  384.    put#0('output t',
  385.          'ree     ');
  386.    prttree(1);
  387.    getroot
  388.    end
  389.  
  390. end.
  391.