|
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: 10535 (0x2927) Types: TextFile Names: »move.c«
└─⟦b20c6495f⟧ Bits:30007238 EUUGD18: Wien-båndet, efterår 1987 └─⟦this⟧ »EUUGD18/General/Scrabble/move.c«
/* 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. * */ #ifdef MSDOS typedef char bool; #endif #include "scrabble.h" #ifdef _STDC_ 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); #else static void dopos(); static int wordpoints(); static bool validword(); static bool validlocation(); #endif #ifdef _STDC_ void bestmove(board_t *board, player_t *player, move_t *best) #else void bestmove(board, player, best) board_t *board; player_t *player; move_t *best; #endif { 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 #ifdef sun386 void printmove(int which, move_t *move, FILE *fp) #else void printmove(which, move, fp) int which; move_t *move; FILE *fp; #endif { 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 #ifdef _STDC_ static void dopos(board_t *board, player_t *player, int x, int y, bool horiz, move_t *best) #else static void dopos(board, player, x, y, horiz, best) board_t *board; player_t *player; int x; int y; bool horiz; move_t *best; #endif { 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; } #ifdef _STDC_ static bool validlocation(board_t *board, int x, int y, bool horiz, int len) #else static bool validlocation(board, x, y, horiz, len) board_t *board; int x; int y; bool horiz; int len; #endif { 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. */ #ifdef _STDC_ void trymove(move_t *move, board_t *board, player_t *player, bool check) #else void trymove(move, board, player, check) move_t *move; board_t *board; player_t *player; bool check; #endif { 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; } #ifdef _STDC_ static bool validword(board_t *board, int x, int y, int len, char subc, bool horiz, bool machine, bool check) #else static bool validword(board, x, y, len, subc, horiz, machine, check) board_t *board; int x; int y; int len; char subc; bool horiz; bool machine; bool check; #endif { 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); } } #ifdef _STDC_ 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) #else static int wordpoints(board, x, y, horiz, len, word, subc, wx, wy, allbonuses, wilds) board_t *board; int x,y; bool horiz; int len; char *word, subc; int wx,wy; bool allbonuses, *wilds; #endif { 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); }