#include <stdio.h> #include "graphics.h" #include "trie.h" #include "globals.h" char tellbuf[80]; void fillsock(void) { register int i; for (i = 0, socksize = 0; i < 28; i++) { socksize += (sock[i] = letterquantity[i]); yourrack[i] = rack[i] = 0; } } void drawtile (int k, char r[28]); void drawtiles (char r[28]) { register int i, j, k, c; for (i = 1, c = 7; i < 28; i++) c -= r[i]; if (c == 7 && socksize == 0) anyrackempty = 1; if (socksize < c) c = socksize; for (i = 0; i < c; i++) { j = rand () % socksize; k = 0; while (j >= 0) j -= sock[++k]; drawtile (k, r); } } void drawtile (int k, char r[28]) { r[k]++; sock[k]--; socksize--; showtilecount (k); } void makemove (struct goodmove *m, bool rr, int bits) { register unsigned r, c; register char *w; char (*xfill)[17]; r = m -> r; c = m -> c; if (m -> fill == afill) xfill = dfill; else xfill = afill; for (w = m -> word, c--; *w; c--) if (!m -> fill[r][c]) { m -> fill[r][c] = xfill[c][r] = ((*w) & 077) | bits; posit (m -> fill, r, c); if (rr) { /* standout (); placeletter (*w); standend (); */ } else placeletter (*w); showtilecount ((*w & BLANKBIT) ? BLANK : chr (*w)); w++; } } void zapmove(void) { register unsigned int c; for (c = 1; c < 16; c++) { /* posit (bestmove.fill, bestmove.r, c); addch (127 & inch ()); */ } } int suggestmove (void) { char *w; int i, j; char saverack[28]; bestmove.value = -1000; for (i = 0; i < 28; ++i) saverack[i] = rack[i]; for (i = 0; i < 28; ++i) rack[i] = yourrack[i]; if (afill[8][8]) { putp (acheck, afill, atrans); putp (dcheck, dfill, dtrans); } else firstmove (); if (bestmove.value > -1000) { for (w = bestmove.word; *w; w++) if (BLANKBIT & (*w)) rack[BLANK]--; else rack[chr (*w)]--; computechecks (dfill, acheck, atrans); computechecks (afill, dcheck, dtrans); makemove (&bestmove, TRUE, NEWBIT); sprintf (tellbuf, "(for %d points)", bestmove.score); tell (tellbuf); for (i = 0; i < 28; ++i) yourrack[i] = rack[i]; for (i = 0; i < 28; ++i) rack[i] = saverack[i]; return(TRUE); } else { tell ("I can't think of any moves for you!"); for (i = 0; i < 28; ++i) yourrack[i] = rack[i]; for (i = 0; i < 28; ++i) rack[i] = saverack[i]; return(FALSE); } } void computermove(void) { char *w; computechecks (dfill, acheck, atrans); computechecks (afill, dcheck, dtrans); bestmove.value = -1000; if (afill[8][8]) { putp (acheck, afill, atrans); putp (dcheck, dfill, dtrans); } else firstmove (); if (bestmove.value > -1000) { for (w = bestmove.word; *w; w++) if (BLANKBIT & (*w)) rack[BLANK]--; else rack[chr (*w)]--; makemove (&bestmove, TRUE, 0); consecutivepasses = 0; drawtiles (rack); myscore += bestmove.score; sprintf (tellbuf, "I get %d points.", bestmove.score); tell (tellbuf); } else { tell ("I can't think of a good move -- your turn."); consecutivepasses++; } computechecks (dfill, acheck, atrans); computechecks (afill, dcheck, dtrans); } int humanmove (char bogus) { int minr = 16, maxr = 0, minc = 16, maxc = 0; int xscore = 0, fscore = 0, factor = 1, t, l; int r, c, count; char new, (*fill)[17], (*xfill)[17]; int (*trans)[17]; for (r = 1; r < 16; r++) for (c = 1; c < 16; c++) if (afill[r][c] & NEWBIT) { if (r < minr) minr = r; if (r > maxr) maxr = r; if (c < minc) minc = c; if (c > maxc) maxc = c; } if (afill[8][8] == 0) { fprintf(stderr, "The first move must cover the center square\n"); return (0); } if (minr != maxr && minc != maxc) { fprintf(stderr, maxr > 0 ? "Your word must be all in the same row or column.\n" : "Use = if you want to pass without playing a word.\n"); return (0); } if (minr == maxr && (maxc > minc || afill[maxr][maxc - 1] || afill[maxr][maxc + 1])) { fill = afill; xfill = dfill; trans = atrans; } else { fill = dfill; xfill = afill; trans = dtrans; minc = minr; minr = maxc; maxc = maxr; maxr = minr; } r = minr; for (c = minc; c <= maxc; c++) if (!fill[r][c]) { fprintf(stderr, "Your word must be contiguous at %c%d.\n", c+'A'-1, r); return (0); } t = (fill[8][8] & NEWBIT) | fill[r][minc - 1] | fill[r][maxc + 1]; for (c = minc; c <= maxc; c++) t |= fill[r - 1][c] | fill[r + 1][c]; if (!t) { fprintf(stderr, "Your word must be adjacent to one already on the board.\n"); return (0); } while (fill[r][c]) c++; if ((!bogus) && !checkmove (fill, r, c - 1)) { /*fprintf(stderr, "bogus or didn't check\n");*/ /*return (0);*/ } bestmove.r = r; bestmove.c = c; bestmove.fill = fill; for (count = 0, c--; new = fill[r][c]; c--) if (NEWBIT & new) { l = lettermult[r][c] * lettervalue[new & 077]; t = trans[r][c]; if (t >= 0) xscore += (t + l) * wordmult[r][c]; fscore += l; factor *= wordmult[r][c]; fill[r][c] = 0; xfill[c][r] = 0; bestmove.word[count++] = new; } else fscore += lettervalue[new]; bestmove.word[count] = 0; bestmove.score = fscore * factor + xscore + 50 * (count == 7); makemove (&bestmove, FALSE, 0); consecutivepasses = 0; zapmove (); yourscore += bestmove.score; fprintf (stderr, "You get %d points.\n", bestmove.score); return (1); } unsigned long checkword (unsigned long t, char *s) { register unsigned long *p; if (!*s) return (t); if (!ptr (t)) return (0); p = dawg + ptr (t); do { if (chr (*p) == chr (*s)) return (checkword (*p, s + 1)); } while (!last (*p++)); return (0); } int checkmove (char (*fill)[17], unsigned int r, unsigned int c) { unsigned long (*check)[17]; if (fill == afill) check = acheck; else check = dcheck; for (; fill[r][c]; c--) if ((fill[r][c] & NEWBIT) && !((1 << chr (fill[r][c])) & check[r][c])) { errortell ("One of your cross words isn't!"); return (0); } if (!term (checkword (root, fill[r] + c + 1))) { errortell ("Your word is bogus."); return (0); } return (1); } int exchange(void) { register unsigned r, c, count = 0; for (r = 1; r < 16; r++) for (c = 1; c < 16; c++) if (afill[r][c] & NEWBIT) count++; if (count == 0) { tell ("Put the tiles you want to trade in anywhere on the board, then press -."); return (0); } if (count > socksize) { errortell ("You're trying to trade in more tiles than there are left!"); return (0); } drawtiles (yourrack); for (r = 1; r < 16; r++) for (c = 1; c < 16; c++) if (afill[r][c] & NEWBIT) { char let = afill[r][c] & BLANKBIT ? BLANK : chr (afill[r][c]); sock[let]++; socksize++; showtilecount (let); position (r, c); removeletter (); afill[r][c] = dfill[c][r] = 0; } return (1); }