home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 10
/
aminetcdnumber101996.iso
/
Aminet
/
game
/
board
/
Backgammon.lha
/
BackEval.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-12-27
|
10KB
|
395 lines
/********************************************************************/
/* */
/* Hoser BackGammon version 1.0 */
/* */
/* Robert Pfister */
/* Copyright June,1987 all rights reserved. */
/********************************************************************/
/****************************************************************/
/* These routines do all the thinking for the computer side */
/* (read: the magic lives here) */
/****************************************************************/
/* This file contains:
Eval vulnerable doom [CopyBoard]
DoMove FindMove GenerateMoves Find4
Find3 Find2 Find1
*/
#include "back.h"
#include <string.h>
#define Running 1
#define Blocking 2
#define Pegging 3
#define BackGame 4
extern you_me_rec me;
int Moves = 0, AvgPos = 0,
LastVun = 0, list[4][2],
count = 0, max = 0,
GameStat = 0, MaxStat = 0;
const BYTE
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},
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},
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},
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};
int doom(BYTE Board[26])
{
int i, value = 0;
if (LastVun == 0)
return(0);
/* find the "doom" factor..the possibility of getting outa being captured */
for(i = 1;i <= 10; i++)
if (Board[i] < -1)
value += 5;
return(value);
}
int vulnerable(BYTE Board[26], int pos)
{
int i,j,k;
int value = 0;
int HitTable[7][7];
if ( (Board[pos]<0) || (pos == 0) || (Board[pos] >= 2) )
return 0;
memset(&HitTable,0,sizeof HitTable); /* intitialize table */
for(i = 1; i <= 12; i++) /* look at all dice within 12 places */
if (pos-i >= 0) /* within the board */
if (Board[pos-i] < 0) /* there exists a piece at that place */
if (valid(Board,pos,pos-i,i)) { /* can capture legally */
if (i <= 6) /* find hits for one die */
for(j = 1; j <= 6; j++) {
HitTable[i][j] = 1;
HitTable[j][i] = 1;
}
for (j = 1;j < i; j++) { /* figure out combinations */
k = i-j; /* first die is j, second is k */
/* 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 if valid (board,position) */
for(i = 1;i <= 6; i++) /* find how many hits in that table */
for(j = 1;j <= 6; j++)
if (HitTable[i][j] == 1)
value++;
LastVun = value;
return(value);
} /* end of vulnerable */
int Eval(BYTE Board[26])
{
int i;
int num = 0, value = 0, me,you;
int Msum = 0, Ysum = 0;
/* see who is ahead */
for(i = 0; i <=24; i++)
if (Board[i] > 0)
Msum += (25 - i) * Board[i];
for(i = 1; i <= 25; i++)
if (Board[i] < 0)
Ysum -= i * Board[i];
for (i = 0; (i <= 24) && (Board[i] <= 0); i++); /* first occurence of me */
me = i;
for (i = 25; (i >= 1) && (Board[i] >= 0); i--); /* first occurence of you */
you = i;
GameStat = BackGame;/* default case */
if (Ysum > Msum+10) GameStat = Running;/* if closer to winning than them */
if (you > 18) GameStat = Blocking;/* if an opponent is within the bounds */
if (me > you) GameStat = Pegging; /* if complete separation */
for(i = 0; i <= 24; i++) {
if (Board[i] > 0) {
num += Board[i];
switch(GameStat) {
case BackGame:
value += back[i] * Board[i];
if (i < 18)
value += 3 * vulnerable(Board,i);
break;
case Pegging:
value += peg[i] * Board[i];
break;
case Blocking:
value += block[i] * Board[i];
value -= 4 * vulnerable(Board,i);
value -= 6 * doom(Board);
break;
case Running:
value += run[i] * Board[i];
value -= 6 * vulnerable(Board,i);
value -= 6 * doom(Board);
break;
} /* end cases */
} /* end if */
} /* end for */
/* 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;
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;
/* if blocking game, check the block length...add points for more */
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 * 2/3;
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);
}
/* copy board 1 to board 2 */
#define CopyBoard(b1, b2) memcpy(b2,b1,sizeof_board)
void DoMove(BYTE Board[26], BYTE Dice[4])
{
int j;
AvgPos += count;
/* don't do anything if nothing to be done */
if (count == 0) {
DoMenuStrip("Can't move from this position!!");
me.wasted += Dice[0] + Dice[1] + Dice[2] + Dice[3];
}
else {
PutMoveNumber(count);
/* show move */
for(j = 0; j <= 3; j++)
if (list[j][0] != -1) {
BlinkPiece(Board,list[j][0]);
update(Board,list[j][0], list[j][1] ,1);
PutSpike( list[j][0],Board[list[j][0]] );
if ((list[j][1] > 0) && (list[j][1] < 25)) /******/
BlinkPiece(Board,list[j][1]);
if (list[j][0] == 0)
me.wasted += list[j][1];
}
else
me.wasted += Dice[j];
/* touch up the bars */
PutSpike(0 ,Board[ 0]);
PutSpike(25,Board[25]);
}
}
void FindMove(BYTE Board[26],BYTE Dice[4], int i1, int i2, int i3,int 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];
}
}
void Find1(BYTE Board[26], BYTE Dice[4])
{
int i1,i2;
BYTE 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);
}
}
} /* end of find1 */
void Find2(BYTE Board[26], BYTE Dice[4])
{
int i1, i2;
BYTE 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 */
void Find3(BYTE Board[26], BYTE Dice[4])
{
int i1,i2,i3;
BYTE 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 */
} /* end of Find3 */
void Find4(BYTE Board[26], BYTE Dice[4])
{
int i1, i2, i3, i4;
BYTE 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 */
} /* end of Find4 */
void GenerateMoves(BYTE Board[26], BYTE Dice[4])
{
BYTE Dice2[4];
count = 0;
PutMoveNumber(count);
/* check for doubles rolled */
if (Dice[2] != 0) {
Find4(Board,Dice);
if (count != 0)
return;
me.incomplete++;
Find3(Board,Dice);
if (count != 0)
return;
Find2(Board,Dice);
if (count != 0)
return;
}
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;
me.incomplete++;
}
Find1(Board,Dice);
} /* end of generate */