home *** CD-ROM | disk | FTP | other *** search
- /********************************************************************/
- /* */
- /* Hoser BackGammon version 1.0 */
- /* */
- /* Robert Pfister */
- /* */
- /* Rfd#3 Box 2340 home:(207)-873-3520 */
- /* Waterville, Maine 04901 */
- /* */
- /* Pfister_rob%dneast@dec.decwrl */
- /* */
- /* */
- /* Copyright June,1987 */
- /* */
- /* This program will play a game of backgammon at the novice level */
- /* */
- /* The code is in 4 parts... */
- /* / */
- /* \/ 1) back.c - main driver */
- /* 2) eval.c - evaluation of moves */
- /* 3) backscn.c - screen stuff.. */
- /* 4) backmenu.c - menu stuff, help text, and ``decoder'' */
- /* */
- /* this was compiled under Manx 3.20a, using long integers */
- /* */
- /********************************************************************/
- #include <libraries/dos.h>
-
- extern int AvgPos;
- extern int Moves;
-
- int MeInc,YouInc=0;
- int MeD,MeM,YouD,YouM=0;
- int MeBar,YouBar=0;
- int Me2,You2=0;
-
- #define StackSize 500
- static int BoardPos[StackSize][26]; /* stack of the previous positions */
- static int DicePos[StackSize][4]; /* stack of the dice rolls */
-
- static int StackPos=0; /* how many moves back are we at? */
-
- static int MoveList[4]; /* stack of this turns moves */
- static int CurMove=0; /* place in the list */
-
- int Uside; /* user side */
- int Cside; /* computer side */
-
- int Turn; /* whose turn is it? */
-
- int board[26]; /* describes the board position..0 is the bar */
- int Dice[4]; /* describes the 2->4 dice availible */
-
- main() /* main procedure */
- {
-
- int i,j,play;
-
- Gsetup();
- Turn=setup(board,Dice);
-
- for (;;) /* go until game is over */
- {
- if (Turn==Uside) DoMenuStrip("Your Turn");
- else DoMenuStrip("My Turn");
-
- ShowDice(Dice,Turn);
- if (Turn==Uside)
- {
- /* store this board position */
- StoreMove();
- /* user stats */
- if (Dice[2]>0) You2++;
- YouD+=Dice[0]+Dice[1]+Dice[2]+Dice[3];
- YouM++;
- if (board[25]<0) YouBar++;
-
-
- /* do the Move */
- do
- if (UserMove(board,Dice,Turn)==0) GameOver(); /* escape */
- while ( (Turn==Uside)&&
- (Won(board,Turn)==0)&&
- (Dice[0]+Dice[1]+Dice[2]+Dice[3]!=0) );
- }
- else /* turn==Cside */
- {
- /* computer stats */
- if (Dice[2]>0) Me2++;
- MeD+=Dice[0]+Dice[1]+Dice[2]+Dice[3];
- MeM++;
- if (board[0]>0) MeBar++;
-
- /* do move */
- GenerateMoves(board,Dice);
- DoMove(board);
- }
-
- Turn=Turn*-1;
- Roll(Dice);
-
- /* signal to restart the game */
- if (Turn==0) Turn=setup(board,Dice);
-
- /* did user win yet? */
- if (Won(board,Uside))
- {
- stats();
- if (requestor("I lose Play Again?","No","Yes")) GameOver();
- else Turn=setup(board,Dice);
- }
-
- /* did computer win yet? */
- if (Won(board,Cside))
- {
- stats();
- if (requestor("Heehee. I Win. Play Again?","No","Yes")) GameOver();
- else Turn=setup(board,Dice);
- }
- ShowDice(Dice,Turn);
-
- } /* end do forever */
-
- } /* end of main */
-
- Restart()
- {
- Turn=0;
- }
-
- StoreMove()
- {
- int i;
-
- if (StackPos<StackSize+1) /* can only store that many */
- {
- for (i=0;i<26;i++)
- BoardPos[StackPos][i]=board[i];
- for (i=0;i<4;i++)
- DicePos[StackPos][i]=Dice[i];
- StackPos++;
- }
- /* printf("STORE: stack is at %d \n",StackPos); */
- }
-
- RecallMove(how)
- int how;
- {
- int i;
-
- StackPos=StackPos-1+how;
- if (StackPos<0) StackPos=0;
-
- for (i=0;i<26;i++)
- if (board[i]!=BoardPos[StackPos][i])
- { /* only refresh stuff changed */
- board[i]=BoardPos[StackPos][i];
- PutSpike(i,board[i]);
- }
-
- for (i=0;i<4;i++)
- Dice[i]=DicePos[StackPos][i];
-
- ShowDice(Dice,Uside);
- StackPos++;
- /* printf("RECALL: stack is at %d \n",StackPos); */
- }
-
- Won(board,side)
- int board[26],side;
- {
- int i;
-
- if (side==1) for(i=0;((board[i]<=0)&&(i<=25));i++);
- else for(i=0;((board[i]>=0)&&(i<=25));i++);
-
- if (i==26) return(1);
- else return(0);
- }
-
- UserMove(board,Dice,side)
- int board[26],Dice[4],side;
- {
- char Action;
- int Pick,Valid; /* flags */
- int i,x,y;
-
- Valid=0;
- Pick =0;
- while (Valid==0)
- {
- Action=Whats_up(&x);
- UnDoMenuStrip();
- switch (Action)
- {
- /* check for abortion */
- case 'D':Dice[0]=0;
- Dice[1]=0;
- Dice[2]=0;
- Dice[3]=0;
- Valid=1;
- YouInc++;
- break;
-
-
- case 'Q':
- Valid=-1;
- break;
-
- case 'P':if (Pick==0)
- {
- if (board[x]*side<=0)
- DoMenuStrip("No peice there!!");
- else
- {
- Pick=1;
- y=x;
- }
- break;
- }
-
- else if (Pick==1) /* only if peice marked already */
- {
- Pick =0;
- for (i=0;(Valid==0)&&(i<4);i++)
- {
- if ((valid(board,y,x,Dice[i]))&&(Dice[i]!=0))
- {
- BlinkPeice(board,y);
- update(board,y,x,side);
- PutSpike(y ,board[ y]);
- BlinkPeice(board,x);
- PutSpike(0 ,board[ 0]);
- PutSpike(25,board[25]);
- Valid=1;
- Dice[i]=0;
- }
- } /* end for */
-
- if (Valid==0) DoMenuStrip("Not Valid move");
-
- break;
- } /* end if...case 'M' */
-
- case 'C':Valid=DoMenu(x);
- break;
-
- default :break;
-
- } /* end of case */
-
- } /* end while Valid==0 */
-
- if (Valid==-1) return(0);
- return(1);
- } /* end UserMove */
-
-
- Roll(d) /* roll the dice (4 results) */
- int d[4];
- {
- long i,k,num1,num2;
- struct DateStamp time;
-
- DateStamp(&time);
-
- k=time.ds_Tick;
-
- for (i=1;i<=k;i++)
- {
- num1=RangeRand(6L)+1;
- num2=RangeRand(6L)+1;
- }
- d[0]=num1;
- d[1]=num2;
- if (num1==num2) /* if rolled doubles */
- {
- d[2]=num1;
- d[3]=num2;
- }
- else
- {
- d[2]=0;
- d[3]=0;
- }
- if (d[3]==0) return(0);
- else return(1);
- }
-
- GameOver()
- {
- stats();
- finit();
- exit(0);
- }
-
- stats()
- {
- if ((YouM!=0)&&(MeM!=0))
- {
- printf("Statistics on the Game \n");
- printf("-------------------------------------------------------\n");
- printf("number of moves %ld avg positions evaluated %ld \n",MeM,AvgPos/MeM);
- printf("\n");
- printf("avg roll : User %ld Computer %ld \n",YouD/YouM,MeD/MeM);
- printf("doubles : User %ld Computer %ld \n",You2,Me2);
- printf("inc. Moves : User %ld Computer %ld \n",YouInc,MeInc);
- printf("Turns on bar: User %ld Computer %ld \n",YouBar,MeBar);
- printf("-------------------------------------------------------\n");
- }
- MeM=0; YouD=0; YouM=0; MeD=0;
- AvgPos=0; You2=0; Me2=0; YouInc=0; MeInc=0;
- YouBar=0; MeBar=0;
- }
-
- setup(board,Dice)
- int board[26],Dice[4];
- {
- int i;
-
- Uside=-1;
- Cside= 1;
-
- /* set the board to the initial setting */
-
- for (i=0; i<=25; i++)
- {
- board[i]= 0;
- }
-
- board[ 1]= 2;
- board[ 6]=-5;
- board[ 8]=-3;
- board[12]= 5;
- board[13]=-5;
- board[17]= 3;
- board[19]= 5;
- board[24]=-2;
- for (i=0;i<=25;i++)
- {
- PutSpike(i,board[i]);
- }
-
- /* see who goes first */
-
- while (Roll(Dice)); /* until no doubles */
-
- if (Dice[0]>Dice[1])
- return(Uside);
- else return(Cside);
- }
-
- /* is the move valid for the board, and one die */
- valid(board,m1,m2,p) /* board, start, stop, dice roll */
- int board[26];
- int m1,m2,p;
- {
- int sign,i,All_In,bar;
-
-
- All_In=-1;
-
- /* what direction are we going? */
- if (board[m1]>0)
- {
- sign=Cside;
-
- if (Cside==1) bar=0;
- else bar=25;
-
- /* is there a man on the bar?? */
- if ((board[bar]!=0)&&(m1!=0)) return(0);
-
- /* see if all peices are in home base */
- for(i=0;(i<=24)&&(All_In==-1);i++)
- if (board[i]>0) All_In=i;
-
- /* check if can take it off */
- if (m2>24)
- {
- if ((All_In>18)&&
- ( (m1==(25-p)) || ((25-p)<All_In)&&(m1==All_In) )) return(1);
- else return(0);
- }
- }
- else
- {
- sign=-1;
- /* is there a man on the bar? */
- if ((board[25]!=0)&&(m1!=25)) return(0);
-
- /* see if all peices are in home base */
- for(i=25;(i>=1)&&(All_In==-1);i--)
- if (board[i]<0) All_In=i;
-
- /* see if can take off */
- if (m2==m1)
- {
- if ((All_In<7)&&
- ( (m1==p)|| ((p>All_In)&&(m1==All_In) ))) return(1);
- else return(0);
- }
- }
-
- /* does dice roll make sense for the move picked? */
- if ((m2-m1)!=(p*sign)) return(0);
-
- /* if spike has more than 1 opponent */
- if (board[m2] * sign < -1) return(0);
-
- /* I suppose that's all there is..*/
- return(1);
- }
-
- /* put a given move onto the board */
- update(board,m1,m2,sign)
- int board[26],m1,m2,sign;
- {
- int bar;
-
- if (sign>0) bar=0;
- else bar=25;
-
- /* remove the peice from the 'source' spike */
-
- board[m1]=board[m1]-sign;
-
- /* if taking a peice off, dont go any furthur */
- if ((m2==m1)||(m2>=25)) return(1);
-
- /* add a peice to the 'destination' spike, consider if capturing*/
-
- board[m2]=board[m2]+sign;
-
- if (board[m2]==0) {
- board[m2 ]=sign;
- board[25-bar]=board[25-bar]-sign;
- }
- return(0);
- }
-