📄 backgammon.c
字号:
/*- * 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 lintstatic 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? "); gets(s); if(*s == 'y') instructions(); putchar('\n'); fprintf(stdout, "Opponent's level: b - beginner,\n"); fprintf(stdout, "i - intermediate, e - expert? "); level='e'; gets(s); 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? "); gets(s); putchar('\n'); if(*s == 'y') nobroll = 1; fprintf(stdout, "Would you like to go first? "); gets(s); 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? "); gets(s); 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? "); gets(s); 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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -