diff --git a/tak.c b/tak.c index 971c8ff..bcb1097 100644 --- a/tak.c +++ b/tak.c @@ -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-d // TODO: taktak @@ -34,6 +33,7 @@ #define FALSE (0) #define ALL (-1) #define ANY (-1) +#define NOBOLD (0) #define BLACK "\e[0;30m" #define BLUE "\e[0;36m" @@ -45,6 +45,7 @@ #define reset "\e[0m" char board[MAXW*MAXH][MAXBOARDSTRLEN]; +int lastmove[MAXW*MAXH]; // how many tiles were moved here last turn int aivalue[MAXW*MAXH]; int aidef[MAXW*MAXH]; #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 i; @@ -100,6 +104,7 @@ int setupround(void) { for (y=0; y < h; y++) { for (x=0; x < w; x++) { strcpy(board[y*w+x], ""); + setlastmove(x,y,0); } } gameover = 0; @@ -174,6 +179,14 @@ char getmod(char *stack) { return ' '; } +// boolean +int hasmod(char *stack) { + if (getmod(stack) == ' ') { + return FALSE; + } + return TRUE; +} + char modprintable(char mod) { switch (mod) { case 'C': @@ -273,6 +286,16 @@ char *getmodname(int mod) { char *readcmd(char *cmd) { 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) { 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)); @@ -290,6 +313,8 @@ char *readcmd(char *cmd) { fgets(cmd ,MAX_CMD_LEN, stdin); if (cmd) { cmd[strlen(cmd)-1] = 0; + } else { + clearerr(stdin); } } printf("%s",reset); @@ -302,7 +327,6 @@ int rowhasmod(int sx, int sy, char mod, int who) { if (!isvalidxy(sx,sy)) { return 0; } - for (x=0; x < w; x++) { if (getmodxy(x,sy) == mod) { 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 (getownernumxy(x, y) == turn) { modaivalue(x,y, -15, "we own this space already"); +/* } else { n = countadjacent(x,y,turn); // modify based on adjacent controlled locations snprintf(temp, 1024, "we own %d adjacent cells", n); modaivalue(x,y, n * 1, temp); // controlled by us +*/ } 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); 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); 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); 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? if (canplacetile(turn, xsel, ysel, ' ', NULL)) { char mod = ' '; - int chance = aidef[ysel*w+xsel]*15; + int chance = aidef[ysel*w+xsel]*10; // wall or cap? if (pctchance(chance)) { 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]); } } + // if player COULD go there, // force owner of given position to given player - strcat(board2[ty*w+tx], getpstr(who)); - if ( playerhasroads(who, board2)) { - wouldwin = TRUE; + if (canplacetile(who, tx, ty, ' ', NULL) || + canmoveanyto(who, tx, ty, NULL, FALSE)) { + strcat(board2[ty*w+tx], getpstr(who)); + if ( playerhasroads(who, board2)) { + wouldwin = TRUE; + } } 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 newxch,newych; char countstr[4]; - char moving[MAXSTACK*2]; - char dropping[MAXSTACK*2]; + char moving[MAXSTACK*30]; + char dropping[MAXSTACK*30]; char *bpos,*newbpos,*p,*dp,*mp; int pass; int xmodamt,ymodamt; @@ -1010,9 +1040,9 @@ int movetile(int count,char xch,char ych, char dir, char *dropstr) { mp++; // havk } if (pass == 1) { - char colorstr[MAXSTACK*10]; + char colorstr[MAXSTACK*30]; // add ansi color codes - makecolorstr(dropping, colorstr); + makecolorstr(dropping, colorstr, NOBOLD); if (debug) { 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 strcat(newbpos, dropping); + if (numtodrop > 0) { + setlastmove(x,y,numtodrop); + } } // remove dropped tiles from moving stack mp += numtodrop; @@ -1030,6 +1063,7 @@ int movetile(int count,char xch,char ych, char dir, char *dropstr) { } + return FALSE; } @@ -1082,6 +1116,7 @@ int placetile(int who,char xch,char ych, char mod) { } else { tilesleft[who]--; } + setlastmove(x,y,1); return FALSE; } @@ -1131,11 +1166,11 @@ int canmoveanyto(int who, int tx, int ty, char *why, int safe) { } if (ok) { 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; } } 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; } } @@ -1273,7 +1308,6 @@ int canmakedropstr(int who, int sx, int sy, int dx, int dy, char *str) { // retu // must drop at least one // TODO: figure out how many we can drop and // still reach dst - // TODO: drop more than 1, prefer our color //z = strchr(mp, getpchar(who)); // stone to drop. @@ -1540,15 +1574,30 @@ int parsecmd(char *cmd) { return err; } -char *makecolorstr(char *orig, char *newstr) { - char *p; - char *curcol; +char *makecolorstr(char *orig, char *newstr, int lastmovecount) { + char *p, *curcol, *boldstart = NULL; + 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, ""); for (p = orig; *p; p++) { if (!ismod(*p)) { curcol = getpcol(getpchar(*p)); strcat(newstr, curcol); } + if (boldstart && p >= boldstart && *p != ' ') { + strcat(newstr, BOLD); + } strncat(newstr, p, 1); } strcat(newstr, reset); @@ -1590,28 +1639,8 @@ void showaivalues(int best) { // TODO: move this to a function // show board stack - 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); + showboardrow(board, y); ch--; - printf("\n"); - line(); - } printf(FORMAT_ROWHEAD, ' '); 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) { int x,y,i; char ch; @@ -1650,38 +1704,8 @@ void showboard(void) { line(); ch = '1' + h - 1; for (y=h-1; y >= 0; 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); + showboardrow(board, y); ch--; - printf("\n"); - line(); - } printf(FORMAT_ROWHEAD, ' '); ch = 'a'; diff --git a/tak.h b/tak.h index 33ac1fa..a5bf346 100644 --- a/tak.h +++ b/tak.h @@ -5,6 +5,7 @@ int setupround(void); void line(void); void cleanup(void); char getmod(char *stack); +int hasmod(char *stack); char getmodxy(int x, int y); char getowner(char *stack); int ismod(char ch); @@ -34,7 +35,7 @@ int xtoleftshift(int num); void printbinaryline(char prefix, int num, int wantcr); int playerhasroads(int pnum, char (*b)[]); void updateroadstatus(void); -char *makecolorstr(char *orig, char *newstr); +char *makecolorstr(char *orig, char *newstr, int boldidx); void showscores(char *str); int checkxyforroad(char (*b)[], int who, int sx, int sy, int sd); 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); int getownernumxy(int x, int y); void checkfortak(int who); +void showboardrow(char (*b)[MAXBOARDSTRLEN], int y); +void setlastmove(int x,int y,int ntiles);