DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T m

⟦abfba67db⟧ TextFile

    Length: 9358 (0x248e)
    Types: TextFile
    Names: »move.c.orig«

Derivation

└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987
    └─⟦this⟧ »EUUGD18/General/Scrabble/move.c.orig« 

TextFile


/* 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);
}