#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);
}