diff options
-rw-r--r-- | games/backgammon/common_source/backgammon.c | 751 |
1 files changed, 0 insertions, 751 deletions
diff --git a/games/backgammon/common_source/backgammon.c b/games/backgammon/common_source/backgammon.c deleted file mode 100644 index 6e00a5a..0000000 --- a/games/backgammon/common_source/backgammon.c +++ /dev/null @@ -1,751 +0,0 @@ -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -static char sccsid[] = "@(#)backgammon.c 8.1 (Berkeley) 5/31/93"; -#endif /* not lint */ - -/* -** The game of Backgammon -*/ - -#include <stdio.h> - -#define WHITE 0 -#define BROWN 1 -#define NIL (-1) -#define MAXGMOV 10 -#define MAXIMOVES 1000 -#define RULES "/usr/games/lib/backrules" - -char level; /*'b'=beginner, 'i'=intermediate, 'e'=expert*/ - -int die1; -int die2; -int i; -int j; -int l; -int m; -int pflg = 1; -int nobroll = 0; -int count; -int imoves; -int goodmoves[MAXGMOV]; -int probmoves[MAXGMOV]; - -int brown[] = { /* brown position table */ - 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, - 0, 0, 0, 0, 3, 0, 5, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0 -}; - -int white[] = { /* white position table */ - 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, - 0, 0, 0, 0, 3, 0, 5, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0 -}; - -int probability[] = { - 0, 11, 12, 13, 14, 15, 16, - 06, 05, 04, 03, 02, 01 -}; - -struct { - int pos[4]; - int mov[4]; -} moves[MAXIMOVES]; - -main() -{ - int go[5], tvec[2]; - int k, n, pid, ret, rpid, t; - char s[100]; - - srand(time(0)); - go[5] = NIL; - fprintf(stdout, "Instructions? "); - fgets(s, 100, stdin); - if(*s == 'y') - instructions(); - putchar('\n'); - fprintf(stdout, "Opponent's level: b - beginner,\n"); - fprintf(stdout, "i - intermediate, e - expert? "); - level='e'; - fgets(s, 100, stdin); - if(*s == 'b') - level = 'b'; - else if(*s == 'i') - level = 'i'; - putchar('\n'); - fprintf(stdout, "You will play brown.\n\n"); - fprintf(stdout, "Would you like to roll your own dice? "); - fgets(s, 100, stdin); - putchar('\n'); - if(*s == 'y') - nobroll = 1; - fprintf(stdout, "Would you like to go first? "); - fgets(s, 100, stdin); - putchar('\n'); - if(*s == 'y') - goto nowhmove; -whitesmv: - roll(WHITE); - fprintf(stdout, "white rolls %d, %d\n", die1, die2); - fprintf(stdout, "white's move is:"); - if(nextmove(white, brown) == NIL) - goto nowhmove; - if(piececount(white, 0, 24) == 0){ - fprintf(stdout, "White wins"); - if(piececount(brown, 0, 6) != 0) - fprintf(stdout, " with a Backgammon!\n"); - else if (piececount(brown, 0, 24) == 24) - fprintf(stdout, " with a Gammon.\n"); - else - fprintf(stdout, ".\n"); - exit(0); - } -nowhmove: - if(pflg) - prtbrd(); - roll(BROWN); -retry: - fprintf(stdout, "\nYour roll is %d %d\n", die1, die2); - fprintf(stdout, "Move? "); - fgets(s, 100, stdin); - switch(*s) { - case '\0': /* empty line */ - fprintf(stdout, "Brown's move skipped.\n"); - goto whitesmv; - - case 'b': /* how many beared off? */ - fprintf(stdout, "Brown: %d\n", piececount(brown, 0, 24) - 15); - fprintf(stdout, "White: %d\n", piececount(white, 0, 24) - 15); - goto retry; - - case 'p': /* print board */ - prtbrd(); - goto retry; - - case 's': /* stop auto printing of board */ - pflg = 0; - goto retry; - - case 'r': /* resume auto printing */ - pflg = 1; - goto retry; - - case 'm': /* print possible moves */ - pmoves(); - goto retry; - - case 'q': /* i give up */ - exit(0); - - case '!': /* escape to Shell */ - if(s[1] != '\0') - system(s+1); - else if((pid = fork()) == 0) { - execl("/bin/sh", "sh", "-", 0); - fprintf(stderr, "back: cannot exec /bin/sh!\n"); - exit(2); - } - while((rpid = wait(&ret)) != pid && rpid != -1) - ; - goto retry; - - case '?': /* well, what can i do? */ - fprintf(stdout, "<newline> skip this move\n"); - fprintf(stdout, "b number beared off\n"); - fprintf(stdout, "p print board\n"); - fprintf(stdout, "q quit\n"); - fprintf(stdout, "r resume auto print of board\n"); - fprintf(stdout, "s stop auto print of board\n"); - fprintf(stdout, "! escape to Shell\n"); - goto retry; - } - n = sscanf(s,"%d%d%d%d%d",&go[0],&go[1],&go[2],&go[3],&go[4]); - if((die1 != die2 && n > 2) || n > 4){ - fprintf(stdout, "Too many moves.\n"); - goto retry; - } - go[n] = NIL; - if(*s=='-'){ - go[0]= -go[0]; - t=die1; - die1=die2; - die2=t; - } - for(k = 0; k < n; k++){ - if(0 <= go[k] && go[k] <= 24) - continue; - else{ - fprintf(stdout, "Move %d illegal.\n", go[k]); - goto retry; - } - } - if(play(brown, white, go)) - goto retry; - if(piececount(brown, 0, 24) == 0){ - fprintf(stdout, "Brown wins"); - if(piececount(white, 0, 6) != 0) - fprintf(stdout, " with a Backgammon.\n"); - else if(piececount(white, 0, 24) == 24) - fprintf(stdout, " with a gammon.\n"); - else - fprintf(stdout, ".\n"); - exit(0); - } - goto whitesmv; -} - -play(player,playee,pos) -int *player,*playee,pos[]; -{ - int k, n, die, ipos; - - for(k=0; k < player[0]; k++){ /*blots on player[0] must be moved first*/ - if(pos[k] == NIL) - break; - if(pos[k] != 0){ - fprintf(stdout, "Stone on bar must be moved first.\n"); - return(NIL); - } - } - for(k = 0; (ipos=pos[k]) != NIL; k++){ - die = k?die2:die1; - n = 25-ipos-die; - if(player[ipos] == 0) - goto badmove; - if(n > 0 && playee[n] >= 2) - goto badmove; - if(n <= 0){ - if(piececount(player,0,18) != 0) - goto badmove; - if((ipos+die) != 25 && piececount(player,19,24-die)!=0) - goto badmove; - } - player[ipos]--; - player[ipos+die]++; - } - for(k = 0; pos[k] != NIL; k++){ - die = k?die2:die1; - n = 25-pos[k]-die; - if(n>0 && playee[n]==1){ - playee[n]=0; - playee[0]++; - } - } - return(0); - -badmove: - fprintf(stdout, "Move %d illegal.\n", ipos); - while(k--){ - die=k?die2:die1; - player[pos[k]]++; - player[pos[k]+die]--; - } - return(NIL); -} -nextmove(player,playee) -int *player,*playee; -{ - int k; - - imoves=0; - movegen(player,playee); - if(die1!=die2){ - k=die1; - die1=die2; - die2=k; - movegen(player,playee); - } - if(imoves==0){ - fprintf(stdout, "no move possible.\n"); - return(NIL); - } - k=strategy(player,playee); /*select kth possible move*/ - prtmov(k); - update(player,playee,k); - return(0); -} -prtmov(k) -int k; -{ - int n; - - if(k == NIL) - fprintf(stdout, "No move possible\n"); - else for(n = 0; n < 4; n++){ - if(moves[k].pos[n] == NIL) - break; - fprintf(stdout, " %d, %d",25-moves[k].pos[n],moves[k].mov[n]); - } - fprintf(stdout, "\n"); -} -update(player,playee,k) -int *player,*playee,k; -{ - int n,t; - - for(n = 0; n < 4; n++){ - if(moves[k].pos[n] == NIL) - break; - player[moves[k].pos[n]]--; - player[moves[k].pos[n]+moves[k].mov[n]]++; - t=25-moves[k].pos[n]-moves[k].mov[n]; - if(t>0 && playee[t]==1){ - playee[0]++; - playee[t]--; - } - } -} -piececount(player,startrow,endrow) -int *player,startrow,endrow; -{ - int sum; - - sum=0; - while(startrow <= endrow) - sum += player[startrow++]; - return(sum); -} -pmoves() -{ - int i1, i2; - - fprintf(stdout, "Possible moves are:\n"); - for(i1 = 0; i1 < imoves; i1++){ - fprintf(stdout, "\n%d",i1); - for (i2 = 0; i2<4; i2++){ - if(moves[i1].pos[i2] == NIL) - break; - fprintf(stdout, "%d, %d",moves[i1].pos[i2],moves[i1].mov[i2]); - } - } - fprintf(stdout, "\n"); -} - -roll(who) -{ - register n; - char s[10]; - - if(who == BROWN && nobroll) { - fprintf(stdout, "Roll? "); - fgets(s, 10, stdin); - n = sscanf(s, "%d%d", &die1, &die2); - if(n != 2 || die1 < 1 || die1 > 6 || die2 < 1 || die2 > 6) - fprintf(stdout, "Illegal - I'll do it!\n"); - else - return; - } - die1 = ((rand()>>8) % 6) + 1; - die2 = ((rand()>>8) % 6) + 1; -} - -movegen(mover,movee) -int *mover,*movee; -{ - int k; - - for(i = 0; i <= 24; i++){ - count = 0; - if(mover[i] == 0) - continue; - if((k=25-i-die1) > 0 && movee[k] >= 2) - if(mover[0] > 0) - break; - else - continue; - if(k <= 0){ - if(piececount(mover, 0, 18) != 0) - break; - if((i+die1) != 25 && piececount(mover,19,i-1) != 0) - break; - } - mover[i]--; - mover[i+die1]++; - count = 1; - for(j = 0; j <= 24; j++){ - if(mover[j]==0) - continue; - if((k=25-j-die2) > 0 && movee[k] >= 2) - if(mover[0] > 0) - break; - else - continue; - if(k <= 0){ - if(piececount(mover,0,18) != 0) - break; - if((j+die2) != 25 && piececount(mover,19,j-1) != 0) - break; - } - mover[j]--; - mover[j+die2]++; - count = 2; - if(die1 != die2){ - moverecord(mover); - if(mover[0] > 0) - break; - else - continue; - } - for(l = 0; l <= 24; l++){ - if(mover[l] == 0) - continue; - if((k=25-l-die1) > 0 && movee[k] >= 2) - if(mover[0] > 0) - break; - else - continue; - if(k <= 0){ - if(piececount(mover, 0, 18) != 0) - break; - if((l+die2) != 25 && piececount(mover,19,l-1) != 0) - break; - } - mover[l]--; - mover[l+die1]++; - count=3; - for(m=0;m<=24;m++){ - if(mover[m]==0) - continue; - if((k=25-m-die1) >= 0 && movee[k] >= 2) - if(mover[0] > 0) - break; - else - continue; - if(k <= 0){ - if(piececount(mover,0,18) != 0) - break; - if((m+die2) != 25 && piececount(mover,19,m-1) != 0) - break; - } - count=4; - moverecord(mover); - if(mover[0] > 0) - break; - } - if(count == 3) - moverecord(mover); - else{ - mover[l]++; - mover[l+die1]--; - } - if(mover[0] > 0) - break; - } - if(count == 2) - moverecord(mover); - else{ - mover[j]++; - mover[j+die1]--; - } - if(mover[0] > 0) - break; - } - if(count == 1) - moverecord(mover); - else{ - mover[i]++; - mover[i+die1]--; - } - if(mover[0] > 0) - break; - } -} -moverecord(mover) -int *mover; -{ - int t; - - if(imoves < MAXIMOVES) { - for(t = 0; t <= 3; t++) - moves[imoves].pos[t] = NIL; - switch(count) { - case 4: - moves[imoves].pos[3]=m; - moves[imoves].mov[3]=die1; - - case 3: - moves[imoves].pos[2]=l; - moves[imoves].mov[2]=die1; - - case 2: - moves[imoves].pos[1]=j; - moves[imoves].mov[1]=die2; - - case 1: - moves[imoves].pos[0]=i; - moves[imoves].mov[0]=die1; - imoves++; - } - } - switch(count) { - case 4: - break; - - case 3: - mover[l]++; - mover[l+die1]--; - break; - - case 2: - mover[j]++; - mover[j+die2]--; - break; - - case 1: - mover[i]++; - mover[i+die1]--; - } -} - -strategy(player,playee) -int *player,*playee; -{ - int k, n, nn, bestval, moveval, prob; - - n = 0; - if(imoves == 0) - return(NIL); - goodmoves[0] = NIL; - bestval = -32000; - for(k = 0; k < imoves; k++){ - if((moveval=eval(player,playee,k,&prob)) < bestval) - continue; - if(moveval > bestval){ - bestval = moveval; - n = 0; - } - if(n<MAXGMOV){ - goodmoves[n]=k; - probmoves[n++]=prob; - } - } - if(level=='e' && n>1){ - nn=n; - n=0; - prob=32000; - for(k = 0; k < nn; k++){ - if((moveval=probmoves[k]) > prob) - continue; - if(moveval<prob){ - prob=moveval; - n=0; - } - goodmoves[n]=goodmoves[k]; - probmoves[n++]=probmoves[k]; - } - } - return(goodmoves[(rand()>>4)%n]); -} - -eval(player,playee,k,prob) -int *player,*playee,k,*prob; -{ - int newtry[31], newother[31], *r, *q, *p, n, sum, first; - int ii, lastwhite, lastbrown; - - *prob = sum = 0; - r = player+25; - p = newtry; - q = newother; - while(player<r){ - *p++= *player++; - *q++= *playee++; - } - q=newtry+31; - for(p = newtry+25; p < q; p++) /* zero out spaces for hit pieces */ - *p = 0; - for(n = 0; n < 4; n++){ - if(moves[k].pos[n] == NIL) - break; - newtry[moves[k].pos[n]]--; - newtry[ii=moves[k].pos[n]+moves[k].mov[n]]++; - if(ii<25 && newother[25-ii]==1){ - newother[25-ii]=0; - newother[0]++; - if(ii<=15 && level=='e') /* hit if near other's home */ - sum++; - } - } - for(lastbrown = 0; newother[lastbrown] == 0; lastbrown++); - ; - for(lastwhite = 0; newtry[lastwhite] == 0; lastwhite++) - ; - lastwhite = 25-lastwhite; - if(lastwhite<=6 && lastwhite<lastbrown) - sum=1000; - /* experts running game. */ - /* first priority is to */ - /* get all pieces into */ - /* white's home */ - if(lastwhite<lastbrown && level=='e' && lastwhite>6) { - for(sum = 1000; lastwhite > 6; lastwhite--) - sum = sum-lastwhite*newtry[25-lastwhite]; - } - for(first = 0; first < 25; first++) - if(newother[first] != 0) /*find other's first piece*/ - break; - q = newtry+25; - for(p = newtry+1; p < q;) /* blocked points are good */ - if(*p++ > 1) - sum++; - if(first > 5) { /* only stress removing pieces if */ - /* homeboard cannot be hit */ - q = newtry+31; - p=newtry+25; - for(n = 6; p < q; n--) - sum += *p++ * n; /*remove pieces, but just barely*/ - } - if(level != 'b'){ - r = newtry+25-first; /*singles past this point can't be hit*/ - for(p = newtry+7; p < r; ) - if(*p++ == 1) /*singles are bad after 1st 6 points if they can be hit*/ - sum--; - q = newtry+3; - for(p = newtry; p < q; ) /*bad to be on 1st three points*/ - sum -= *p++; - } - - for(n = 1; n <= 4; n++) - *prob += n*getprob(newtry,newother,6*n-5,6*n); - return(sum); -} -instructions() -{ - register fd, r; - char buf[BUFSIZ]; - - if((fd = open(RULES, 0)) < 0) { - fprintf(stderr, "back: cannot open %s\n", RULES); - return; - } - while(r = read(fd, buf, BUFSIZ)) - write(1, buf, r); -} - -getprob(player,playee,start,finish) -int *player,*playee,start,finish; -{ /*returns the probability (times 102) that any - pieces belonging to 'player' and lying between - his points 'start' and 'finish' will be hit - by a piece belonging to playee - */ - int k, n, sum; - - sum = 0; - for(; start <= finish; start++){ - if(player[start] == 1){ - for(k = 1; k <= 12; k++){ - if((n=25-start-k) < 0) - break; - if(playee[n] != 0) - sum += probability[k]; - } - } - } - return(sum); -} -prtbrd() -{ - int k; - static char undersc[]="______________________________________________________"; - - fprintf(stdout, "White's Home\n%s\r",undersc); - for(k = 1; k <= 6; k++) - fprintf(stdout, "%4d",k); - fprintf(stdout, " "); - for(k = 7; k <= 12; k++) - fprintf(stdout, "%4d",k); - putchar('\n'); - numline(brown, white, 1, 6); - fprintf(stdout, " "); - numline(brown, white, 7, 12); - putchar('\n'); - colorline(brown, 'B', white, 'W', 1, 6); - fprintf(stdout, " "); - colorline(brown, 'B', white, 'W', 7, 12); - putchar('\n'); - if(white[0] != 0) - fprintf(stdout, "%28dW\n",white[0]); - else - putchar('\n'); - if(brown[0] != 0) - fprintf(stdout, "%28dB\n", brown[0]); - else - putchar('\n'); - colorline(white, 'W', brown, 'B', 1, 6); - fprintf(stdout, " "); - colorline(white, 'W', brown, 'B', 7, 12); - fprintf(stdout, "\n%s\r",undersc); - numline(white, brown, 1, 6); - fprintf(stdout, " "); - numline(white, brown, 7, 12); - putchar('\n'); - for(k = 24; k >= 19; k--) - fprintf(stdout, "%4d",k); - fprintf(stdout, " "); - for(k = 18; k >= 13; k--) - fprintf(stdout, "%4d",k); - fprintf(stdout, "\nBrown's Home\n\n\n\n\n"); -} -numline(upcol,downcol,start,fin) -int *upcol,*downcol,start,fin; -{ - int k, n; - - for(k = start; k <= fin; k++){ - if((n = upcol[k]) != 0 || (n = downcol[25-k]) != 0) - fprintf(stdout, "%4d", n); - else - fprintf(stdout, " "); - } -} -colorline(upcol,c1,downcol,c2,start,fin) -int *upcol,*downcol,start,fin; -char c1,c2; -{ - int k; - char c; - - for(k = start; k <= fin; k++){ - c = ' '; - if(upcol[k] != 0) - c = c1; - if(downcol[25-k] != 0) - c = c2; - fprintf(stdout, " %c",c); - } -} |