/* Program: Zappa */
/* David Roe */
/* Email: roe@research.att.com */
/* Compile: cc -O Zappa.c */
/* Run: a.out FILENAME
#include
#include
/*******************/
/* MACROS */
/*******************/
#define MAXROW 9 /* number of rows */
#define MAXCOL 26 /* number of columns */
#define MAXMOVE 100 /* max number of moves in the game */
#define LINEL 80 /* maximum line length in input */
#define INST_SIZE 9 /* maximum characters in an instruction */
#define FFACTOR 1.0 /* Fudge-factor for leaky average */
#define min(x,y) ((x)<(y) ? (x) : (y))
#define max(x,y) ((x)>(y) ? (x) : (y))
#define abs(x) (((x)>0) ? (x) : (-(x)))
#define round(x) (((x)>0) ? (int)((x)+.5) : (int)((x)-.5))
#define out4(f,ss,inst) if(inst.comm[0]!='\0') fprintf(f,"%s \t%s\n",ss,inst2str(buf,&inst))
#define out3(f,str,row,col) fprintf(f,"%s\t%c %d\n",str,'A'-1+row,col)
#define out2(f,str,value) fprintf(f,"%s %d\n",str,value)
#define outfloat(f,str,value) fprintf(f,"%s %.2f\n",str,value)
#define SOK(x) strtok(x," \t\n")
#define SOK2 strtok(NULL," \t\n")
/********************/
/* STRUCTURE DEFN */
/********************/
struct Inst {
char comm[INST_SIZE+1];
int row;
int col;
};
/*******************/
/* EXTERNAL MEMORY */
/*******************/
int wall_r[2*MAXMOVE], wall_c[2*MAXMOVE], nwalls=0;
/*******************/
/* SUBROUTINES */
/*******************/
int normc(int col) { /* Truncate to a column value */
if(col<=1) return 1; /* between 1 and MAXCOL */
if(col>=MAXCOL) return MAXCOL;
return(col);
}
int normr(int row) { /* Truncate to a row value */
if(row<1) return 1; /* between 1 and MAXROW */
if(row>MAXROW) return MAXROW;
return(row);
}
char *inst2str(char *buf,struct Inst *pinstr) {
if(pinstr->row>0)
sprintf(buf,"%s %c %d",pinstr->comm,'A'-1+pinstr->row,pinstr->col);
else
sprintf(buf,"%s",pinstr->comm);
return buf;
}
int is_wallat(int row, int col) { /* Check if a wall is at (row,col) */
int i;
for(i=0;iMAXROW||mcol>MAXCOL)
return(5); /* move off the board */
if(mrow==frow) {
if(mcol==fcol) return(3); /* same space */
if(abs(mcol-fcol)==1) {
if(is_wallat(mrow,mcol)) return(1); /* there's a wall there */
return(0); /* a legal move */
}
else return(2); /* OK for zap, not for move */
}
else if(mcol==fcol) {
if(abs(mrow-frow)==1) {
if(is_wallat(mrow,mcol)) return(1); /* there's a wall there */
return(0); /* a legal move */
}
else return(2); /* OK for zap, not for move */
}
else return(4); /* too far to move */
}
void dumpout(FILE *fp, int me_first, int my_row, int my_col, int my_turns,
int op_row,int op_col,int op_turns,
int max_row, int max_col, float rv_dist, float cv_dist, float v_time,
int my_hello,int my_ouchs,
int nwalls, int *wall_r, int *wall_c,
struct Inst c_move, struct Inst p_feedback, struct Inst p_move) {
int i;
char buf[LINEL+1];
out2(fp,"me_first", me_first);
out3(fp,"my_pos",my_row,my_col);
out2(fp,"my_turns", my_turns);
out3(fp,"op_pos",op_row,op_col);
out2(fp,"op_turns", op_turns);
out3(fp,"max_pos",max_row,max_col);
outfloat(fp,"rv_dist",rv_dist);
outfloat(fp,"cv_dist",cv_dist);
outfloat(fp,"v_time",v_time);
if(my_hello>0) out2(fp,"my_hello",my_hello);
if(my_ouchs>0) out2(fp,"my_ouchs",my_ouchs);
for(i=0;i1.0 */
*prv_dist=min(*pv_time,*prv_dist); /* distances may be + or - */
*prv_dist=max(-*pv_time,*prv_dist);
*pcv_dist=min(*pv_time,*pcv_dist);
*pcv_dist=max(-*pv_time,*pcv_dist);
*pop_row=*pmax_row=*pest_row=newrow; /* update the positions */
*pop_col=*pmax_col=*pest_col=newcol;
*pop_turns=newturns; /* update the number of turns */
}
int zap_wall(int row, int col) { /* Zap a wall at position (row,col) */
int i;
for(i=0;i0? 1 : -1);
}
else if(ccol==dcol) {
dc=0;
dr=(drow-crow>0? 1 : -1);
}
else {
printf("bad direction in rm_wall: crow=%d, ccol=%d, drow=%d, dcol=%d\n",
crow,ccol, drow,dcol);
return(-1);
}
while(crow>=1 && ccol<=MAXCOL && ccol>=1 && crow<=MAXROW) {
crow+=dr;
ccol+=dc;
if(zap_wall(crow,ccol)>0) { /* zapped it */
return(0);
}
}
return(-1); /* found no wall to zap */
}
void setinst(struct Inst *pinstr, char *command, int row, int col)
{
strncpy(pinstr->comm,command,INST_SIZE);
pinstr->row=row;
pinstr->col=col;
}
void printinst(struct Inst *pinstr)
{
char buf[LINEL+1];
printf("%s\n",inst2str(buf,pinstr));
}
static int rrc(int *prow, int *pcol) {
char *cptr,stri[INST_SIZE+1];
if((cptr=SOK2)==NULL) {
printf("rrc(): illegal command\n");
return(-1);
}
strcpy(stri,cptr);
if(stri[0]=='\0') printf("bad stdin\n");
if((int)strlen(stri)>1 || stri[0]<'A' || stri[0]>'I') {
printf("illegal row %s in a move\n", stri);
return(-1);
}
*prow=*stri-'A'+1;
if((cptr=SOK2)==NULL) {
printf("illegal command\n");
return(-1);
}
*pcol= atoi(cptr);
if(*pcol<=0 || *pcol>MAXCOL) {
printf("illegal col %d in a move\n", *pcol);
return(-1);
}
return(2);
}
int readinst(char *buf, struct Inst *pinstr)
{
strncpy(pinstr->comm,SOK(buf),INST_SIZE);
if(
strcmp(pinstr->comm,"ZAP")==0 ||
strcmp(pinstr->comm,"MOVE")==0 ||
strcmp(pinstr->comm,"WALL")==0 ||
strcmp(pinstr->comm,"INIT")==0 ||
strcmp(pinstr->comm,"LOC")==0 ||
strcmp(pinstr->comm,"AT")==0) {
if(rrc(&pinstr->row,&pinstr->col)<0) {
printf("bad move %s\n",buf);
return(-1);
}
}
else if(
strcmp(pinstr->comm,"RADAR")==0 ||
strcmp(pinstr->comm,"HELP")==0 ||
strcmp(pinstr->comm,"OK")==0 ||
strcmp(pinstr->comm,"ERROR")==0 ||
strcmp(pinstr->comm,"OUCH")==0 ||
strcmp(pinstr->comm,"HELLO")==0 ||
strcmp(pinstr->comm,"OOPS")==0 ||
strcmp(pinstr->comm,"MISS")==0 ||
strcmp(pinstr->comm,"BOOM")==0 ||
strcmp(pinstr->comm,"HIT")==0
) {
pinstr->row=0;
pinstr->col=0;
}
else {
printf("illegal instruction, %s\n",pinstr->comm);
return(-1);
}
return(0);
}
/********************/
/* MAIN PROGRAM */
/********************/
main(int argc, char **argv) {
struct Inst feedback,c_move,p_move,p_feedback,n_move;
int i,row,col,me_first;
char *s,buf[LINEL+1],quantity[LINEL+1];
int op_turns=0, my_turns=0, my_ouchs=0, my_hello=0;
FILE *fp;
int nturns; /* opponent turns since latest radar */
int delta; /* the direction I'm going */
int closecol; /* =1 if opponent is closer to my colum */
/* than my row */
int my_row, my_col; /* my known position */
int my_rowt, my_colt; /* my target in the corner */
int op_row, op_col; /* opponent's latest known position */
int op_rowt, op_colt; /* opponent's target in the corner */
float est_row, est_col; /* estimated op's row&col position */
float est_vrow, est_vcol; /* estimated op's row&col position, */
/* based on current velocity */
float est_speed; /* estimated op's probability of moving */
int max_row, max_col; /* opponent's furthest possible position */
int del_op_row, del_op_col; /* difference between op's latest position */
/* and mine */
float del_est_row,del_est_col;/* estimated difference between op's position */
/* and mine */
int del_max_row, del_max_col; /* max difference between op's position */
/* and mine */
int md; /* minimum distance, based on op's */
/* latest known position */
int nmd; /* new minimum distance, based on op's */
/* futhest position */
int my_dist; /* distance I need to travel */
int op_dist; /* distance op needs to travel */
int est_dist; /* distance op might still need to travel */
/* based on estimated position */
int im_confused=0; /* indicates total confusion if ==1 */
int im_past_col, im_past_row; /* 1 if I have passed op's row or col */
int im_quad2; /* quadrant you are in */
int im_hunting; /* 1 if Im_quad2, */
/* and farther from goal than op */
/* 0 if opponent has farther to go than me */
int im_desperate; /* opponent is about to win */
float rv_dist, cv_dist; /* av. distance op moved in v_time turns */
float v_time; /* turns over which op's velocity is computed*/
/* STRATEGY FACTORS */
float pmovm; /* prob. to move in "minimum" direction */
float pmovo; /* prob. to move in "other" direction */
float prad; /* prob. to use radar */
float pzap; /* prob. to zap in "minimum" direction */
float ranprob; /* random value, compare to prob's */
/********************/
/* GET OPTIONS */
/********************/
while(--argc>0 && (*++argv)[0] =='-') {
for(s=argv[0]+1;*s!='\0';s++) {
switch (*s) {
default:
printf("Zappa: illegal option %s\n",s);
printf("usage: Zappa memory_file\n");
exit(1);
}
}
}
if(argc!=1) {
printf("incorrect argument count %d\n",argc);
exit(-1);
}
/*************************/
/* GET STDIN FEEDBACK */
/*************************/
fgets(buf, LINEL, stdin);
if(readinst(buf,&feedback)<0)
printf("bad input ""%s..."" in stdin\n",buf);
c_move.comm[0]=p_move.comm[0]=p_feedback.comm[0]='\0';
/*************************/
/* EITHER INITIALIZE... */
/*************************/
if(strcmp(feedback.comm,"INIT")==0) {
my_hello=my_ouchs=0;
if(feedback.row==1 && feedback.col==1) {
me_first=1;
my_turns=0;
op_row=max_row=est_row=MAXROW;
op_col=max_col=est_col=MAXCOL;
}
else if(feedback.row==MAXROW && feedback.col==MAXCOL) {
my_turns=1; /* pretend you took a null turn */
me_first=0;
op_row=max_row=est_row=1;
op_col=max_col=est_col=1;
}
else {
printf("bad initial row-col value %d %d\n",feedback.row,feedback.col);
exit(1);
}
my_row=feedback.row;
my_col=feedback.col;
}
/*************************/
/* ...OR READ INPUT FILE */
/*************************/
else {
if((fp=fopen(argv[0],"r"))==NULL) {
printf("cannot open memory_file named %s\n",argv[0]);
exit(-1);
}
while ( fgets(buf, LINEL, fp) != NULL) {
strcpy(quantity,buf);
SOK(quantity);
if(strcmp(quantity,"my_pos")==0) {
rrc(&my_row,&my_col);
}
else if(strcmp(quantity,"op_pos")==0) {
rrc(&op_row,&op_col);
}
else if(strcmp(quantity,"max_pos")==0) {
rrc(&max_row,&max_col);
}
else if(strcmp(quantity,"my_turns")==0)
my_turns=atoi(SOK2);
else if(strcmp(quantity,"op_turns")==0)
op_turns=atoi(SOK2);
else if(strcmp(quantity,"my_ouchs")==0)
my_ouchs=atoi(SOK2);
else if(strcmp(quantity,"my_hello")==0)
my_hello=atoi(SOK2);
else if(strcmp(quantity,"me_first")==0)
me_first=atoi(SOK2);
else if(strcmp(quantity,"rv_dist")==0)
rv_dist=atof(SOK2);
else if(strcmp(quantity,"cv_dist")==0)
cv_dist=atof(SOK2);
else if(strcmp(quantity,"v_time")==0)
v_time=atof(SOK2);
else if(strcmp(quantity,"wall_at")==0) {
rrc(&row,&col);
buildwall(row,col);
}
else if(strcmp(quantity,"c_move")==0) {
readinst((char *)(buf+7),&c_move);
}
else if(strcmp(quantity,"p_move")==0) {
readinst(buf+7,&p_move);
}
else if(strcmp(quantity,"p_feedback")==0) {
readinst(buf+11,&p_feedback);
}
}
fclose(fp);
}
/*******************/
/* INITIAL SET-UP */
/*******************/
if(me_first>0) { /* I am first player */
op_rowt=op_colt=1;
delta=1; /* my direction is 1, lower to higher, */
my_rowt=MAXROW;
my_colt=MAXCOL;
}
else { /* I am second player */
my_rowt=my_colt=1;
delta=(-1); /* my direction is -1, higher to lower */
op_rowt=MAXROW;
op_colt=MAXCOL;
}
/**********************/
/* PROCESS FEEDBACK */
/**********************/
if(strcmp(feedback.comm,"INIT")==0) { /* INIT: do nothing */
rv_dist= -delta*(MAXROW/(float)(MAXROW+MAXCOL+1));
cv_dist= -delta*(MAXCOL/(float)(MAXROW+MAXCOL+1));
v_time=1.;
}
else if(strcmp(c_move.comm,"RADAR")==0) {
if(strcmp(feedback.comm,"AT")==0) {
updop(feedback.row, feedback.col, my_turns-1, &op_row, &op_col,
&max_row, &max_col, &est_row, &est_col, &op_turns,
&rv_dist, &cv_dist, &v_time);
}
else {
printf("bad feedback for RADAR: %s\n",inst2str(buf,&feedback));
exit(1);
}
}
else if(strcmp(c_move.comm,"WALL")==0) {
if(strcmp(feedback.comm,"OK")==0) { /* I built a wall! */
buildwall(c_move.row,c_move.col);
}
else if(strcmp(feedback.comm,"OOPS")==0) { /* Opponent was there*/
updop(c_move.row, c_move.col, my_turns-1, &op_row, &op_col,
&max_row, &max_col, &est_row, &est_col, &op_turns,
&rv_dist, &cv_dist, &v_time);
}
else if(strcmp(feedback.comm,"ERROR")==0) { /* Wall not built */
if(c_move.row<1 ||c_move.col<1 ||c_move.row>MAXROW||c_move.col>MAXCOL) {
;
}
else {
my_row=c_move.row;
my_col=c_move.col;
}
}
else {
printf("Illegal feedback to WALL command: %s\n",feedback.comm);
dumpout(stdout,me_first,my_row,my_col,my_turns,op_row,op_col,op_turns,
max_row,max_col,rv_dist,cv_dist,v_time,
my_hello, my_ouchs,nwalls,wall_r,wall_c,
c_move,p_feedback,p_move);
exit(1);
}
}
else if(strcmp(c_move.comm,"MOVE")==0) {
if(strcmp(feedback.comm,"OK")==0) { /* I moved! */
my_row=c_move.row;
my_col=c_move.col;
}
else if(strcmp(feedback.comm,"OUCH")==0) { /* I hit a wall */
buildwall(c_move.row,c_move.col);
my_ouchs++;
}
else if(strcmp(feedback.comm,"HELLO")==0) { /* Opponent is here! */
updop(c_move.row, c_move.col, my_turns-1, &op_row, &op_col,
&max_row, &max_col, &est_row, &est_col, &op_turns,
&rv_dist, &cv_dist, &v_time);
my_hello++;
}
else if(strcmp(feedback.comm,"ERROR")==0) {
i=checkmove(c_move.row,c_move.col,my_row,my_col);
if(i==0) /* I'm not in right place */
im_confused=1;
}
else {
printf("Illegal feedback to MOVE command: %s\n",feedback.comm);
dumpout(stdout,me_first,my_row,my_col,my_turns,op_row,op_col,op_turns,
max_row,max_col,rv_dist,cv_dist,v_time,
my_hello, my_ouchs,nwalls,wall_r,wall_c,
c_move,p_feedback,p_move);
exit(1);
}
}
else if(strcmp(c_move.comm,"ZAP")==0) {
if(strcmp(feedback.comm,"MISS")==0) { /* No walls! */
/* remove all "stray" walls along the path */
while(rm_wall(my_row,my_col,c_move.row,c_move.col)>=0);
/* check if max row or column is forbidden 'cause there was no HIT*/
/* zap along row */
if(max_row==my_row && (c_move.col-my_col)*(max_col-my_col)>=0
&& (c_move.col-my_col)*(op_col-my_col)>0 ) {
max_row+=delta;
}
/* zap along column */
if(max_col==my_col && (c_move.row-my_row)*(max_row-my_row)>=0
&& (c_move.row-my_row)*(op_row-my_row)>0 ) {
max_col+=delta;
}
/* check if op_row or op_col is forbidden 'cause there was no HIT */
/* zap along row */
if(op_row==my_row && (c_move.col-my_col)*(max_col-my_col)>=0
&& (c_move.col-my_col)*(op_col-my_col)>0 ) {
op_row-=delta;
}
/* zap along column */
if(op_col==my_col && (c_move.row-my_row)*(max_row-my_row)>=0
&& (c_move.row-my_row)*(op_row-my_row)>0 ) {
op_col-=delta;
}
}
else if(strcmp(feedback.comm,"BOOM")==0) { /* I hit a wall */
/* remove the first wall along the path */
rm_wall(my_row,my_col,c_move.row,c_move.col);
}
else if(strcmp(feedback.comm,"HIT")==0) { /* Opp. is somewhere here! */
if(c_move.row==my_row)
op_row=est_row=max_row=c_move.row;
else
op_col=est_col=max_col=c_move.col;
op_turns=my_turns; /* set ZAP flag */
}
else if(strcmp(feedback.comm,"ERROR")==0) {
i=checkmove(c_move.row,c_move.col,my_row,my_col);
if(i==0 || i==2) /* I'm in the wrong place */
im_confused=1;
}
else {
printf("Illegal feedback to ZAP command: %s\n",feedback.comm);
dumpout(stdout,me_first,my_row,my_col,my_turns,op_row,op_col,op_turns,
max_row,max_col,rv_dist,cv_dist,v_time,
my_hello, my_ouchs,nwalls,wall_r,wall_c,
c_move,p_feedback,p_move);
exit(1);
}
}
else if(strcmp(c_move.comm,"HELP")==0) {
if(strcmp(feedback.comm,"LOC")==0) { /* Get my position */
my_row=feedback.row;
my_col=feedback.col;
}
}
else {
printf("illegal c_move: %s\n",c_move.comm);
dumpout(stdout,me_first,my_row,my_col,my_turns,op_row,op_col,op_turns,
max_row,max_col,rv_dist,cv_dist,v_time,
my_hello, my_ouchs,nwalls,wall_r,wall_c,
c_move,p_feedback,p_move);
exit(1);
}
/*************************/
/* ANALYZE POSITION */
/*************************/
nturns=my_turns-op_turns;
/* estimate op's position */
my_dist=abs((my_col-my_colt)+(my_row-my_rowt));
if(my_dist==0) im_confused=1;
op_dist=abs((op_col-op_colt)+(op_row-op_rowt));
/* increment max_row and max_col */
max_row=normr(max_row-(op_turnsabs(max_row-op_row))
est_row=max_row;
est_col=op_col-nturns*est_speed*(op_col-op_colt)/(float)op_dist;
if(abs(est_col-op_col)>abs(max_col-op_col))
est_col=max_col;
/* estimate position based on cur. velocity */
est_vrow=op_row+nturns*rv_dist/v_time;
if(abs(est_vrow-op_row)>abs(max_row-op_row))
est_vrow=max_row;
est_vcol=op_col+nturns*cv_dist/v_time;
if(abs(est_vcol-op_col)>abs(max_col-op_col))
est_vcol=max_col;
/* average est_pos and est_vpos */
est_row=(est_row+est_vrow)/2;
est_col=(est_col+est_vcol)/2;
/* check for symtoms of zapping to */
/* limit min_col */
if((op_col-max_col)*delta==1) {
est_col=op_col+(1./nturns)*(est_col-op_col);
}
if((op_row-max_row)*delta==1) {
est_row=op_row+(1./max(1,nturns))*(est_row-op_row);
}
del_op_row=delta*(op_row-my_row); /* if del_op_row>0, opponent is */
del_op_col=delta*(op_col-my_col); /* positioned "ahead" of me */
del_est_row=delta*(est_row-my_row);
del_est_col=delta*(est_col-my_col);
del_max_row=delta*(max_row-my_row);
del_max_col=delta*(max_col-my_col);
/* closecol=1 if op is closer to col than row */
/* closecol depends on del_max_pos first... */
if(del_max_col!=del_max_row && (del_max_col>0||del_max_row>0))
closecol=(del_max_colabs(est_col-my_col) ? 1 : 0);
md=(closecol ? max(del_est_col,del_op_col) : max(del_est_row,del_op_row));
nmd=(closecol ? del_max_col : del_max_row);
est_dist=max(1,round(abs((est_col-op_colt)+(est_row-op_rowt))));
im_past_row = ((abs(est_row-my_rowt)>abs(my_row-my_rowt)) ? 1 : 0);
im_past_col = ((abs(est_col-my_colt)>abs(my_col-my_colt)) ? 1 : 0);
im_quad2 = ((im_past_row+im_past_col)==2 ? 1 : 0 );
im_hunting = ((im_quad2 && my_dist>est_dist ) ? 1 : 0 );
if (nturns>0 && (nmd<(-1) || (nmd<0 && op_dist<=2) || est_dist<=1.2))
im_desperate =(((im_hunting && (est_dist<=2) || op_dist<=3)) ? 1 : 0);
else im_desperate=0;
/*********************/
/* TABLE OF STRATEGY */
/*********************/
if(md>=3 && nmd>=2) { pmovm=.2; pmovo=.8; prad=.0; pzap=.0; } /*pwall =.0*/ /* at beginning, know exact op position */
if(md>=3 && nmd==md) { pmovm=.0; pmovo=.1; prad=.0; pzap=.0; } /*pwall =.9*/
if(md>=3 && nmd==md-1) { pmovm=.1; pmovo=.8; prad=.0; pzap=.0; } /*pwall =.1*/
/* the order is important here */
if(md>=3 && nmd==1) { pmovm=.0; pmovo=.1; prad=.9; pzap=.0; }
if(md>=3 && nmd==0) { pmovm=.0; pmovo=.0; prad=.5; pzap=.5; }
if(md>=3 && nmd <0) { pmovm=.0; pmovo=.0; prad=1.; pzap=.0; }
if(md==2 && nmd>=1) { pmovm=.2; pmovo=.8; prad=.0; pzap=.0; }
if(md==2 && nmd==0) { pmovm=.0; pmovo=.1; prad=.1; pzap=.8; }
if(md==2 && nmd==(-1)) { pmovm=.0; pmovo=.0; prad=.5; pzap=.5; }
if(md==2 && nmd<=(-2)) { pmovm=.0; pmovo=.0; prad=1.; pzap=.0; }
if(md==1 && nmd>=1) { pmovm=.1; pmovo=.1; prad=.2; pzap=.6; }
if(md==1 && nmd==0) { pmovm=.0; pmovo=.3; prad=.0; pzap=.7; }
if(md==1 && nmd==(-1)) { pmovm=.0; pmovo=.1; prad=.2; pzap=.7; }
if(md==1 && nmd==(-2)) { pmovm=.0; pmovo=.1; prad=.7; pzap=.2; }
if(md==1 && nmd<=(-3)) { pmovm=.0; pmovo=.0; prad=1.; pzap=.0; }
if(md==0 && nmd==0) { pmovm=.0; pmovo=.0; prad=.0; pzap=1.; }
if(md==0 && nmd==(-1)) { pmovm=.3; pmovo=.0; prad=.0; pzap=.7; }
if(md==0 && nmd==(-2)) { pmovm=.6; pmovo=.1; prad=.0; pzap=.3; }
if(md==0 && nmd<=(-3)) { pmovm=.0; pmovo=.0; prad=.7; pzap=.3; }
if(md==(-1) && nmd>=(-1)) { pmovm=.1; pmovo=.75; prad=.0; pzap=.15; }
if(md==(-1) && nmd==(-2)) { pmovm=.5; pmovo=.3; prad=.0; pzap=.1; }
if(md==(-1) && nmd<=(-3)) { pmovm=.6; pmovo=.0; prad=.4; pzap=.0; }
if(md<=(-2) && nmd==md-1) { pmovm=.6; pmovo=.1; prad=.0; pzap=.0; } /*pwall=.3*/
if(md<=(-2) && nmd!=md-1 && my_dist=est_dist)
{ pmovm=.6; pmovo=.0; prad=.3; pzap=.0; }
/*************************/
/* FIGURE OUT STRATEGY */
/*************************/
srand(11*my_turns+7*me_first+3*(int)time(NULL));
rand();
newrand:
ranprob=rand()/32768.;
/*****************/
/* HELP COMMAND */
/*****************/
if(im_confused>0)
setinst(&n_move,"HELP",0,0);
/***********************/
/* DESPERATE COMMANDS */
/***********************/
else if(im_desperate>0) {
if(ranprob<0.4 || op_dist<=2)
setinst(&n_move,"WALL",op_rowt,op_colt);
else
setinst(&n_move,"RADAR",0,0);
}
/******************/
/* MOVE COMMAND */
/******************/
else if(ranprob0)
/* o dir. is illegal */
setinst(&n_move,"ZAP",m_row,m_col); /* zap in m_direction */
else setinst(&n_move,"MOVE",o_row,o_col); /* else substitue movo */
}
else setinst(&n_move,"MOVE",m_row,m_col);
}
else { /* move along other direction */
/* check whether movo is legal, smart */
if(checkmove(o_row,o_col,my_row,my_col)==5) {
/* o dir. is off board */
if(pmovo<1.0) goto newrand;
else setinst(&n_move,"RADAR",0,0); /* this is a cop-out */
}
else if(checkmove(o_row,o_col,my_row,my_col)==1) {
/* There's a wall */
/* check whether to substitute movm */
if(pmovm==0. || checkmove(m_row,m_col,my_row,my_col)>0)
/* m dir. is illegal */
setinst(&n_move,"ZAP",o_row,o_col); /* zap in o_direction */
else setinst(&n_move,"MOVE",m_row,m_col); /* else substitiue movm */
}
else setinst(&n_move,"MOVE",o_row,o_col); /* normal movo */
}
}
/*******************/
/* RADAR COMMAND */
/*******************/
else if(ranprobnturns)
zr=(op_row>my_row? 1 : -1); /* row won't reach; zap column */
else if(abs(my_col-op_col)>nturns)
zc=(op_col>my_col ? 1 : -1); /* column won't reach; zap row */
else { /* else zap toward the opponent */
if(closecol)
zr=(est_row>my_row ? 1 : -1);
else
zc=(est_col>my_col ? 1 : -1);
}
setinst(&n_move,"ZAP",my_row+zr,my_col+zc);
}
/*******************/
/* WALL COMMAND */
/*******************/
else { /* P(wall) is left over */
/* put a wall in front of the opp */
int nr,nc,ec,er;
er=normr(round(est_row));
ec=normc(round(est_col));
for(i=1;i<20;i++) {
nr=normr(round(est_row+i*rv_dist));
nc=normc(round(est_col+i*cv_dist));
if(nr==er && nc==ec) continue;
if(is_wallat(nr,nc)) continue;
setinst(&n_move,"WALL",nr,nc);
goto ewall;
}
nr=normr(round(est_row-delta));
nc=normc(round(est_col-delta));
setinst(&n_move,"WALL",nr,nc);
ewall:
;
}
/******************/
/* FINAL OUTPUT */
/******************/
my_turns++;
printinst(&n_move);
if((fp=fopen(argv[0],"w"))==NULL) {
printf("cannot open memory_file named %s for writing\n",argv[0]);
exit(-1);
} /* save all information in a temp file */
dumpout(fp,me_first,my_row,my_col,my_turns,op_row,op_col,op_turns,
max_row,max_col,rv_dist,cv_dist,v_time,
my_hello, my_ouchs,nwalls,wall_r,wall_c,
n_move,feedback,c_move); /* substitute n_move for c_move, */
/* substitute c_move for p_move */
fclose(fp);
return(0);
}