home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / games / backgammon / common_source / backgammon.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-04-08  |  15.9 KB  |  752 lines

  1. /*-
  2.  * Copyright (c) 1991 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. static char sccsid[] = "@(#)backgammon.c    5.1 (Berkeley) 4/8/91";
  36. #endif /* not lint */
  37.  
  38. /*
  39. **    The game of Backgammon
  40. */
  41.  
  42. #include    <stdio.h>
  43.  
  44. #define    WHITE        0
  45. #define    BROWN        1
  46. #define    NIL        (-1)
  47. #define    MAXGMOV        10
  48. #define    MAXIMOVES    1000
  49. #define    RULES        "/usr/games/lib/backrules"
  50.  
  51. char    level;        /*'b'=beginner, 'i'=intermediate, 'e'=expert*/
  52.  
  53. int    die1;
  54. int    die2;
  55. int    i;
  56. int    j;
  57. int    l;
  58. int    m;
  59. int    pflg = 1;
  60. int    nobroll = 0;
  61. int    count;
  62. int    imoves;
  63. int    goodmoves[MAXGMOV];
  64. int    probmoves[MAXGMOV];
  65.  
  66. int    brown[] = {        /* brown position table */
  67.     0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 
  68.     0, 0, 0, 0, 3, 0, 5, 0, 0, 0, 0, 0, 
  69.     0, 0, 0, 0, 0, 0
  70. };
  71.  
  72. int    white[] = {        /* white position table */
  73.     0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 
  74.     0, 0, 0, 0, 3, 0, 5, 0, 0, 0, 0, 0, 
  75.     0, 0, 0, 0, 0, 0
  76. };
  77.  
  78. int    probability[] = {
  79.     0, 11, 12, 13, 14, 15, 16, 
  80.     06, 05, 04, 03, 02, 01
  81. };
  82.  
  83. struct    {
  84.     int    pos[4];
  85.     int    mov[4];
  86. } moves[MAXIMOVES];
  87.  
  88. main()
  89. {
  90.     int    go[5], tvec[2];
  91.     int    k, n, pid, ret, rpid, t;
  92.     char    s[100];
  93.  
  94.     srand(time(0));
  95.     go[5] = NIL;
  96.     fprintf(stdout, "Instructions? ");
  97.     gets(s);
  98.     if(*s == 'y')
  99.         instructions();
  100.     putchar('\n');
  101.     fprintf(stdout, "Opponent's level: b - beginner,\n");
  102.     fprintf(stdout, "i - intermediate, e - expert? ");
  103.     level='e';
  104.     gets(s);
  105.     if(*s == 'b')
  106.         level = 'b';
  107.     else if(*s == 'i')
  108.         level = 'i';
  109.     putchar('\n');
  110.     fprintf(stdout, "You will play brown.\n\n");
  111.     fprintf(stdout, "Would you like to roll your own dice? ");
  112.     gets(s);
  113.     putchar('\n');
  114.     if(*s == 'y')
  115.         nobroll = 1;
  116.     fprintf(stdout, "Would you like to go first? ");
  117.     gets(s);
  118.     putchar('\n');
  119.     if(*s == 'y')
  120.         goto nowhmove;
  121. whitesmv:
  122.     roll(WHITE);
  123.     fprintf(stdout, "white rolls %d, %d\n", die1, die2);
  124.     fprintf(stdout, "white's move is:");
  125.     if(nextmove(white, brown) == NIL)
  126.         goto nowhmove;
  127.     if(piececount(white, 0, 24) == 0){
  128.         fprintf(stdout, "White wins");
  129.         if(piececount(brown, 0, 6) != 0)
  130.             fprintf(stdout, " with a Backgammon!\n");
  131.         else if (piececount(brown, 0, 24) == 24)
  132.             fprintf(stdout, " with a Gammon.\n");
  133.         else
  134.             fprintf(stdout, ".\n");
  135.         exit(0);
  136.     }
  137. nowhmove:
  138.     if(pflg)
  139.         prtbrd();
  140.     roll(BROWN);
  141. retry:
  142.     fprintf(stdout, "\nYour roll is %d  %d\n", die1, die2);
  143.     fprintf(stdout, "Move? ");
  144.     gets(s);
  145.     switch(*s) {
  146.         case '\0':            /* empty line */
  147.             fprintf(stdout, "Brown's move skipped.\n");
  148.             goto whitesmv;
  149.  
  150.         case 'b':            /* how many beared off? */
  151.             fprintf(stdout, "Brown:   %d\n", piececount(brown, 0, 24) - 15);
  152.             fprintf(stdout, "White:   %d\n", piececount(white, 0, 24) - 15);
  153.             goto retry;
  154.  
  155.         case 'p':            /* print board */
  156.             prtbrd();
  157.             goto retry;
  158.  
  159.         case 's':            /* stop auto printing of board */
  160.             pflg = 0;
  161.             goto retry;
  162.  
  163.         case 'r':            /* resume auto printing */
  164.             pflg = 1;
  165.             goto retry;
  166.  
  167.         case 'm':            /* print possible moves */
  168.             pmoves();
  169.             goto retry;
  170.  
  171.         case 'q':            /* i give up */
  172.             exit(0);
  173.  
  174.         case '!':            /* escape to Shell */
  175.             if(s[1] != '\0')
  176.                 system(s+1);
  177.             else if((pid = fork()) == 0) {
  178.                 execl("/bin/sh", "sh", "-", 0);
  179.                 fprintf(stderr, "back: cannot exec /bin/sh!\n");
  180.                 exit(2);
  181.             }
  182.             while((rpid = wait(&ret)) != pid && rpid != -1)
  183.                 ;
  184.             goto retry;
  185.  
  186.         case '?':            /* well, what can i do? */
  187.             fprintf(stdout, "<newline>    skip this move\n");
  188.             fprintf(stdout, "b        number beared off\n");
  189.             fprintf(stdout, "p        print board\n");
  190.             fprintf(stdout, "q        quit\n");
  191.             fprintf(stdout, "r        resume auto print of board\n");
  192.             fprintf(stdout, "s        stop auto print of board\n");
  193.             fprintf(stdout, "!        escape to Shell\n");
  194.             goto retry;
  195.     }
  196.     n = sscanf(s,"%d%d%d%d%d",&go[0],&go[1],&go[2],&go[3],&go[4]);
  197.     if((die1 != die2 && n > 2) || n > 4){
  198.         fprintf(stdout, "Too many moves.\n");
  199.         goto retry;
  200.     }
  201.     go[n] = NIL;
  202.     if(*s=='-'){
  203.         go[0]= -go[0];
  204.         t=die1;
  205.         die1=die2;
  206.         die2=t;
  207.     }
  208.     for(k = 0; k < n; k++){
  209.         if(0 <= go[k] && go[k] <= 24)
  210.             continue;
  211.         else{
  212.             fprintf(stdout, "Move %d illegal.\n", go[k]);
  213.             goto retry;
  214.         }
  215.     }
  216.     if(play(brown, white, go))
  217.         goto retry;
  218.     if(piececount(brown, 0, 24) == 0){
  219.         fprintf(stdout, "Brown wins");
  220.         if(piececount(white, 0, 6) != 0)
  221.             fprintf(stdout, " with a Backgammon.\n");
  222.         else if(piececount(white, 0, 24) == 24)
  223.             fprintf(stdout, " with a gammon.\n");
  224.         else
  225.             fprintf(stdout, ".\n");
  226.         exit(0);
  227.     }
  228.     goto whitesmv;
  229. }
  230.  
  231. play(player,playee,pos)
  232. int *player,*playee,pos[];
  233. {
  234.     int    k, n, die, ipos;
  235.  
  236.     for(k=0; k < player[0]; k++){  /*blots on player[0] must be moved first*/
  237.         if(pos[k] == NIL)
  238.             break;
  239.         if(pos[k] != 0){
  240.             fprintf(stdout, "Stone on bar must be moved first.\n");
  241.             return(NIL);
  242.         }
  243.     }
  244.     for(k = 0; (ipos=pos[k]) != NIL; k++){
  245.         die = k?die2:die1;
  246.         n = 25-ipos-die;
  247.         if(player[ipos] == 0)
  248.             goto badmove;
  249.         if(n > 0 && playee[n] >= 2)
  250.             goto badmove;
  251.         if(n <= 0){
  252.             if(piececount(player,0,18) != 0)
  253.                 goto badmove;
  254.             if((ipos+die) != 25 && piececount(player,19,24-die)!=0)
  255.                 goto badmove;
  256.         }
  257.         player[ipos]--;
  258.         player[ipos+die]++;
  259.     }
  260.     for(k = 0; pos[k] != NIL; k++){
  261.         die = k?die2:die1;
  262.         n = 25-pos[k]-die;
  263.         if(n>0 && playee[n]==1){
  264.             playee[n]=0;
  265.             playee[0]++;
  266.         }
  267.     }
  268.     return(0);
  269.  
  270. badmove:
  271.     fprintf(stdout, "Move %d illegal.\n", ipos);
  272.     while(k--){
  273.         die=k?die2:die1;
  274.         player[pos[k]]++;
  275.         player[pos[k]+die]--;
  276.     }
  277.     return(NIL);
  278. }
  279. nextmove(player,playee)
  280. int *player,*playee;
  281. {
  282.     int    k;
  283.  
  284.     imoves=0;
  285.     movegen(player,playee);
  286.     if(die1!=die2){
  287.         k=die1;
  288.         die1=die2;
  289.         die2=k;
  290.         movegen(player,playee);
  291.     }
  292.     if(imoves==0){
  293.         fprintf(stdout, "no move possible.\n");
  294.         return(NIL);
  295.     }
  296.     k=strategy(player,playee);        /*select kth possible move*/
  297.     prtmov(k);
  298.     update(player,playee,k);
  299.     return(0);
  300. }
  301. prtmov(k)
  302. int k;
  303. {
  304.     int    n;
  305.  
  306.     if(k == NIL)
  307.         fprintf(stdout, "No move possible\n");
  308.     else for(n = 0; n < 4; n++){
  309.         if(moves[k].pos[n] == NIL)
  310.             break;
  311.         fprintf(stdout, "    %d, %d",25-moves[k].pos[n],moves[k].mov[n]);
  312.     }
  313.     fprintf(stdout, "\n");
  314. }
  315. update(player,playee,k)
  316. int *player,*playee,k;
  317. {
  318.     int    n,t;
  319.  
  320.     for(n = 0; n < 4; n++){
  321.         if(moves[k].pos[n] == NIL)
  322.             break;
  323.         player[moves[k].pos[n]]--;
  324.         player[moves[k].pos[n]+moves[k].mov[n]]++;
  325.         t=25-moves[k].pos[n]-moves[k].mov[n];
  326.         if(t>0 && playee[t]==1){
  327.             playee[0]++;
  328.             playee[t]--;
  329.         }
  330.     }
  331. }
  332. piececount(player,startrow,endrow)
  333. int *player,startrow,endrow;
  334. {
  335.     int    sum;
  336.  
  337.     sum=0;
  338.     while(startrow <= endrow)
  339.         sum += player[startrow++];
  340.     return(sum);
  341. }
  342. pmoves()
  343. {
  344.     int    i1, i2;
  345.  
  346.     fprintf(stdout, "Possible moves are:\n");
  347.     for(i1 = 0; i1 < imoves; i1++){
  348.         fprintf(stdout, "\n%d",i1);
  349.          for (i2 = 0; i2<4; i2++){
  350.             if(moves[i1].pos[i2] == NIL)
  351.                 break;
  352.             fprintf(stdout, "%d, %d",moves[i1].pos[i2],moves[i1].mov[i2]);
  353.         }
  354.     }
  355.     fprintf(stdout, "\n");
  356. }
  357.  
  358. roll(who)
  359. {
  360.     register n;
  361.     char     s[10];
  362.  
  363.     if(who == BROWN && nobroll) {
  364.         fprintf(stdout, "Roll? ");
  365.         gets(s);
  366.         n = sscanf(s, "%d%d", &die1, &die2);
  367.         if(n != 2 || die1 < 1 || die1 > 6 || die2 < 1 || die2 > 6)
  368.             fprintf(stdout, "Illegal - I'll do it!\n");
  369.         else
  370.             return;
  371.     }
  372.     die1 = ((rand()>>8) % 6) + 1;
  373.     die2 = ((rand()>>8) % 6) + 1;
  374. }
  375.  
  376. movegen(mover,movee)
  377. int *mover,*movee;
  378. {
  379.     int    k;
  380.  
  381.     for(i = 0; i <= 24; i++){
  382.         count = 0;
  383.         if(mover[i] == 0)
  384.             continue;
  385.         if((k=25-i-die1) > 0 && movee[k] >= 2)
  386.             if(mover[0] > 0)
  387.                 break;
  388.         else
  389.             continue;
  390.         if(k <= 0){
  391.             if(piececount(mover, 0, 18) != 0)
  392.                 break;
  393.             if((i+die1) != 25 && piececount(mover,19,i-1) != 0)
  394.                 break;
  395.         }
  396.         mover[i]--;
  397.         mover[i+die1]++;
  398.         count = 1;
  399.         for(j = 0; j <= 24; j++){
  400.             if(mover[j]==0)
  401.                 continue;
  402.             if((k=25-j-die2) > 0 && movee[k] >= 2)
  403.                 if(mover[0] > 0)
  404.                     break;
  405.             else
  406.                 continue;
  407.             if(k <= 0){
  408.                 if(piececount(mover,0,18) != 0)
  409.                     break;
  410.                 if((j+die2) != 25 && piececount(mover,19,j-1) != 0)
  411.                     break;
  412.             }
  413.             mover[j]--;
  414.             mover[j+die2]++;
  415.             count = 2;
  416.             if(die1 != die2){
  417.                 moverecord(mover);
  418.                 if(mover[0] > 0)
  419.                     break;
  420.                 else
  421.                     continue;
  422.             }
  423.             for(l = 0; l <= 24; l++){
  424.                 if(mover[l] == 0)
  425.                     continue;
  426.                 if((k=25-l-die1) > 0 && movee[k] >= 2)
  427.                     if(mover[0] > 0)
  428.                         break;
  429.                 else
  430.                     continue;
  431.                 if(k <= 0){
  432.                     if(piececount(mover, 0, 18) != 0)
  433.                         break;
  434.                     if((l+die2) != 25 && piececount(mover,19,l-1) != 0)
  435.                         break;
  436.                 }
  437.                 mover[l]--;
  438.                 mover[l+die1]++;
  439.                 count=3;
  440.                 for(m=0;m<=24;m++){
  441.                     if(mover[m]==0)
  442.                         continue;
  443.                     if((k=25-m-die1) >= 0 && movee[k] >= 2)
  444.                         if(mover[0] > 0)
  445.                             break;
  446.                     else
  447.                         continue;
  448.                     if(k <= 0){
  449.                         if(piececount(mover,0,18) != 0)
  450.                             break;
  451.                         if((m+die2) != 25 && piececount(mover,19,m-1) != 0)
  452.                             break;
  453.                     }
  454.                     count=4;
  455.                     moverecord(mover);
  456.                     if(mover[0] > 0)
  457.                         break;
  458.                 }
  459.                 if(count == 3)
  460.                     moverecord(mover);
  461.                 else{
  462.                     mover[l]++;
  463.                     mover[l+die1]--;
  464.                 }
  465.                 if(mover[0] > 0)
  466.                     break;
  467.             }
  468.             if(count == 2)
  469.                 moverecord(mover);
  470.             else{
  471.                 mover[j]++;
  472.                 mover[j+die1]--;
  473.             }
  474.             if(mover[0] > 0)
  475.                 break;
  476.         }
  477.         if(count == 1)
  478.             moverecord(mover);
  479.         else{
  480.             mover[i]++;
  481.             mover[i+die1]--;
  482.         }
  483.         if(mover[0] > 0)
  484.             break;
  485.     }
  486. }
  487. moverecord(mover)
  488. int *mover;
  489. {
  490.     int    t;
  491.  
  492.     if(imoves < MAXIMOVES) {
  493.         for(t = 0; t <= 3; t++)
  494.             moves[imoves].pos[t] = NIL;
  495.         switch(count) {
  496.         case 4:
  497.             moves[imoves].pos[3]=m;
  498.             moves[imoves].mov[3]=die1;
  499.  
  500.         case 3:
  501.             moves[imoves].pos[2]=l;
  502.             moves[imoves].mov[2]=die1;
  503.  
  504.         case 2:
  505.             moves[imoves].pos[1]=j;
  506.             moves[imoves].mov[1]=die2;
  507.  
  508.         case 1:
  509.             moves[imoves].pos[0]=i;
  510.             moves[imoves].mov[0]=die1;
  511.             imoves++;
  512.         }
  513.     }
  514.     switch(count) {
  515.     case 4:
  516.         break;
  517.  
  518.     case 3:
  519.         mover[l]++;
  520.         mover[l+die1]--;
  521.         break;
  522.  
  523.     case 2:
  524.         mover[j]++;
  525.         mover[j+die2]--;
  526.         break;
  527.  
  528.     case 1:
  529.         mover[i]++;
  530.         mover[i+die1]--;
  531.     }
  532. }
  533.  
  534. strategy(player,playee)
  535. int *player,*playee;
  536. {
  537.     int    k, n, nn, bestval, moveval, prob;
  538.  
  539.     n = 0;
  540.     if(imoves == 0)
  541.         return(NIL);
  542.     goodmoves[0] = NIL;
  543.     bestval = -32000;
  544.     for(k = 0; k < imoves; k++){
  545.         if((moveval=eval(player,playee,k,&prob)) < bestval)
  546.             continue;
  547.         if(moveval > bestval){
  548.             bestval = moveval;
  549.             n = 0;
  550.         }
  551.         if(n<MAXGMOV){
  552.             goodmoves[n]=k;
  553.             probmoves[n++]=prob;
  554.         }
  555.     }
  556.     if(level=='e' && n>1){
  557.         nn=n;
  558.         n=0;
  559.         prob=32000;
  560.         for(k = 0; k < nn; k++){
  561.             if((moveval=probmoves[k]) > prob)
  562.                 continue;
  563.             if(moveval<prob){
  564.                 prob=moveval;
  565.                 n=0;
  566.             }
  567.             goodmoves[n]=goodmoves[k];
  568.             probmoves[n++]=probmoves[k];
  569.         }
  570.     }
  571.     return(goodmoves[(rand()>>4)%n]);
  572. }
  573.  
  574. eval(player,playee,k,prob)
  575. int *player,*playee,k,*prob;
  576. {
  577.     int    newtry[31], newother[31], *r, *q, *p, n, sum, first;
  578.     int    ii, lastwhite, lastbrown;
  579.  
  580.     *prob = sum = 0;
  581.     r = player+25;
  582.     p = newtry;
  583.     q = newother;
  584.     while(player<r){
  585.         *p++= *player++;
  586.         *q++= *playee++;
  587.     }
  588.     q=newtry+31;
  589.     for(p = newtry+25; p < q; p++)        /* zero out spaces for hit pieces */
  590.         *p = 0;
  591.     for(n = 0; n < 4; n++){
  592.         if(moves[k].pos[n] == NIL)
  593.             break;
  594.         newtry[moves[k].pos[n]]--;
  595.         newtry[ii=moves[k].pos[n]+moves[k].mov[n]]++;
  596.         if(ii<25 && newother[25-ii]==1){
  597.             newother[25-ii]=0;
  598.             newother[0]++;
  599.             if(ii<=15 && level=='e')        /* hit if near other's home */
  600.                 sum++;
  601.         }
  602.     }
  603.     for(lastbrown = 0; newother[lastbrown] == 0; lastbrown++);
  604.         ;
  605.     for(lastwhite = 0; newtry[lastwhite] == 0; lastwhite++)
  606.         ;
  607.     lastwhite = 25-lastwhite;
  608.     if(lastwhite<=6 && lastwhite<lastbrown)
  609.         sum=1000;
  610.                                     /* experts running game. */
  611.                                     /* first priority is to */
  612.                                     /* get all pieces into */
  613.                                     /* white's home */
  614.     if(lastwhite<lastbrown && level=='e' && lastwhite>6) {
  615.         for(sum = 1000; lastwhite > 6; lastwhite--)
  616.             sum = sum-lastwhite*newtry[25-lastwhite];
  617.     }
  618.     for(first = 0; first < 25; first++)
  619.         if(newother[first] != 0)        /*find other's first piece*/
  620.             break;
  621.     q = newtry+25;
  622.     for(p = newtry+1; p < q;)            /* blocked points are good */
  623.         if(*p++ > 1)
  624.             sum++;
  625.     if(first > 5) {                    /* only stress removing pieces if */
  626.                             /* homeboard cannot be hit */
  627.         q = newtry+31;
  628.         p=newtry+25;
  629.         for(n = 6; p < q; n--)
  630.             sum += *p++ * n;            /*remove pieces, but just barely*/
  631.     }
  632.     if(level != 'b'){
  633.         r = newtry+25-first;    /*singles past this point can't be hit*/
  634.         for(p = newtry+7; p < r; )
  635.             if(*p++ == 1)        /*singles are bad after 1st 6 points if they can be hit*/
  636.                 sum--;
  637.         q = newtry+3;
  638.         for(p = newtry; p < q; )       /*bad to be on 1st three points*/
  639.             sum -= *p++;
  640.     }
  641.  
  642.     for(n = 1; n <= 4; n++)
  643.         *prob += n*getprob(newtry,newother,6*n-5,6*n);
  644.     return(sum);
  645. }
  646. instructions()
  647. {
  648.     register fd, r;
  649.     char     buf[BUFSIZ];
  650.  
  651.     if((fd = open(RULES, 0)) < 0) {
  652.         fprintf(stderr, "back: cannot open %s\n", RULES);
  653.         return;
  654.     }
  655.     while(r = read(fd, buf, BUFSIZ))
  656.         write(1, buf, r);
  657. }
  658.  
  659. getprob(player,playee,start,finish)
  660. int *player,*playee,start,finish;
  661. {            /*returns the probability (times 102) that any
  662.               pieces belonging to 'player' and lying between
  663.               his points 'start' and 'finish' will be hit
  664.               by a piece belonging to playee
  665.             */
  666.     int    k, n, sum;
  667.  
  668.     sum = 0;
  669.     for(; start <= finish; start++){
  670.         if(player[start] == 1){
  671.             for(k = 1; k <= 12; k++){
  672.                 if((n=25-start-k) < 0)
  673.                     break;
  674.                 if(playee[n] != 0)
  675.                     sum += probability[k];
  676.             }
  677.         }
  678.     }
  679.     return(sum);
  680. }
  681. prtbrd()
  682. {
  683.     int    k;
  684.     static char undersc[]="______________________________________________________";
  685.  
  686.     fprintf(stdout, "White's Home\n%s\r",undersc);
  687.     for(k = 1; k <= 6; k++)
  688.         fprintf(stdout, "%4d",k);
  689.     fprintf(stdout, "    ");
  690.     for(k = 7; k <= 12; k++)
  691.         fprintf(stdout, "%4d",k); 
  692.     putchar('\n');
  693.     numline(brown, white, 1, 6);
  694.     fprintf(stdout, "    ");
  695.     numline(brown, white, 7, 12);
  696.     putchar('\n');
  697.     colorline(brown, 'B', white, 'W', 1, 6);
  698.     fprintf(stdout, "    ");
  699.     colorline(brown, 'B', white, 'W', 7, 12);
  700.     putchar('\n');
  701.     if(white[0] != 0)
  702.         fprintf(stdout, "%28dW\n",white[0]);
  703.     else
  704.         putchar('\n');
  705.     if(brown[0] != 0)
  706.         fprintf(stdout, "%28dB\n", brown[0]);
  707.     else
  708.         putchar('\n');
  709.     colorline(white, 'W', brown, 'B', 1, 6);
  710.     fprintf(stdout, "    ");
  711.     colorline(white, 'W', brown, 'B', 7, 12);
  712.     fprintf(stdout, "\n%s\r",undersc);
  713.     numline(white, brown, 1, 6);
  714.     fprintf(stdout, "    ");
  715.     numline(white, brown, 7, 12);
  716.     putchar('\n');
  717.     for(k = 24; k >= 19; k--)
  718.         fprintf(stdout, "%4d",k);
  719.     fprintf(stdout, "    ");
  720.     for(k = 18; k >= 13; k--)
  721.         fprintf(stdout, "%4d",k);
  722.     fprintf(stdout, "\nBrown's Home\n\n\n\n\n");
  723. }
  724. numline(upcol,downcol,start,fin)
  725. int *upcol,*downcol,start,fin;
  726. {
  727.     int    k, n;
  728.  
  729.     for(k = start; k <= fin; k++){
  730.         if((n = upcol[k]) != 0 || (n = downcol[25-k]) != 0)
  731.             fprintf(stdout, "%4d", n);
  732.         else
  733.             fprintf(stdout, "    ");
  734.     }
  735. }
  736. colorline(upcol,c1,downcol,c2,start,fin)
  737. int *upcol,*downcol,start,fin;
  738. char c1,c2;
  739. {
  740.     int    k;
  741.     char     c;
  742.  
  743.     for(k = start; k <= fin; k++){
  744.         c = ' ';
  745.         if(upcol[k] != 0)
  746.             c = c1;
  747.         if(downcol[25-k] != 0)
  748.             c = c2;
  749.         fprintf(stdout, "   %c",c);
  750.     }
  751. }
  752.