|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T m
Length: 9358 (0x248e)
Types: TextFile
Names: »move.c.orig«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
└─⟦this⟧ »EUUGD18/General/Scrabble/move.c.orig«
/* RCS Info: $Revision: 1.2 $ on $Date: 89/03/15 11:16:30 $
* $Source: /yew3/faustus/src/scrabble/RCS/move.c,v $
* Copyright (c) 1989 Wayne A. Christopher, U. C. Berkeley CS Dept
* faustus@renoir.berkeley.edu, ucbvax!faustus
* Permission is granted to modify and re-distribute this code in any manner
* as long as this notice is preserved. All standard disclaimers apply.
*
*/
#include "scrabble.h"
static void dopos(board_t *board, player_t *player, int x, int y,
bool horiz, move_t *best);
static int wordpoints(board_t *board, int x, int y, bool horiz, int len,
char *word, char subc, int wx, int wy, bool allbonuses,
bool *wilds);
static bool validword(board_t *board, int x, int y, int len, char subc,
bool horiz, bool machine, bool check);
static bool validlocation(board_t *board, int x, int y, bool horiz, int len);
void
bestmove(board_t *board, player_t *player, move_t *best)
{
int x, y;
move_t try;
best->points = -1;
for (x = 0; x < SIZE; x++)
for (y = 0; y < SIZE; y++) {
dopos(board, player, x, y, true, &try);
if (try.points > best->points)
*best = try;
dopos(board, player, x, y, false, &try);
if (try.points > best->points)
*best = try;
}
return;
}
#ifdef notdef
void
printmove(int which, move_t *move, FILE *fp)
{
fprintf(fp, "Player %d: \"%s\", %s at (%d, %d) for %d points.\n",
which, move->word, move->horiz ? "horiz" : "vert",
move->x, move->y, move->points);
return;
}
#endif
static void
dopos(board_t *board, player_t *player, int x, int y, bool horiz, move_t *best)
{
char opt[SIZE];
char req[SIZE];
int numopt, numreq;
word_t *words, *set, *word;
int i, j, len;
char c;
move_t try;
best->points = -1;
try.x = x;
try.y = y;
try.horiz = horiz;
for (len = 1; horiz ? (x + len <= SIZE) : (y + len <= SIZE); len++) {
try.length = len;
/* First make sure this is a place we can put a word. */
if (!validlocation(board, x, y, horiz, len))
continue;
#ifdef notdef
if (debug)
fprintf(stderr, "\t(%d, %d), %s, len %d ---\n",
x, y, horiz ? "horiz" : "vert", len);
#endif
/* Make the letter set. */
for (i = 0, numopt = 0; i < player->numworking; i++)
opt[i] = player->working[i];
numopt = player->numworking;
for (j = 0, numreq = 0; j < len; j++) {
c = boardletter(board, x, y, horiz, j);
if (something(c))
req[numreq++] = c;
}
if (((horiz ? x : y) + len < SIZE) && something(boardletter
(board, x, y, horiz, len)))
continue;
if (((horiz ? x : y) > 0) && something(boardletter
(board, x, y, horiz, - 1)))
continue;
if (numreq + numopt < len)
break;
#ifdef notdef
if (debug) {
fprintf(stderr, "\tReq:");
for (i = 0; i < numreq; i++)
fprintf(stderr, " %c", req[i]);
fprintf(stderr, "\n\tOpt:");
for (i = 0; i < numopt; i++)
fprintf(stderr, " %c", opt[i]);
fprintf(stderr, "\n");
}
#endif
words = getpossibles(opt, numopt, req, numreq, len);
for (set = words; set; set = set->next_set)
for (word = set; word; word = word->next) {
try.word = word->word;
for (i = 0; i < SIZE; i++)
try.wild[i] = false;
trymove(&try, board, player, false);
if (try.points > best->points)
*best = try;
}
}
return;
}
static bool
validlocation(board_t *board, int x, int y, bool horiz, int len)
{
int i;
if (board->virgin) {
if (((y == SIZE / 2) && (x <= SIZE / 2) &&
(x + len - 1 >= SIZE / 2)) ||
((x == SIZE / 2) && (y <= SIZE / 2) &&
(y + len - 1 >= SIZE / 2)))
return (true);
else
return (false);
}
for (i = 0; i < len; i++)
if (horiz) {
if (something(boardletter(board, x, y, horiz, i)) ||
((y > 0) && something(boardletter
(board, x, y - 1, horiz, i))) ||
((y < SIZE - 1) && something(boardletter
(board, x, y + 1, horiz, i))))
return (true);
} else {
if (something(boardletter(board, x, y, horiz, i)) ||
((x > 0) && something(boardletter
(board, x - 1, y, horiz, i))) ||
((x < SIZE - 1) && something(boardletter
(board, x + 1, y, horiz, i))))
return (true);
}
return (false);
}
/* This routine returns the value of a move, or -1 if the move would
* be invalid.
*/
void
trymove(move_t *move, board_t *board, player_t *player, bool check)
{
bool used[WORK_SIZE];
int numused = 0;
int i, j, x, y;
int len;
char c;
char buf[BSIZE];
/*printf("try %s at %d, %d, %d\n", move->word, move->x, move->y, move->horiz);*/
if (check) {
sprintf(buf, "Is \"%s\" a word?", move->word);
if (!user_confirm(buf)) {
remword(move->word);
move->points = -1;
return;
}
}
for (i = 0; i < WORK_SIZE; i++) {
used[i] = false;
if (iswild(player->working[i]))
player->working[i] = WILD;
}
/* First do the validity checks. */
for (i = 0; i < move->length; i++) {
c = boardletter(board, move->x, move->y, move->horiz, i);
if (iswild(c))
c = maketame(c);
if (something(c)) {
if (move->word[i] != c) {
move->points = -1;
return;
}
} else {
for (j = 0; j < player->numworking; j++)
if ((move->word[i] == player->working[j]) &&
!used[j]) {
used[j] = true;
numused++;
break;
}
if (j == player->numworking) {
for (j = 0; j < player->numworking; j++)
if ((player->working[j] == WILD) &&
!used[j]) {
move->wild[i] = true;
used[j] = true;
numused++;
break;
}
if (j == player->numworking) {
move->points = -1;
return;
}
}
}
}
#ifdef notdef
if (debug)
fprintf(stderr, "\t(%d, %d) %s: %s", move->x, move->y,
move->horiz ? "horiz" : "vert", move->word);
#endif
if (!numused) {
move->points = -1;
return;
}
/* Add up the value of this word. */
move->points = wordpoints(board, move->x, move->y, move->horiz,
move->length, move->word, '\0', 0, 0, true,
move->wild);
if (numused == WORK_SIZE)
move->points += ALL_BONUS;
if (move->horiz)
for (i = 0; i < move->length; i++) {
x = move->x + i;
if (something(board->letters[x][move->y]))
continue;
for (y = move->y; (y > 0) && something(board->
letters[x][y - 1]); y--)
;
for (len = 1, j = y; (j < SIZE - 1) &&
(something(board->letters[x][j + 1]) ||
(j + 1 == move->y)); len++, j++)
;
if (len == 1)
continue;
if (validword(board, x, y, len, move->word[i], false,
player->machine, check))
move->points += wordpoints(board, x, y, false,
len, (char *) NULL,
move->word[i], x, y,
false, (bool *) NULL);
else {
move->points = -1;
#ifdef notdef
if (debug)
fprintf(stderr, "=-1\n");
#endif
return;
}
}
else
for (i = 0; i < move->length; i++) {
y = move->y + i;
if (something(board->letters[move->x][y]))
continue;
for (x = move->x; (x > 0) && something(board->
letters[x - 1][y]); x--)
;
for (len = 1, j = x; (j < SIZE - 1) &&
(something(board->letters[j + 1][y]) ||
(j + 1 == move->x)); len++, j++)
;
if (len == 1)
continue;
if (validword(board, x, y, len, move->word[i], true,
player->machine, check))
move->points += wordpoints(board, x, y, true,
len, (char *) NULL,
move->word[i], x, y,
false, (bool *) NULL);
else {
move->points = -1;
#ifdef notdef
if (debug)
fprintf(stderr, "=-1\n");
#endif
return;
}
}
#ifdef notdef
if (debug)
fprintf(stderr, "\n");
#endif
return;
}
static bool
validword(board_t *board, int x, int y, int len, char subc, bool horiz,
bool machine, bool check)
{
char buf[BSIZE], qbuf[BSIZE], c;
int i;
for (i = 0; i < len; i++) {
c = boardletter(board, x, y, horiz, i);
if (something(c))
buf[i] = c;
else
buf[i] = subc;
if (iswild(buf[i]))
buf[i] = maketame(buf[i]);
}
buf[i] = '\0';
#ifdef notdef
if (debug)
fprintf(stderr, " %s", buf);
#endif
if (check) {
sprintf(qbuf, "Is \"%s\" a word?", buf);
if (user_confirm(qbuf)) {
return (true);
} else {
remword(buf);
return (false);
}
} else if (isaword(buf)) {
return (true);
} else if (!machine) {
sprintf(qbuf, "I don't think \"%s\" is a word. Do you?", buf);
if (user_confirm(qbuf)) {
addword(buf);
return (true);
} else
return (false);
} else {
return (false);
}
}
static int
wordpoints(board_t *board, int x, int y, bool horiz, int len, char *word,
char subc, int wx, int wy, bool allbonuses, bool *wilds)
{
int value = 0;
int mult = 1;
int i;
bonus_t b;
char c;
if ((horiz ? x : y) + len > SIZE)
return (-1);
for (i = 0; i < len; i++) {
if (allbonuses || (horiz && (x + i == wx)) ||
(!horiz && (y + i == wy)))
b = boardbonus(board, x, y, horiz, i);
else
b = NONE;
c = boardletter(board, x, y, horiz, i);
if (!something(c)) {
if (word)
c = word[i];
else
c = subc;
assert(c);
} else
b = NONE;
if (wilds && wilds[i])
c = makewild(c);
switch (b) {
case NONE:
value += letterpoints(c);
break;
case DOUBLE_LETTER:
value += letterpoints(c) * 2;
break;
case TRIPLE_LETTER:
value += letterpoints(c) * 3;
break;
case DOUBLE_WORD:
value += letterpoints(c);
mult *= 2;
break;
case TRIPLE_WORD:
value += letterpoints(c);
mult *= 3;
break;
}
}
value *= mult;
#ifdef notdef
if (debug)
fprintf(stderr, "=%d", value);
#endif
return (value);
}