18ccff702Sbostic #ifndef lint
2*32792795Sbostic static char sccsid[] = "@(#)btlgammon.c 1.2 (Berkeley) 09/20/87";
38ccff702Sbostic #endif not lint
48ccff702Sbostic
58ccff702Sbostic /*
68ccff702Sbostic ** The game of Backgammon
78ccff702Sbostic */
88ccff702Sbostic
98ccff702Sbostic #include <stdio.h>
108ccff702Sbostic
118ccff702Sbostic #define WHITE 0
128ccff702Sbostic #define BROWN 1
138ccff702Sbostic #define NIL (-1)
148ccff702Sbostic #define MAXGMOV 10
158ccff702Sbostic #define MAXIMOVES 1000
168ccff702Sbostic #define RULES "/usr/games/lib/backrules"
178ccff702Sbostic
188ccff702Sbostic char level; /*'b'=beginner, 'i'=intermediate, 'e'=expert*/
198ccff702Sbostic
208ccff702Sbostic int die1;
218ccff702Sbostic int die2;
228ccff702Sbostic int i;
238ccff702Sbostic int j;
248ccff702Sbostic int l;
258ccff702Sbostic int m;
268ccff702Sbostic int pflg = 1;
278ccff702Sbostic int nobroll = 0;
288ccff702Sbostic int count;
298ccff702Sbostic int imoves;
308ccff702Sbostic int goodmoves[MAXGMOV];
318ccff702Sbostic int probmoves[MAXGMOV];
328ccff702Sbostic
338ccff702Sbostic int brown[] = { /* brown position table */
348ccff702Sbostic 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
358ccff702Sbostic 0, 0, 0, 0, 3, 0, 5, 0, 0, 0, 0, 0,
368ccff702Sbostic 0, 0, 0, 0, 0, 0
378ccff702Sbostic };
388ccff702Sbostic
398ccff702Sbostic int white[] = { /* white position table */
408ccff702Sbostic 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
418ccff702Sbostic 0, 0, 0, 0, 3, 0, 5, 0, 0, 0, 0, 0,
428ccff702Sbostic 0, 0, 0, 0, 0, 0
438ccff702Sbostic };
448ccff702Sbostic
458ccff702Sbostic int probability[] = {
468ccff702Sbostic 0, 11, 12, 13, 14, 15, 16,
478ccff702Sbostic 06, 05, 04, 03, 02, 01
488ccff702Sbostic };
498ccff702Sbostic
508ccff702Sbostic struct {
518ccff702Sbostic int pos[4];
528ccff702Sbostic int mov[4];
538ccff702Sbostic } moves[MAXIMOVES];
548ccff702Sbostic
main()558ccff702Sbostic main()
568ccff702Sbostic {
578ccff702Sbostic int go[5], tvec[2];
588ccff702Sbostic int k, n, pid, ret, rpid, t;
598ccff702Sbostic char s[100];
608ccff702Sbostic
618ccff702Sbostic srand(time(0));
628ccff702Sbostic go[5] = NIL;
638ccff702Sbostic fprintf(stdout, "Instructions? ");
648ccff702Sbostic gets(s);
658ccff702Sbostic if(*s == 'y')
668ccff702Sbostic instructions();
678ccff702Sbostic putchar('\n');
688ccff702Sbostic fprintf(stdout, "Opponent's level: b - beginner,\n");
698ccff702Sbostic fprintf(stdout, "i - intermediate, e - expert? ");
708ccff702Sbostic level='e';
718ccff702Sbostic gets(s);
728ccff702Sbostic if(*s == 'b')
738ccff702Sbostic level = 'b';
748ccff702Sbostic else if(*s == 'i')
758ccff702Sbostic level = 'i';
768ccff702Sbostic putchar('\n');
778ccff702Sbostic fprintf(stdout, "You will play brown.\n\n");
788ccff702Sbostic fprintf(stdout, "Would you like to roll your own dice? ");
798ccff702Sbostic gets(s);
808ccff702Sbostic putchar('\n');
818ccff702Sbostic if(*s == 'y')
828ccff702Sbostic nobroll = 1;
838ccff702Sbostic fprintf(stdout, "Would you like to go first? ");
848ccff702Sbostic gets(s);
858ccff702Sbostic putchar('\n');
868ccff702Sbostic if(*s == 'y')
878ccff702Sbostic goto nowhmove;
888ccff702Sbostic whitesmv:
898ccff702Sbostic roll(WHITE);
908ccff702Sbostic fprintf(stdout, "white rolls %d, %d\n", die1, die2);
918ccff702Sbostic fprintf(stdout, "white's move is:");
928ccff702Sbostic if(nextmove(white, brown) == NIL)
938ccff702Sbostic goto nowhmove;
948ccff702Sbostic if(piececount(white, 0, 24) == 0){
958ccff702Sbostic fprintf(stdout, "White wins");
968ccff702Sbostic if(piececount(brown, 0, 6) != 0)
978ccff702Sbostic fprintf(stdout, " with a Backgammon!\n");
988ccff702Sbostic else if (piececount(brown, 0, 24) == 24)
998ccff702Sbostic fprintf(stdout, " with a Gammon.\n");
1008ccff702Sbostic else
1018ccff702Sbostic fprintf(stdout, ".\n");
1028ccff702Sbostic exit(0);
1038ccff702Sbostic }
1048ccff702Sbostic nowhmove:
1058ccff702Sbostic if(pflg)
1068ccff702Sbostic prtbrd();
1078ccff702Sbostic roll(BROWN);
1088ccff702Sbostic retry:
1098ccff702Sbostic fprintf(stdout, "\nYour roll is %d %d\n", die1, die2);
1108ccff702Sbostic fprintf(stdout, "Move? ");
1118ccff702Sbostic gets(s);
1128ccff702Sbostic switch(*s) {
1138ccff702Sbostic case '\0': /* empty line */
1148ccff702Sbostic fprintf(stdout, "Brown's move skipped.\n");
1158ccff702Sbostic goto whitesmv;
1168ccff702Sbostic
1178ccff702Sbostic case 'b': /* how many beared off? */
1188ccff702Sbostic fprintf(stdout, "Brown: %d\n", piececount(brown, 0, 24) - 15);
1198ccff702Sbostic fprintf(stdout, "White: %d\n", piececount(white, 0, 24) - 15);
1208ccff702Sbostic goto retry;
1218ccff702Sbostic
1228ccff702Sbostic case 'p': /* print board */
1238ccff702Sbostic prtbrd();
1248ccff702Sbostic goto retry;
1258ccff702Sbostic
1268ccff702Sbostic case 's': /* stop auto printing of board */
1278ccff702Sbostic pflg = 0;
1288ccff702Sbostic goto retry;
1298ccff702Sbostic
1308ccff702Sbostic case 'r': /* resume auto printing */
1318ccff702Sbostic pflg = 1;
1328ccff702Sbostic goto retry;
1338ccff702Sbostic
1348ccff702Sbostic case 'm': /* print possible moves */
1358ccff702Sbostic pmoves();
1368ccff702Sbostic goto retry;
1378ccff702Sbostic
1388ccff702Sbostic case 'q': /* i give up */
1398ccff702Sbostic exit(0);
1408ccff702Sbostic
1418ccff702Sbostic case '!': /* escape to Shell */
142*32792795Sbostic #ifdef ADD_A_MAJOR_SECURITY_HOLE
1438ccff702Sbostic if(s[1] != '\0')
1448ccff702Sbostic system(s+1);
145*32792795Sbostic else
146*32792795Sbostic #endif
147*32792795Sbostic if (!(pid = vfork()) == 0) {
148*32792795Sbostic (void)setuid(getuid());
149*32792795Sbostic (void)setgid(getgid());
1508ccff702Sbostic execl("/bin/sh", "sh", "-", 0);
1518ccff702Sbostic fprintf(stderr, "back: cannot exec /bin/sh!\n");
1528ccff702Sbostic exit(2);
1538ccff702Sbostic }
1548ccff702Sbostic while((rpid = wait(&ret)) != pid && rpid != -1)
1558ccff702Sbostic ;
1568ccff702Sbostic goto retry;
1578ccff702Sbostic
1588ccff702Sbostic case '?': /* well, what can i do? */
1598ccff702Sbostic fprintf(stdout, "<newline> skip this move\n");
1608ccff702Sbostic fprintf(stdout, "b number beared off\n");
1618ccff702Sbostic fprintf(stdout, "p print board\n");
1628ccff702Sbostic fprintf(stdout, "q quit\n");
1638ccff702Sbostic fprintf(stdout, "r resume auto print of board\n");
1648ccff702Sbostic fprintf(stdout, "s stop auto print of board\n");
1658ccff702Sbostic fprintf(stdout, "! escape to Shell\n");
1668ccff702Sbostic goto retry;
1678ccff702Sbostic }
1688ccff702Sbostic n = sscanf(s,"%d%d%d%d%d",&go[0],&go[1],&go[2],&go[3],&go[4]);
1698ccff702Sbostic if((die1 != die2 && n > 2) || n > 4){
1708ccff702Sbostic fprintf(stdout, "Too many moves.\n");
1718ccff702Sbostic goto retry;
1728ccff702Sbostic }
1738ccff702Sbostic go[n] = NIL;
1748ccff702Sbostic if(*s=='-'){
1758ccff702Sbostic go[0]= -go[0];
1768ccff702Sbostic t=die1;
1778ccff702Sbostic die1=die2;
1788ccff702Sbostic die2=t;
1798ccff702Sbostic }
1808ccff702Sbostic for(k = 0; k < n; k++){
1818ccff702Sbostic if(0 <= go[k] && go[k] <= 24)
1828ccff702Sbostic continue;
1838ccff702Sbostic else{
1848ccff702Sbostic fprintf(stdout, "Move %d illegal.\n", go[k]);
1858ccff702Sbostic goto retry;
1868ccff702Sbostic }
1878ccff702Sbostic }
1888ccff702Sbostic if(play(brown, white, go))
1898ccff702Sbostic goto retry;
1908ccff702Sbostic if(piececount(brown, 0, 24) == 0){
1918ccff702Sbostic fprintf(stdout, "Brown wins");
1928ccff702Sbostic if(piececount(white, 0, 6) != 0)
1938ccff702Sbostic fprintf(stdout, " with a Backgammon.\n");
1948ccff702Sbostic else if(piececount(white, 0, 24) == 24)
1958ccff702Sbostic fprintf(stdout, " with a gammon.\n");
1968ccff702Sbostic else
1978ccff702Sbostic fprintf(stdout, ".\n");
1988ccff702Sbostic exit(0);
1998ccff702Sbostic }
2008ccff702Sbostic goto whitesmv;
2018ccff702Sbostic }
2028ccff702Sbostic
play(player,playee,pos)2038ccff702Sbostic play(player,playee,pos)
2048ccff702Sbostic int *player,*playee,pos[];
2058ccff702Sbostic {
2068ccff702Sbostic int k, n, die, ipos;
2078ccff702Sbostic
2088ccff702Sbostic for(k=0; k < player[0]; k++){ /*blots on player[0] must be moved first*/
2098ccff702Sbostic if(pos[k] == NIL)
2108ccff702Sbostic break;
2118ccff702Sbostic if(pos[k] != 0){
2128ccff702Sbostic fprintf(stdout, "Stone on bar must be moved first.\n");
2138ccff702Sbostic return(NIL);
2148ccff702Sbostic }
2158ccff702Sbostic }
2168ccff702Sbostic for(k = 0; (ipos=pos[k]) != NIL; k++){
2178ccff702Sbostic die = k?die2:die1;
2188ccff702Sbostic n = 25-ipos-die;
2198ccff702Sbostic if(player[ipos] == 0)
2208ccff702Sbostic goto badmove;
2218ccff702Sbostic if(n > 0 && playee[n] >= 2)
2228ccff702Sbostic goto badmove;
2238ccff702Sbostic if(n <= 0){
2248ccff702Sbostic if(piececount(player,0,18) != 0)
2258ccff702Sbostic goto badmove;
2268ccff702Sbostic if((ipos+die) != 25 && piececount(player,19,24-die)!=0)
2278ccff702Sbostic goto badmove;
2288ccff702Sbostic }
2298ccff702Sbostic player[ipos]--;
2308ccff702Sbostic player[ipos+die]++;
2318ccff702Sbostic }
2328ccff702Sbostic for(k = 0; pos[k] != NIL; k++){
2338ccff702Sbostic die = k?die2:die1;
2348ccff702Sbostic n = 25-pos[k]-die;
2358ccff702Sbostic if(n>0 && playee[n]==1){
2368ccff702Sbostic playee[n]=0;
2378ccff702Sbostic playee[0]++;
2388ccff702Sbostic }
2398ccff702Sbostic }
2408ccff702Sbostic return(0);
2418ccff702Sbostic
2428ccff702Sbostic badmove:
2438ccff702Sbostic fprintf(stdout, "Move %d illegal.\n", ipos);
2448ccff702Sbostic while(k--){
2458ccff702Sbostic die=k?die2:die1;
2468ccff702Sbostic player[pos[k]]++;
2478ccff702Sbostic player[pos[k]+die]--;
2488ccff702Sbostic }
2498ccff702Sbostic return(NIL);
2508ccff702Sbostic }
nextmove(player,playee)2518ccff702Sbostic nextmove(player,playee)
2528ccff702Sbostic int *player,*playee;
2538ccff702Sbostic {
2548ccff702Sbostic int k;
2558ccff702Sbostic
2568ccff702Sbostic imoves=0;
2578ccff702Sbostic movegen(player,playee);
2588ccff702Sbostic if(die1!=die2){
2598ccff702Sbostic k=die1;
2608ccff702Sbostic die1=die2;
2618ccff702Sbostic die2=k;
2628ccff702Sbostic movegen(player,playee);
2638ccff702Sbostic }
2648ccff702Sbostic if(imoves==0){
2658ccff702Sbostic fprintf(stdout, "no move possible.\n");
2668ccff702Sbostic return(NIL);
2678ccff702Sbostic }
2688ccff702Sbostic k=strategy(player,playee); /*select kth possible move*/
2698ccff702Sbostic prtmov(k);
2708ccff702Sbostic update(player,playee,k);
2718ccff702Sbostic return(0);
2728ccff702Sbostic }
prtmov(k)2738ccff702Sbostic prtmov(k)
2748ccff702Sbostic int k;
2758ccff702Sbostic {
2768ccff702Sbostic int n;
2778ccff702Sbostic
2788ccff702Sbostic if(k == NIL)
2798ccff702Sbostic fprintf(stdout, "No move possible\n");
2808ccff702Sbostic else for(n = 0; n < 4; n++){
2818ccff702Sbostic if(moves[k].pos[n] == NIL)
2828ccff702Sbostic break;
2838ccff702Sbostic fprintf(stdout, " %d, %d",25-moves[k].pos[n],moves[k].mov[n]);
2848ccff702Sbostic }
2858ccff702Sbostic fprintf(stdout, "\n");
2868ccff702Sbostic }
update(player,playee,k)2878ccff702Sbostic update(player,playee,k)
2888ccff702Sbostic int *player,*playee,k;
2898ccff702Sbostic {
2908ccff702Sbostic int n,t;
2918ccff702Sbostic
2928ccff702Sbostic for(n = 0; n < 4; n++){
2938ccff702Sbostic if(moves[k].pos[n] == NIL)
2948ccff702Sbostic break;
2958ccff702Sbostic player[moves[k].pos[n]]--;
2968ccff702Sbostic player[moves[k].pos[n]+moves[k].mov[n]]++;
2978ccff702Sbostic t=25-moves[k].pos[n]-moves[k].mov[n];
2988ccff702Sbostic if(t>0 && playee[t]==1){
2998ccff702Sbostic playee[0]++;
3008ccff702Sbostic playee[t]--;
3018ccff702Sbostic }
3028ccff702Sbostic }
3038ccff702Sbostic }
piececount(player,startrow,endrow)3048ccff702Sbostic piececount(player,startrow,endrow)
3058ccff702Sbostic int *player,startrow,endrow;
3068ccff702Sbostic {
3078ccff702Sbostic int sum;
3088ccff702Sbostic
3098ccff702Sbostic sum=0;
3108ccff702Sbostic while(startrow <= endrow)
3118ccff702Sbostic sum += player[startrow++];
3128ccff702Sbostic return(sum);
3138ccff702Sbostic }
pmoves()3148ccff702Sbostic pmoves()
3158ccff702Sbostic {
3168ccff702Sbostic int i1, i2;
3178ccff702Sbostic
3188ccff702Sbostic fprintf(stdout, "Possible moves are:\n");
3198ccff702Sbostic for(i1 = 0; i1 < imoves; i1++){
3208ccff702Sbostic fprintf(stdout, "\n%d",i1);
3218ccff702Sbostic for (i2 = 0; i2<4; i2++){
3228ccff702Sbostic if(moves[i1].pos[i2] == NIL)
3238ccff702Sbostic break;
3248ccff702Sbostic fprintf(stdout, "%d, %d",moves[i1].pos[i2],moves[i1].mov[i2]);
3258ccff702Sbostic }
3268ccff702Sbostic }
3278ccff702Sbostic fprintf(stdout, "\n");
3288ccff702Sbostic }
3298ccff702Sbostic
roll(who)3308ccff702Sbostic roll(who)
3318ccff702Sbostic {
3328ccff702Sbostic register n;
3338ccff702Sbostic char s[10];
3348ccff702Sbostic
3358ccff702Sbostic if(who == BROWN && nobroll) {
3368ccff702Sbostic fprintf(stdout, "Roll? ");
3378ccff702Sbostic gets(s);
3388ccff702Sbostic n = sscanf(s, "%d%d", &die1, &die2);
3398ccff702Sbostic if(n != 2 || die1 < 1 || die1 > 6 || die2 < 1 || die2 > 6)
3408ccff702Sbostic fprintf(stdout, "Illegal - I'll do it!\n");
3418ccff702Sbostic else
3428ccff702Sbostic return;
3438ccff702Sbostic }
3448ccff702Sbostic die1 = ((rand()>>8) % 6) + 1;
3458ccff702Sbostic die2 = ((rand()>>8) % 6) + 1;
3468ccff702Sbostic }
3478ccff702Sbostic
movegen(mover,movee)3488ccff702Sbostic movegen(mover,movee)
3498ccff702Sbostic int *mover,*movee;
3508ccff702Sbostic {
3518ccff702Sbostic int k;
3528ccff702Sbostic
3538ccff702Sbostic for(i = 0; i <= 24; i++){
3548ccff702Sbostic count = 0;
3558ccff702Sbostic if(mover[i] == 0)
3568ccff702Sbostic continue;
3578ccff702Sbostic if((k=25-i-die1) > 0 && movee[k] >= 2)
3588ccff702Sbostic if(mover[0] > 0)
3598ccff702Sbostic break;
3608ccff702Sbostic else
3618ccff702Sbostic continue;
3628ccff702Sbostic if(k <= 0){
3638ccff702Sbostic if(piececount(mover, 0, 18) != 0)
3648ccff702Sbostic break;
3658ccff702Sbostic if((i+die1) != 25 && piececount(mover,19,i-1) != 0)
3668ccff702Sbostic break;
3678ccff702Sbostic }
3688ccff702Sbostic mover[i]--;
3698ccff702Sbostic mover[i+die1]++;
3708ccff702Sbostic count = 1;
3718ccff702Sbostic for(j = 0; j <= 24; j++){
3728ccff702Sbostic if(mover[j]==0)
3738ccff702Sbostic continue;
3748ccff702Sbostic if((k=25-j-die2) > 0 && movee[k] >= 2)
3758ccff702Sbostic if(mover[0] > 0)
3768ccff702Sbostic break;
3778ccff702Sbostic else
3788ccff702Sbostic continue;
3798ccff702Sbostic if(k <= 0){
3808ccff702Sbostic if(piececount(mover,0,18) != 0)
3818ccff702Sbostic break;
3828ccff702Sbostic if((j+die2) != 25 && piececount(mover,19,j-1) != 0)
3838ccff702Sbostic break;
3848ccff702Sbostic }
3858ccff702Sbostic mover[j]--;
3868ccff702Sbostic mover[j+die2]++;
3878ccff702Sbostic count = 2;
3888ccff702Sbostic if(die1 != die2){
3898ccff702Sbostic moverecord(mover);
3908ccff702Sbostic if(mover[0] > 0)
3918ccff702Sbostic break;
3928ccff702Sbostic else
3938ccff702Sbostic continue;
3948ccff702Sbostic }
3958ccff702Sbostic for(l = 0; l <= 24; l++){
3968ccff702Sbostic if(mover[l] == 0)
3978ccff702Sbostic continue;
3988ccff702Sbostic if((k=25-l-die1) > 0 && movee[k] >= 2)
3998ccff702Sbostic if(mover[0] > 0)
4008ccff702Sbostic break;
4018ccff702Sbostic else
4028ccff702Sbostic continue;
4038ccff702Sbostic if(k <= 0){
4048ccff702Sbostic if(piececount(mover, 0, 18) != 0)
4058ccff702Sbostic break;
4068ccff702Sbostic if((l+die2) != 25 && piececount(mover,19,l-1) != 0)
4078ccff702Sbostic break;
4088ccff702Sbostic }
4098ccff702Sbostic mover[l]--;
4108ccff702Sbostic mover[l+die1]++;
4118ccff702Sbostic count=3;
4128ccff702Sbostic for(m=0;m<=24;m++){
4138ccff702Sbostic if(mover[m]==0)
4148ccff702Sbostic continue;
4158ccff702Sbostic if((k=25-m-die1) >= 0 && movee[k] >= 2)
4168ccff702Sbostic if(mover[0] > 0)
4178ccff702Sbostic break;
4188ccff702Sbostic else
4198ccff702Sbostic continue;
4208ccff702Sbostic if(k <= 0){
4218ccff702Sbostic if(piececount(mover,0,18) != 0)
4228ccff702Sbostic break;
4238ccff702Sbostic if((m+die2) != 25 && piececount(mover,19,m-1) != 0)
4248ccff702Sbostic break;
4258ccff702Sbostic }
4268ccff702Sbostic count=4;
4278ccff702Sbostic moverecord(mover);
4288ccff702Sbostic if(mover[0] > 0)
4298ccff702Sbostic break;
4308ccff702Sbostic }
4318ccff702Sbostic if(count == 3)
4328ccff702Sbostic moverecord(mover);
4338ccff702Sbostic else{
4348ccff702Sbostic mover[l]++;
4358ccff702Sbostic mover[l+die1]--;
4368ccff702Sbostic }
4378ccff702Sbostic if(mover[0] > 0)
4388ccff702Sbostic break;
4398ccff702Sbostic }
4408ccff702Sbostic if(count == 2)
4418ccff702Sbostic moverecord(mover);
4428ccff702Sbostic else{
4438ccff702Sbostic mover[j]++;
4448ccff702Sbostic mover[j+die1]--;
4458ccff702Sbostic }
4468ccff702Sbostic if(mover[0] > 0)
4478ccff702Sbostic break;
4488ccff702Sbostic }
4498ccff702Sbostic if(count == 1)
4508ccff702Sbostic moverecord(mover);
4518ccff702Sbostic else{
4528ccff702Sbostic mover[i]++;
4538ccff702Sbostic mover[i+die1]--;
4548ccff702Sbostic }
4558ccff702Sbostic if(mover[0] > 0)
4568ccff702Sbostic break;
4578ccff702Sbostic }
4588ccff702Sbostic }
moverecord(mover)4598ccff702Sbostic moverecord(mover)
4608ccff702Sbostic int *mover;
4618ccff702Sbostic {
4628ccff702Sbostic int t;
4638ccff702Sbostic
4648ccff702Sbostic if(imoves < MAXIMOVES) {
4658ccff702Sbostic for(t = 0; t <= 3; t++)
4668ccff702Sbostic moves[imoves].pos[t] = NIL;
4678ccff702Sbostic switch(count) {
4688ccff702Sbostic case 4:
4698ccff702Sbostic moves[imoves].pos[3]=m;
4708ccff702Sbostic moves[imoves].mov[3]=die1;
4718ccff702Sbostic
4728ccff702Sbostic case 3:
4738ccff702Sbostic moves[imoves].pos[2]=l;
4748ccff702Sbostic moves[imoves].mov[2]=die1;
4758ccff702Sbostic
4768ccff702Sbostic case 2:
4778ccff702Sbostic moves[imoves].pos[1]=j;
4788ccff702Sbostic moves[imoves].mov[1]=die2;
4798ccff702Sbostic
4808ccff702Sbostic case 1:
4818ccff702Sbostic moves[imoves].pos[0]=i;
4828ccff702Sbostic moves[imoves].mov[0]=die1;
4838ccff702Sbostic imoves++;
4848ccff702Sbostic }
4858ccff702Sbostic }
4868ccff702Sbostic switch(count) {
4878ccff702Sbostic case 4:
4888ccff702Sbostic break;
4898ccff702Sbostic
4908ccff702Sbostic case 3:
4918ccff702Sbostic mover[l]++;
4928ccff702Sbostic mover[l+die1]--;
4938ccff702Sbostic break;
4948ccff702Sbostic
4958ccff702Sbostic case 2:
4968ccff702Sbostic mover[j]++;
4978ccff702Sbostic mover[j+die2]--;
4988ccff702Sbostic break;
4998ccff702Sbostic
5008ccff702Sbostic case 1:
5018ccff702Sbostic mover[i]++;
5028ccff702Sbostic mover[i+die1]--;
5038ccff702Sbostic }
5048ccff702Sbostic }
5058ccff702Sbostic
strategy(player,playee)5068ccff702Sbostic strategy(player,playee)
5078ccff702Sbostic int *player,*playee;
5088ccff702Sbostic {
5098ccff702Sbostic int k, n, nn, bestval, moveval, prob;
5108ccff702Sbostic
5118ccff702Sbostic n = 0;
5128ccff702Sbostic if(imoves == 0)
5138ccff702Sbostic return(NIL);
5148ccff702Sbostic goodmoves[0] = NIL;
5158ccff702Sbostic bestval = -32000;
5168ccff702Sbostic for(k = 0; k < imoves; k++){
5178ccff702Sbostic if((moveval=eval(player,playee,k,&prob)) < bestval)
5188ccff702Sbostic continue;
5198ccff702Sbostic if(moveval > bestval){
5208ccff702Sbostic bestval = moveval;
5218ccff702Sbostic n = 0;
5228ccff702Sbostic }
5238ccff702Sbostic if(n<MAXGMOV){
5248ccff702Sbostic goodmoves[n]=k;
5258ccff702Sbostic probmoves[n++]=prob;
5268ccff702Sbostic }
5278ccff702Sbostic }
5288ccff702Sbostic if(level=='e' && n>1){
5298ccff702Sbostic nn=n;
5308ccff702Sbostic n=0;
5318ccff702Sbostic prob=32000;
5328ccff702Sbostic for(k = 0; k < nn; k++){
5338ccff702Sbostic if((moveval=probmoves[k]) > prob)
5348ccff702Sbostic continue;
5358ccff702Sbostic if(moveval<prob){
5368ccff702Sbostic prob=moveval;
5378ccff702Sbostic n=0;
5388ccff702Sbostic }
5398ccff702Sbostic goodmoves[n]=goodmoves[k];
5408ccff702Sbostic probmoves[n++]=probmoves[k];
5418ccff702Sbostic }
5428ccff702Sbostic }
5438ccff702Sbostic return(goodmoves[(rand()>>4)%n]);
5448ccff702Sbostic }
5458ccff702Sbostic
eval(player,playee,k,prob)5468ccff702Sbostic eval(player,playee,k,prob)
5478ccff702Sbostic int *player,*playee,k,*prob;
5488ccff702Sbostic {
5498ccff702Sbostic int newtry[31], newother[31], *r, *q, *p, n, sum, first;
5508ccff702Sbostic int ii, lastwhite, lastbrown;
5518ccff702Sbostic
5528ccff702Sbostic *prob = sum = 0;
5538ccff702Sbostic r = player+25;
5548ccff702Sbostic p = newtry;
5558ccff702Sbostic q = newother;
5568ccff702Sbostic while(player<r){
5578ccff702Sbostic *p++= *player++;
5588ccff702Sbostic *q++= *playee++;
5598ccff702Sbostic }
5608ccff702Sbostic q=newtry+31;
5618ccff702Sbostic for(p = newtry+25; p < q; p++) /* zero out spaces for hit pieces */
5628ccff702Sbostic *p = 0;
5638ccff702Sbostic for(n = 0; n < 4; n++){
5648ccff702Sbostic if(moves[k].pos[n] == NIL)
5658ccff702Sbostic break;
5668ccff702Sbostic newtry[moves[k].pos[n]]--;
5678ccff702Sbostic newtry[ii=moves[k].pos[n]+moves[k].mov[n]]++;
5688ccff702Sbostic if(ii<25 && newother[25-ii]==1){
5698ccff702Sbostic newother[25-ii]=0;
5708ccff702Sbostic newother[0]++;
5718ccff702Sbostic if(ii<=15 && level=='e') /* hit if near other's home */
5728ccff702Sbostic sum++;
5738ccff702Sbostic }
5748ccff702Sbostic }
5758ccff702Sbostic for(lastbrown = 0; newother[lastbrown] == 0; lastbrown++);
5768ccff702Sbostic ;
5778ccff702Sbostic for(lastwhite = 0; newtry[lastwhite] == 0; lastwhite++)
5788ccff702Sbostic ;
5798ccff702Sbostic lastwhite = 25-lastwhite;
5808ccff702Sbostic if(lastwhite<=6 && lastwhite<lastbrown)
5818ccff702Sbostic sum=1000;
5828ccff702Sbostic /* experts running game. */
5838ccff702Sbostic /* first priority is to */
5848ccff702Sbostic /* get all pieces into */
5858ccff702Sbostic /* white's home */
5868ccff702Sbostic if(lastwhite<lastbrown && level=='e' && lastwhite>6) {
5878ccff702Sbostic for(sum = 1000; lastwhite > 6; lastwhite--)
5888ccff702Sbostic sum = sum-lastwhite*newtry[25-lastwhite];
5898ccff702Sbostic }
5908ccff702Sbostic for(first = 0; first < 25; first++)
5918ccff702Sbostic if(newother[first] != 0) /*find other's first piece*/
5928ccff702Sbostic break;
5938ccff702Sbostic q = newtry+25;
5948ccff702Sbostic for(p = newtry+1; p < q;) /* blocked points are good */
5958ccff702Sbostic if(*p++ > 1)
5968ccff702Sbostic sum++;
5978ccff702Sbostic if(first > 5) { /* only stress removing pieces if */
5988ccff702Sbostic /* homeboard cannot be hit */
5998ccff702Sbostic q = newtry+31;
6008ccff702Sbostic p=newtry+25;
6018ccff702Sbostic for(n = 6; p < q; n--)
6028ccff702Sbostic sum += *p++ * n; /*remove pieces, but just barely*/
6038ccff702Sbostic }
6048ccff702Sbostic if(level != 'b'){
6058ccff702Sbostic r = newtry+25-first; /*singles past this point can't be hit*/
6068ccff702Sbostic for(p = newtry+7; p < r; )
6078ccff702Sbostic if(*p++ == 1) /*singles are bad after 1st 6 points if they can be hit*/
6088ccff702Sbostic sum--;
6098ccff702Sbostic q = newtry+3;
6108ccff702Sbostic for(p = newtry; p < q; ) /*bad to be on 1st three points*/
6118ccff702Sbostic sum -= *p++;
6128ccff702Sbostic }
6138ccff702Sbostic
6148ccff702Sbostic for(n = 1; n <= 4; n++)
6158ccff702Sbostic *prob += n*getprob(newtry,newother,6*n-5,6*n);
6168ccff702Sbostic return(sum);
6178ccff702Sbostic }
instructions()6188ccff702Sbostic instructions()
6198ccff702Sbostic {
6208ccff702Sbostic register fd, r;
6218ccff702Sbostic char buf[BUFSIZ];
6228ccff702Sbostic
6238ccff702Sbostic if((fd = open(RULES, 0)) < 0) {
6248ccff702Sbostic fprintf(stderr, "back: cannot open %s\n", RULES);
6258ccff702Sbostic return;
6268ccff702Sbostic }
6278ccff702Sbostic while(r = read(fd, buf, BUFSIZ))
6288ccff702Sbostic write(1, buf, r);
6298ccff702Sbostic }
6308ccff702Sbostic
getprob(player,playee,start,finish)6318ccff702Sbostic getprob(player,playee,start,finish)
6328ccff702Sbostic int *player,*playee,start,finish;
6338ccff702Sbostic { /*returns the probability (times 102) that any
6348ccff702Sbostic pieces belonging to 'player' and lying between
6358ccff702Sbostic his points 'start' and 'finish' will be hit
6368ccff702Sbostic by a piece belonging to playee
6378ccff702Sbostic */
6388ccff702Sbostic int k, n, sum;
6398ccff702Sbostic
6408ccff702Sbostic sum = 0;
6418ccff702Sbostic for(; start <= finish; start++){
6428ccff702Sbostic if(player[start] == 1){
6438ccff702Sbostic for(k = 1; k <= 12; k++){
6448ccff702Sbostic if((n=25-start-k) < 0)
6458ccff702Sbostic break;
6468ccff702Sbostic if(playee[n] != 0)
6478ccff702Sbostic sum += probability[k];
6488ccff702Sbostic }
6498ccff702Sbostic }
6508ccff702Sbostic }
6518ccff702Sbostic return(sum);
6528ccff702Sbostic }
prtbrd()6538ccff702Sbostic prtbrd()
6548ccff702Sbostic {
6558ccff702Sbostic int k;
6568ccff702Sbostic static char undersc[]="______________________________________________________";
6578ccff702Sbostic
6588ccff702Sbostic fprintf(stdout, "White's Home\n%s\r",undersc);
6598ccff702Sbostic for(k = 1; k <= 6; k++)
6608ccff702Sbostic fprintf(stdout, "%4d",k);
6618ccff702Sbostic fprintf(stdout, " ");
6628ccff702Sbostic for(k = 7; k <= 12; k++)
6638ccff702Sbostic fprintf(stdout, "%4d",k);
6648ccff702Sbostic putchar('\n');
6658ccff702Sbostic numline(brown, white, 1, 6);
6668ccff702Sbostic fprintf(stdout, " ");
6678ccff702Sbostic numline(brown, white, 7, 12);
6688ccff702Sbostic putchar('\n');
6698ccff702Sbostic colorline(brown, 'B', white, 'W', 1, 6);
6708ccff702Sbostic fprintf(stdout, " ");
6718ccff702Sbostic colorline(brown, 'B', white, 'W', 7, 12);
6728ccff702Sbostic putchar('\n');
6738ccff702Sbostic if(white[0] != 0)
6748ccff702Sbostic fprintf(stdout, "%28dW\n",white[0]);
6758ccff702Sbostic else
6768ccff702Sbostic putchar('\n');
6778ccff702Sbostic if(brown[0] != 0)
6788ccff702Sbostic fprintf(stdout, "%28dB\n", brown[0]);
6798ccff702Sbostic else
6808ccff702Sbostic putchar('\n');
6818ccff702Sbostic colorline(white, 'W', brown, 'B', 1, 6);
6828ccff702Sbostic fprintf(stdout, " ");
6838ccff702Sbostic colorline(white, 'W', brown, 'B', 7, 12);
6848ccff702Sbostic fprintf(stdout, "\n%s\r",undersc);
6858ccff702Sbostic numline(white, brown, 1, 6);
6868ccff702Sbostic fprintf(stdout, " ");
6878ccff702Sbostic numline(white, brown, 7, 12);
6888ccff702Sbostic putchar('\n');
6898ccff702Sbostic for(k = 24; k >= 19; k--)
6908ccff702Sbostic fprintf(stdout, "%4d",k);
6918ccff702Sbostic fprintf(stdout, " ");
6928ccff702Sbostic for(k = 18; k >= 13; k--)
6938ccff702Sbostic fprintf(stdout, "%4d",k);
6948ccff702Sbostic fprintf(stdout, "\nBrown's Home\n\n\n\n\n");
6958ccff702Sbostic }
numline(upcol,downcol,start,fin)6968ccff702Sbostic numline(upcol,downcol,start,fin)
6978ccff702Sbostic int *upcol,*downcol,start,fin;
6988ccff702Sbostic {
6998ccff702Sbostic int k, n;
7008ccff702Sbostic
7018ccff702Sbostic for(k = start; k <= fin; k++){
7028ccff702Sbostic if((n = upcol[k]) != 0 || (n = downcol[25-k]) != 0)
7038ccff702Sbostic fprintf(stdout, "%4d", n);
7048ccff702Sbostic else
7058ccff702Sbostic fprintf(stdout, " ");
7068ccff702Sbostic }
7078ccff702Sbostic }
colorline(upcol,c1,downcol,c2,start,fin)7088ccff702Sbostic colorline(upcol,c1,downcol,c2,start,fin)
7098ccff702Sbostic int *upcol,*downcol,start,fin;
7108ccff702Sbostic char c1,c2;
7118ccff702Sbostic {
7128ccff702Sbostic int k;
7138ccff702Sbostic char c;
7148ccff702Sbostic
7158ccff702Sbostic for(k = start; k <= fin; k++){
7168ccff702Sbostic c = ' ';
7178ccff702Sbostic if(upcol[k] != 0)
7188ccff702Sbostic c = c1;
7198ccff702Sbostic if(downcol[25-k] != 0)
7208ccff702Sbostic c = c2;
7218ccff702Sbostic fprintf(stdout, " %c",c);
7228ccff702Sbostic }
7238ccff702Sbostic }
724