home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
207.lha
/
BackGammon
/
eval.c
< prev
next >
Wrap
C/C++ Source or Header
|
1988-12-27
|
13KB
|
504 lines
/********************************************************************/
/* */
/* 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 all rights reserved. */
/* */
/* 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 */
/* */
/********************************************************************/
/****************************************************************/
/* These routines do all the thinking for the computer side */
/* */
/* (read: the magic lives here) */
/****************************************************************/
#define Running 1
#define Blocking 2
#define Pegging 3
#define BackGame 4
extern int MeInc;
int Moves =0;
int AvgPos=0;
int LastVun=0;
int list[4][2];
int count=0;
int max=0;
int GameStat=0;
int MaxStat=0;
int block[26]={-1,1,2,3,4,5,6, 8,9,10,11,12,13 ,14,15,17,21,25,27,
25,21,19,8,3,1,0};
int run[26] ={-1,1,2,3,4,5,6, 15,16,17,18,19,20, 30,31,32,33,34,35,
50,51,52,53,54,55};
int peg[26] ={-20,0,0,0,0,0,0 ,1,2,3,4,5,6, 30,31,32,33,34,35,
50,49,48,47,46,45,0};
int back[26]={20,40,30,20,10,5,0 ,1,2,3,4,5,6, 30,31,32,30,40,50,
50,49,48,30,20,10,0};
Eval(Board)
int Board[26];
{
register int i;
int num,value,me,you;
int Msum,Ysum;
num=0;
value=0;
/* see who is ahead */
Msum=0;
for(i=0;i<=24;i++)
if (Board[i]>0)
Msum+=(25-i)*Board[i];
Ysum=0;
for(i=1;i<=25;i++)
if (Board[i]<0)
Ysum-=i*Board[i];
for (i= 0;(i<=24)&&(Board[i]<=0);i++); /* first occurance of me */
me=i;
for (i=25;(i>=1)&&(Board[i]>=0);i--);/* first occurance of you */
you=1;
GameStat=BackGame; /* default case */
if (Ysum>Msum+10) GameStat=Running; /* if closer to winning than them */
if (you>18) GameStat=Blocking; /* if a opponent is within the bounds */
if (me>you) GameStat=Pegging; /* if complete separation */
for(i=0;i<=24;i++)
{
if (Board[i]>0)
{
num=num+Board[i];
switch(GameStat)
{
case BackGame:
value+=back[i]*Board[i];
if (i<18) value+=3*vunerable(Board,i);
break;
case Pegging:
value+=peg[i]*Board[i];
break;
case Blocking:
value+=block[i]*Board[i];
value-=4*vunerable(Board,i);
value-=6*doom(Board);
break;
case Running:
value+=run[i]*Board[i];
value-=6*vunerable(Board,i);
value-=6*doom(Board);
break;
}
}
}
/* add points for taking men off...more if no chance of being taken */
if (GameStat==Pegging) value+=(15-num)*300;
else value+=(15-num)*75;
/* if blocking game, check the block length...add points for more */
switch(GameStat)
{
case BackGame:
num=0;
for(i=0;i<=6;i++) if ((Board[i]>0)&&(you>i)) num++;
value+=100*num;
num=0;
for(i=15;i<=21;i++) if (Board[i]>0) num+=Board[i];
value+=30*num;
value-=100*Board[25];
num=0;
for(i=17;i<=23;i++) if (Board[i]>=2) num++;
value+=(num*300);
break;
case Blocking:
num=0;
for(i=14;i<=22;i++)
{
if (Board[i]>=2) num++;
if ((you>i)&&(Board[i]>=2)) num++;
}
value+=(num*400);
num=0;
for(i=0;i<=17;i++) if (Board[i]>0) num+=(Board[i]*(18-i)*(18-i));
value-=num/1.5;
break;
case Pegging:
case Running:
num=0;
for(i=0;i<=17;i++) if (Board[i]>0) num++;
value-=10*num;
num=0;
for(i=0;i<=17;i++) if (Board[i]>0) num+=(Board[i]*(26-i)*(26-i));
value-=num;
break;
}
return(value);
}
vunerable(Board,pos)
int Board[26],pos;
{
register int i,j,k;
int value;
int HitTable[7][7];
value=0;
if ( (Board[pos]<0) || (pos==0) || (Board[pos]>=2) ) return (value);
/* intitialize table */
for(i=1;i<=6;i++)
for(j=1;j<=6;j++)
HitTable[i][j]=0;
/* look at all dice within 12 places */
for(i=1;i<=12;i++)
{
if (pos-i>=0) /* within the board */
if (Board[pos-i]<0) /* there peice exists at that place */
if (valid(Board,pos,pos-i,i)) /* can capture legally */
{
/*--------------------------------------------------*/
/* find hits for one die */
if (i<=6)
for(j=1;j<=6;j++)
{
HitTable[i][j]=1;
HitTable[j][i]=1;
}
/* figure out combinations */
for (j=1;j<i;j++)
{
/* first die is j, second is k */
k=i-j;
/* check legality of the intermediate place */
if (valid (Board,pos,pos-j,j))
{
HitTable[k][j]=1;
HitTable[j][k]=1;
}
if (valid (Board,pos,pos-k,k))
{
HitTable[k][j]=1;
HitTable[j][k]=1;
}
}
/*---------------------------------------------------*/
} /* end of valid (board,position) */
} /* end of for i */
/* find how many hits in that table */
for(i=1;i<=6;i++)
for(j=1;j<=6;j++)
if (HitTable[i][j]==1) value++;
LastVun=value;
return(value);
} /* end of vunerable */
doom(Board)
int Board[26];
{
register int i,value;
if (LastVun==0) return(0);
/* find the "doom" factor..the possibilty of getting outa being captured */
for(i=1;i<=10;i++) if (Board[i]<-1) value+=5;
return(value);
}
/* copy b1 to b2 */
CopyBoard(b1,b2)
int b1[26],b2[26];
{
register int i;
for (i=0;i<=25;i++)
{
b2[i]=b1[i];
} /* end for */
} /* end of Copy */
DoMove(Board)
int Board[26];
{
int j,sum;
AvgPos+=count;
/* dont do anything if nothing to be done */
if (count==0)
{
DoMenuStrip("Cant move from this position!!");
return(0);
}
PutMoveNumber(count);
/* show move */
for(j=0;j<=3;j++)
if (list[j][0]!=-1)
{
BlinkPeice(Board,list[j][0]);
update(Board,list[j][0], list[j][1] ,1);
PutSpike( list[j][0],Board[list[j][0]] );
BlinkPeice(Board,list[j][1]);
}
/* touch up the bar's */
PutSpike(0 ,Board[ 0]);
PutSpike(25,Board[25]);
}
FindMove(Board,Dice,i1,i2,i3,i4)
int Board[26],Dice[4],i1,i2,i3,i4;
{
int j;
if ((count<50)||(10*(count/10)==count))
PutMoveNumber(count);
j=Eval(Board);
if ((count==1)||(j>max))
{
max=j;
MaxStat=GameStat;
list[0][0]=i1; list[0][1]=i1+Dice[0];
list[1][0]=i2; list[1][1]=i2+Dice[1];
list[2][0]=i3; list[2][1]=i3+Dice[2];
list[3][0]=i4; list[3][1]=i4+Dice[3];
}
}
GenerateMoves(Board,Dice)
int Board[26],Dice[4];
{
register int i;
int Dice2[4];
count=0;
PutMoveNumber(count);
/* check for doubles rolled */
if (Dice[2]!=0)
{
Find4(Board,Dice);
if (count!=0) return(0);
MeInc++;
Find3(Board,Dice);
if (count!=0) return(0);
Find2(Board,Dice);
if (count!=0) return(0);
}
else
{
Find2(Board,Dice);
Dice2[0]=Dice[1];
Dice2[1]=Dice[0];
Dice2[2]=Dice[2];
Dice2[3]=Dice[3];
Find2(Board,Dice2);
if (count!=0) return(0);
MeInc++;
}
Find1(Board,Dice);
return(0);
} /* end of generate */
Find4(Board,Dice)
int Board[26],Dice[4];
{
register int i1,i2,i3,i4;
int Board1[26],Board2[26],Board3[26],Board4[26];
for (i1=0;i1<=24;i1++)
{
if (Board[i1]>0)
if (valid(Board,i1,i1+Dice[0],Dice[0]))
{
CopyBoard(Board,Board1);
update(Board1,i1,i1+Dice[0],1);
for (i2=0;i2<=24;i2++)
{
if (Board1[i2]>0)
if (valid(Board1,i2,i2+Dice[1],Dice[1]))
{
CopyBoard(Board1,Board2);
update(Board2,i2,i2+Dice[1],1);
for (i3=0;i3<=24;i3++)
{
if (Board2[i3]>0)
if (valid(Board2,i3,i3+Dice[2],Dice[2]))
{
CopyBoard(Board2,Board3);
update(Board3,i3,i3+Dice[2],1);
for (i4=0;i4<=24;i4++)
{
if (Board3[i4]>0)
if (valid(Board3,i4,i4+Dice[3],Dice[3]))
{
count++;
CopyBoard(Board3,Board4);
update(Board4,i4,i4+Dice[3],1);
FindMove(Board4,Dice,i1,i2,i3,i4);
}
} /* end for i4 */
} /* end valid Dice[2] */
} /* end for i3 */
} /* end valid Dice[1] */
} /* end for i2 */
} /* end if Valid Dice[0] */
} /* end for i1 */
return(0);
} /* end of Find4 */
Find3(Board,Dice)
int Board[26],Dice[4];
{
register int i1,i2,i3;
int Board1[26],Board2[26],Board3[26];
for (i1=0;i1<=24;i1++)
{
if (Board[i1]>0)
if (valid(Board,i1,i1+Dice[0],Dice[0]))
{
CopyBoard(Board,Board1);
update(Board1,i1,i1+Dice[0],1);
for (i2=0;i2<=24;i2++)
{
if (Board1[i2]>0)
if (valid(Board1,i2,i2+Dice[1],Dice[1]))
{
CopyBoard(Board1,Board2);
update(Board2,i2,i2+Dice[1],1);
for (i3=0;i3<=24;i3++)
{
if (Board2[i3]>0)
if (valid(Board2,i3,i3+Dice[2],Dice[2]))
{
count++;
CopyBoard(Board2,Board3);
update(Board3,i3,i3+Dice[2],1);
FindMove(Board3,Dice,i1,i2,i3,-1);
} /* end valid Dice[2] */
} /* end for i3 */
} /* end valid Dice[1] */
} /* end for i2 */
} /* end if Valid Dice[0] */
} /* end for i1 */
return(0);
} /* end of Find3 */
Find2(Board,Dice)
int Board[26],Dice[4];
{
register int i1,i2;
int Board1[26],Board2[26];
for (i1=0;i1<=24;i1++)
{
if (Board[i1]>0)
if (valid(Board,i1,i1+Dice[0],Dice[0]))
{
CopyBoard(Board,Board1);
update(Board1,i1,i1+Dice[0],1);
for (i2=0;i2<=24;i2++)
{
if (Board1[i2]>0)
if (valid(Board1,i2,i2+Dice[1],Dice[1]))
{
count++;
CopyBoard(Board1,Board2);
update(Board2,i2,i2+Dice[1],1);
FindMove(Board2,Dice,i1,i2,-1,-1);
}/* end valid Dice[1] */
}/* end for i2 */
}/* end if Valid Dice[0] */
}/* end for i1 */
}/* end find2 */
Find1(Board,Dice)
int Board[26],Dice[4];
{
register int i1,i2;
int Board1[26],Dice2[4];
for (i2=0;i2<=1;i2++)
{
Dice2[0]=Dice[i2]; Dice2[1]=0; Dice2[2]=0; Dice2[3]=0;
for (i1=0;i1<=24;i1++)
if (Board[i1]>0) if (valid(Board,i1,i1+Dice[i2],Dice[i2]))
{
count++;
CopyBoard(Board,Board1);
update(Board1,i1,i1+Dice[i2],1);
FindMove(Board1,Dice2,i1,-1,-1,-1);
}
}
return(0);
} /* end of find1 */