void check_n_letter(int n, const char *letters) { if (!running) return; if (!dict_letters(n,letters)) return; int i = 0, j; int jump = (len - 1 - n ? len - 1 - n : 1); for (i = jump - 1; i > 0; i--) jump *= i; if (n > 3) jump *= difficulty[7-n]; char *p,str[MAX_CHAR]; if ( stage & STAGE_FIRST ) { for (p = strings; *p != '\0'; p += len*jump) { strcpy(str,p); str[n] = '\0'; ai_play.y = 7; if (dict_match(str)) { if ( (i=score(str,7-strlen(str)/2,7,0)) > ai_play.score ) { ai_play.x = 7 - strlen(str)/2; ai_play.score = i; strcpy(ai_play.word,str); } } } } else for (p = strings; *p != '\0'; p += len*jump) { strcpy(str,p); str[n] = '\0'; for (i = 0; i < 16 - n; i++) for (j = 0; j < 15; j++) check_string(i,j,str,0); for (i = 0; i < 15; i++) for (j = 0; j < 16 - n; j++) check_string(i,j,str,1); } }
void check_string(int x, int y, const char *str, const int down) { if (board[x][y].tile) return; Tile *t; int i, c, opt_score; char connect = 0; /* find real start of word */ if (down) while (y && board[x][y-1].tile) y--; else while (x && board[x-1][y].tile) x--; /* build "word" */ for (i = 0, c = 0; i < 15 - (down ? y : x) && c < strlen(str); i++) { if ( (t = board[(down?x:x+i)][(down?y+i:y)].tile) ){ connect = word[i] = t->letter; } else word[i] = str[c++]; } while ( (i < 15 - (down?y:x)) && (t=board[(down?x:x+i)][(down?y+i:y)].tile) ) connect = word[i++] = t->letter; word[i] = '\0'; /* check for real word, then get score */ if ( i && connect && c == strlen(str) && dict_match(word) ) { // TODO check "cross" words opt_score = score(word,x,y,down); if (opt_score > ai_play.score) { ai_play.score = opt_score; ai_play.x = x; ai_play.y = y; ai_play.down = down; strcpy(ai_play.word,word); } } }
/** * prune_lookup_list -- discard all list entries that don't match string * Walk the lookup list (of right links), discarding all nodes that do * not match the dictionary string s. The matching is dictionary matching: * suffixed entries will match "bare" entries. */ static Dict_node * prune_lookup_list(Dict_node *llist, const char * s) { Dict_node *dn, *dnx, *list_new; list_new = NULL; for (dn = llist; dn != NULL; dn = dnx) { dnx = dn->right; /* now put dn onto the answer list, or free it */ if (dict_match(dn->string, s)) { dn->right = list_new; list_new = dn; } else { free_dict_node(dn); } } /* now reverse the list back */ llist = NULL; for (dn = list_new; dn != NULL; dn = dnx) { dnx = dn->right; dn->right = llist; llist = dn; } return llist; }
void play_notify() { if ( stage & STAGE_PLAYER ) fprintf(logger,"%d: Player ",time(NULL)); else if ( stage & STAGE_AI ) fprintf(logger,"%d: AI ",time(NULL)); else return; if (dict_match(ai_play.word)) { fprintf(logger,"plays \"%s\" at (%d,%d) for %d points\n", ai_play.word, ai_play.x,ai_play.y,ai_play.score); if ( stage & STAGE_PLAYER ) score_player += ai_play.score; else score_comp += ai_play.score; } else { fprintf(logger,"cheats! \"%s\" at (%d,%d) for %d points\n", ai_play.word, ai_play.x,ai_play.y,ai_play.score); } }
int score(const char *word, int x, int y, int down) { int i, pts = 0, word_multi = 1, multi_score = 0, n = 0; for (i = 0; i < strlen(word); i++) { if (board[x][y].tile && board[x][y].tile->flags == TILE_BOARD_PERM) { pts += letter_pts[word[i]-97]; } else { pts += letter_pts[word[i]-97] * board[x][y].tile_bonus; word_multi *= board[x][y].word_bonus; n++; if (down) { if ( (x > 0 && board[x-1][y].tile) || (x < 14 && board[x+1][y].tile) ) { int xx, mw=1, sub=0, crossn = 0; char cross[15]; for (xx = x; xx && board[xx-1][y].tile ; xx--); for (xx = xx; xx < 15 && (board[xx][y].tile || xx==x); xx++) { if (board[xx][y].tile && board[xx][y].tile->flags == TILE_BOARD_PERM) { sub += letter_pts[board[xx][y].tile->letter - 97]; cross[crossn++] = board[xx][y].tile->letter; } else { sub += letter_pts[word[i] - 97] * board[xx][y].tile_bonus; mw = board[xx][y].word_bonus; cross[crossn++] = word[i]; } } cross[crossn] = '\0'; if (dict_match(cross)) { multi_score += sub*mw; } else { return 0; } } } else { if ( (y > 0 && board[x][y-1].tile) || (y < 14 && board[x][y+1].tile) ) { int yy, mw=1, sub=0, crossn = 0; char cross[15]; for (yy = y; yy && board[x][yy-1].tile; yy--); for (yy = yy; yy < 15 && (board[x][yy].tile || yy==y); yy++) { if (board[x][yy].tile && board[x][yy].tile->flags == TILE_BOARD_PERM) { sub += letter_pts[board[x][yy].tile->letter - 97]; cross[crossn++] = board[x][yy].tile->letter; } else { sub += letter_pts[word[i] - 97] * board[x][yy].tile_bonus; mw = board[x][yy].word_bonus; cross[crossn++] = word[i]; } } cross[crossn] = '\0'; if (dict_match(cross)) multi_score += sub*mw; else return 0; } } } if (down) y++; else x++; } pts *= word_multi; pts += multi_score; if (n == 7) pts += 50; return pts; }