various fixes

This commit is contained in:
Rob Pearce 2021-02-21 17:19:03 +11:00
parent 1d1b1b932e
commit 7658823a75
2 changed files with 98 additions and 71 deletions

164
tak.c
View File

@ -1,4 +1,3 @@
// TODO: why isnt this working: never move away from place that would give a win to other p
// TODO: trap ctrl-c // TODO: trap ctrl-c
// TODO: trap ctrl-d // TODO: trap ctrl-d
// TODO: taktak // TODO: taktak
@ -34,6 +33,7 @@
#define FALSE (0) #define FALSE (0)
#define ALL (-1) #define ALL (-1)
#define ANY (-1) #define ANY (-1)
#define NOBOLD (0)
#define BLACK "\e[0;30m" #define BLACK "\e[0;30m"
#define BLUE "\e[0;36m" #define BLUE "\e[0;36m"
@ -45,6 +45,7 @@
#define reset "\e[0m" #define reset "\e[0m"
char board[MAXW*MAXH][MAXBOARDSTRLEN]; char board[MAXW*MAXH][MAXBOARDSTRLEN];
int lastmove[MAXW*MAXH]; // how many tiles were moved here last turn
int aivalue[MAXW*MAXH]; int aivalue[MAXW*MAXH];
int aidef[MAXW*MAXH]; int aidef[MAXW*MAXH];
#define BLOCKED -999 #define BLOCKED -999
@ -92,6 +93,9 @@ void init(void) {
} }
} }
void setlastmove(int x,int y,int ntiles) {
lastmove[y*w+x] = ntiles;
}
int setupround(void) { int setupround(void) {
int i; int i;
@ -100,6 +104,7 @@ int setupround(void) {
for (y=0; y < h; y++) { for (y=0; y < h; y++) {
for (x=0; x < w; x++) { for (x=0; x < w; x++) {
strcpy(board[y*w+x], ""); strcpy(board[y*w+x], "");
setlastmove(x,y,0);
} }
} }
gameover = 0; gameover = 0;
@ -174,6 +179,14 @@ char getmod(char *stack) {
return ' '; return ' ';
} }
// boolean
int hasmod(char *stack) {
if (getmod(stack) == ' ') {
return FALSE;
}
return TRUE;
}
char modprintable(char mod) { char modprintable(char mod) {
switch (mod) { switch (mod) {
case 'C': case 'C':
@ -273,6 +286,16 @@ char *getmodname(int mod) {
char *readcmd(char *cmd) { char *readcmd(char *cmd) {
char turntext[64]; char turntext[64];
int x,y;
// clear out last move
for (y=0; y < h; y++) {
for (x=0; x < w; x++) {
setlastmove(x,y,0);
}
}
if (turnnumber == 1) { if (turnnumber == 1) {
sprintf(turntext, "SETUP: %s%s%s placing %s%s's%s initial tile", getpcol(turn),getpname(turn), reset, getpcol(1-turn),getpname(1-turn),reset); sprintf(turntext, "SETUP: %s%s%s placing %s%s's%s initial tile", getpcol(turn),getpname(turn), reset, getpcol(1-turn),getpname(1-turn),reset);
printf("R%d/%d-T%d. %s %s==> ",curround,numrounds,turnnumber, turntext, getpcol(turn)); printf("R%d/%d-T%d. %s %s==> ",curround,numrounds,turnnumber, turntext, getpcol(turn));
@ -290,6 +313,8 @@ char *readcmd(char *cmd) {
fgets(cmd ,MAX_CMD_LEN, stdin); fgets(cmd ,MAX_CMD_LEN, stdin);
if (cmd) { if (cmd) {
cmd[strlen(cmd)-1] = 0; cmd[strlen(cmd)-1] = 0;
} else {
clearerr(stdin);
} }
} }
printf("%s",reset); printf("%s",reset);
@ -302,7 +327,6 @@ int rowhasmod(int sx, int sy, char mod, int who) {
if (!isvalidxy(sx,sy)) { if (!isvalidxy(sx,sy)) {
return 0; return 0;
} }
for (x=0; x < w; x++) { for (x=0; x < w; x++) {
if (getmodxy(x,sy) == mod) { if (getmodxy(x,sy) == mod) {
if (who == ANY || getownernumxy(x,sy) == who) { if (who == ANY || getownernumxy(x,sy) == who) {
@ -422,11 +446,13 @@ void aiupdatetile(int x, int y) {
// if we already own it, probably dont want to go there // if we already own it, probably dont want to go there
if (getownernumxy(x, y) == turn) { if (getownernumxy(x, y) == turn) {
modaivalue(x,y, -15, "we own this space already"); modaivalue(x,y, -15, "we own this space already");
/*
} else { } else {
n = countadjacent(x,y,turn); n = countadjacent(x,y,turn);
// modify based on adjacent controlled locations // modify based on adjacent controlled locations
snprintf(temp, 1024, "we own %d adjacent cells", n); snprintf(temp, 1024, "we own %d adjacent cells", n);
modaivalue(x,y, n * 1, temp); // controlled by us modaivalue(x,y, n * 1, temp); // controlled by us
*/
} }
if (getownernumxy(x, y) == turn) { if (getownernumxy(x, y) == turn) {
@ -447,11 +473,11 @@ void aiupdatetile(int x, int y) {
snprintf(temp, 1024, "we own %d cells in this row", n); snprintf(temp, 1024, "we own %d cells in this row", n);
modaivalue(x,y, n * 6, temp); modaivalue(x,y, n * 6, temp);
n = rowhasmod(x,y,turn,'|') + rowhasmod(x,y,1-turn,'|'); n = rowhasmod(x,y,'|',turn) + rowhasmod(x,y,'|',1-turn);
snprintf(temp, 1024, "%d walls in this row", n); snprintf(temp, 1024, "%d walls in this row", n);
modaivalue(x,y, -(n * 7), temp); modaivalue(x,y, -(n * 7), temp);
n = rowhasmod(x,y,1-turn,'^'); n = rowhasmod(x,y,'^',1-turn);
snprintf(temp, 1024, "%d opposing capstones in this row", n); snprintf(temp, 1024, "%d opposing capstones in this row", n);
modaivalue(x,y, -(n * 10), temp); modaivalue(x,y, -(n * 10), temp);
@ -586,7 +612,7 @@ char *genaicmd(char *cmd, int showdb, int useworst) {
// we place a tile here or move here? // we place a tile here or move here?
if (canplacetile(turn, xsel, ysel, ' ', NULL)) { if (canplacetile(turn, xsel, ysel, ' ', NULL)) {
char mod = ' '; char mod = ' ';
int chance = aidef[ysel*w+xsel]*15; int chance = aidef[ysel*w+xsel]*10;
// wall or cap? // wall or cap?
if (pctchance(chance)) { if (pctchance(chance)) {
if ((capsleft[turn] > 0) && if ((capsleft[turn] > 0) &&
@ -628,10 +654,14 @@ int xywouldgivewinto(int who, int tx, int ty) {
strcpy(board2[y*w+x], board[y*w+x]); strcpy(board2[y*w+x], board[y*w+x]);
} }
} }
// if player COULD go there,
// force owner of given position to given player // force owner of given position to given player
strcat(board2[ty*w+tx], getpstr(who)); if (canplacetile(who, tx, ty, ' ', NULL) ||
if ( playerhasroads(who, board2)) { canmoveanyto(who, tx, ty, NULL, FALSE)) {
wouldwin = TRUE; strcat(board2[ty*w+tx], getpstr(who));
if ( playerhasroads(who, board2)) {
wouldwin = TRUE;
}
} }
return wouldwin; return wouldwin;
} }
@ -867,8 +897,8 @@ int movetile(int count,char xch,char ych, char dir, char *dropstr) {
int pos,newpos,x,y,mod,origcount; int pos,newpos,x,y,mod,origcount;
int newxch,newych; int newxch,newych;
char countstr[4]; char countstr[4];
char moving[MAXSTACK*2]; char moving[MAXSTACK*30];
char dropping[MAXSTACK*2]; char dropping[MAXSTACK*30];
char *bpos,*newbpos,*p,*dp,*mp; char *bpos,*newbpos,*p,*dp,*mp;
int pass; int pass;
int xmodamt,ymodamt; int xmodamt,ymodamt;
@ -1010,9 +1040,9 @@ int movetile(int count,char xch,char ych, char dir, char *dropstr) {
mp++; // havk mp++; // havk
} }
if (pass == 1) { if (pass == 1) {
char colorstr[MAXSTACK*10]; char colorstr[MAXSTACK*30];
// add ansi color codes // add ansi color codes
makecolorstr(dropping, colorstr); makecolorstr(dropping, colorstr, NOBOLD);
if (debug) { if (debug) {
printf(" - dropping '%s' (%d) at %c%c. remaining: '%s' (%d)\n", printf(" - dropping '%s' (%d) at %c%c. remaining: '%s' (%d)\n",
@ -1021,6 +1051,9 @@ int movetile(int count,char xch,char ych, char dir, char *dropstr) {
} }
// actually drop tiles here // actually drop tiles here
strcat(newbpos, dropping); strcat(newbpos, dropping);
if (numtodrop > 0) {
setlastmove(x,y,numtodrop);
}
} }
// remove dropped tiles from moving stack // remove dropped tiles from moving stack
mp += numtodrop; mp += numtodrop;
@ -1030,6 +1063,7 @@ int movetile(int count,char xch,char ych, char dir, char *dropstr) {
} }
return FALSE; return FALSE;
} }
@ -1082,6 +1116,7 @@ int placetile(int who,char xch,char ych, char mod) {
} else { } else {
tilesleft[who]--; tilesleft[who]--;
} }
setlastmove(x,y,1);
return FALSE; return FALSE;
} }
@ -1131,11 +1166,11 @@ int canmoveanyto(int who, int tx, int ty, char *why, int safe) {
} }
if (ok) { if (ok) {
if (safe) { if (safe) {
if (!canmovefrom(who, x, y, why)) { // got somethong to move here if (!willmovefrom(who, x, y, why)) { // got somethong which is safe to move here
ok = FALSE; ok = FALSE;
} }
} else { } else {
if (!willmovefrom(who, x, y, why)) { // got somethong which is safe to move here if (!canmovefrom(who, x, y, why)) { // got somethong to move here
ok = FALSE; ok = FALSE;
} }
} }
@ -1273,7 +1308,6 @@ int canmakedropstr(int who, int sx, int sy, int dx, int dy, char *str) { // retu
// must drop at least one // must drop at least one
// TODO: figure out how many we can drop and // TODO: figure out how many we can drop and
// still reach dst // still reach dst
// TODO: drop more than 1, prefer our color
//z = strchr(mp, getpchar(who)); //z = strchr(mp, getpchar(who));
// stone to drop. // stone to drop.
@ -1540,15 +1574,30 @@ int parsecmd(char *cmd) {
return err; return err;
} }
char *makecolorstr(char *orig, char *newstr) { char *makecolorstr(char *orig, char *newstr, int lastmovecount) {
char *p; char *p, *curcol, *boldstart = NULL;
char *curcol; if (lastmovecount > 0) {
int count = 0;
for (p = orig+strlen(orig)-1; p >= orig; p--) {
if (*p == getpchar(0) || *p == getpchar(1)) {
count++;
if (count == lastmovecount) {
boldstart = p;
break;
}
}
}
}
// printf("\nmcs(): got lmc = %d, boldidx = %d\n",lastmovecount, boldidx);
strcpy(newstr, ""); strcpy(newstr, "");
for (p = orig; *p; p++) { for (p = orig; *p; p++) {
if (!ismod(*p)) { if (!ismod(*p)) {
curcol = getpcol(getpchar(*p)); curcol = getpcol(getpchar(*p));
strcat(newstr, curcol); strcat(newstr, curcol);
} }
if (boldstart && p >= boldstart && *p != ' ') {
strcat(newstr, BOLD);
}
strncat(newstr, p, 1); strncat(newstr, p, 1);
} }
strcat(newstr, reset); strcat(newstr, reset);
@ -1590,28 +1639,8 @@ void showaivalues(int best) {
// TODO: move this to a function // TODO: move this to a function
// show board stack // show board stack
printf(FORMAT_ROWHEAD, ch); showboardrow(board, y);
for (x=0; x < w; x++) {
char *str = board[y*w+x];
// show stack
if (str) {
char origstr[MAXSTACK*10];
char colorstr[MAXSTACK*10];
sprintf(origstr,FORMAT_STACK, str ? str : " ");
// add ansi color codes
makecolorstr(origstr, colorstr);
//strcpy(colorstr,origstr);
printf("%s", colorstr);
} else {
printf(FORMAT_STACK, " ");
}
}
printf(FORMAT_ROWTAIL, ch);
ch--; ch--;
printf("\n");
line();
} }
printf(FORMAT_ROWHEAD, ' '); printf(FORMAT_ROWHEAD, ' ');
ch = 'a'; ch = 'a';
@ -1630,6 +1659,31 @@ void showaivalues(int best) {
} }
void showboardrow(char (*b)[MAXBOARDSTRLEN], int y) {
int x,ch;
xytopos(0, y, NULL, &ch);
printf(FORMAT_ROWHEAD, ch);
for (x=0; x < w; x++) {
char *str = board[y*w+x];
// show stack
if (str) {
char origstr[MAXSTACK*30];
char colorstr[MAXSTACK*30];
sprintf(origstr,FORMAT_STACK, str ? str : " ");
// add ansi color codes
makecolorstr(origstr, colorstr, lastmove[y*w+x]);
printf("%s", colorstr);
} else {
printf(FORMAT_STACK, " ");
}
}
printf(FORMAT_ROWTAIL, ch);
printf("\n");
line();
}
void showboard(void) { void showboard(void) {
int x,y,i; int x,y,i;
char ch; char ch;
@ -1650,38 +1704,8 @@ void showboard(void) {
line(); line();
ch = '1' + h - 1; ch = '1' + h - 1;
for (y=h-1; y >= 0; y--) { for (y=h-1; y >= 0; y--) {
/* showboardrow(board, y);
printf(FORMAT_ROWHEAD, ch);
for (x=0; x < w; x++) {
char *str = board[y*w+x];
// show owner
printf(FORMAT_OWNER, getpcol(getowner(str)),getowner(str), getmod(str), reset);
}
printf(FORMAT_ROWTAIL, ch);
printf("\n");
*/
printf(FORMAT_ROWHEAD, ch);
for (x=0; x < w; x++) {
char *str = board[y*w+x];
// show stack
if (str) {
char origstr[MAXSTACK*10];
char colorstr[MAXSTACK*10];
sprintf(origstr,FORMAT_STACK, str ? str : " ");
// add ansi color codes
makecolorstr(origstr, colorstr);
//strcpy(colorstr,origstr);
printf("%s", colorstr);
} else {
printf(FORMAT_STACK, " ");
}
}
printf(FORMAT_ROWTAIL, ch);
ch--; ch--;
printf("\n");
line();
} }
printf(FORMAT_ROWHEAD, ' '); printf(FORMAT_ROWHEAD, ' ');
ch = 'a'; ch = 'a';

5
tak.h
View File

@ -5,6 +5,7 @@ int setupround(void);
void line(void); void line(void);
void cleanup(void); void cleanup(void);
char getmod(char *stack); char getmod(char *stack);
int hasmod(char *stack);
char getmodxy(int x, int y); char getmodxy(int x, int y);
char getowner(char *stack); char getowner(char *stack);
int ismod(char ch); int ismod(char ch);
@ -34,7 +35,7 @@ int xtoleftshift(int num);
void printbinaryline(char prefix, int num, int wantcr); void printbinaryline(char prefix, int num, int wantcr);
int playerhasroads(int pnum, char (*b)[]); int playerhasroads(int pnum, char (*b)[]);
void updateroadstatus(void); void updateroadstatus(void);
char *makecolorstr(char *orig, char *newstr); char *makecolorstr(char *orig, char *newstr, int boldidx);
void showscores(char *str); void showscores(char *str);
int checkxyforroad(char (*b)[], int who, int sx, int sy, int sd); int checkxyforroad(char (*b)[], int who, int sx, int sy, int sd);
void pickfirstplayer(void); void pickfirstplayer(void);
@ -70,3 +71,5 @@ void roadlog(char *dname, int dir, int xch, int ych, int newx, int newy);
char getownerxy(int x, int y); char getownerxy(int x, int y);
int getownernumxy(int x, int y); int getownernumxy(int x, int y);
void checkfortak(int who); void checkfortak(int who);
void showboardrow(char (*b)[MAXBOARDSTRLEN], int y);
void setlastmove(int x,int y,int ntiles);