-
Notifications
You must be signed in to change notification settings - Fork 0
/
Search.c
148 lines (132 loc) · 4.08 KB
/
Search.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/*
* FJ Tria (@fjstria)
* WordleSolver/Search.c
*/
#include "Search.h"
int score_letter(char letter, char **vocabulary, size_t num_words) {
int score = 0;
for(size_t i = 0; i < num_words; i++) {
if (vocabulary[i] == NULL) { // this word is invalid, do not count
continue;
}
for(size_t j = 0; j < 5; j++) {
if (vocabulary[i][j] == letter) { // check if this is the letter we want
score++;
break; // only find first instance of the letter in this word, avoid others
}
}
}
return score;
}
int score_word(char *word, int *letter_scores) {
int score = 0;
char letters_used[] = "_____"; // array will be edited as loop happens
for (int i = 0; i < 5; i++) {
bool found = false; // a flag for checking if a letter has already been accounted for
for (int j = 0; j < 5; j++) {
if (word[i] == letters_used[j]) { // find the letter in letters_used
found = true; // letter found
}
}
if (found) {
continue; // skip the letter if found
}
else {
score += letter_scores[word[i]-'a']; // add the letter's score to score
} // word[i] - 'a' maps each letter to an int 0-25
letters_used[i] = word[i]; // add the letter to letters_used
}
return score;
}
char *get_guess(char **vocabulary, size_t num_words) {
int letter_scores[26];
for (int i = 0; i < 26; i++) {
letter_scores[i] = score_letter('a' + i, vocabulary, num_words);
}
char *best_guess = NULL;
int best_score = 0;
int score = 0;
for (size_t i = 0; i < num_words; i++) {
if (vocabulary[i] == NULL) {
continue;
}
score = score_word(vocabulary[i], letter_scores);
if (score > best_score) {
best_guess = vocabulary[i];
best_score = score;
}
}
return best_guess ? strdup(best_guess) : NULL;
}
size_t filter_vocabulary_gray(char letter, char **vocabulary, size_t num_words) {
size_t count = 0;
for (size_t i = 0; i < num_words; i++) {
if (vocabulary[i] == NULL) {
continue; // this word has already been removed, skip it
}
for (int j = 0; j < 5; j++) {
if (vocabulary[i][j] == letter) { // letter that's not in secret word found, remove word
char *temp = vocabulary[i];
free(temp);
vocabulary[i] = NULL;
count++; // count this word as removed
break; // word doesn't exist anymore, don't search further
}
}
}
return count;
}
size_t filter_vocabulary_yellow(char letter, int position, char **vocabulary, size_t num_words) {
size_t count = 0;
for (size_t i = 0; i < num_words; i++) {
if (vocabulary[i] == NULL) {
continue; // this word has already been removed, skip it
}
if (vocabulary[i][position] == letter) { // letter should not be in this position, remove word
char *temp = vocabulary[i];
free(temp);
vocabulary[i] = NULL;
count++;
}
else {
bool found = false; // flag for checking if the letter is in the word
for (int j = 0; j < 5; j++) {
if (vocabulary[i][j] == letter) {
found = true; // letter is found
break; // no need to check the word further
}
}
if (!found) { // if the letter is not found, remove the word
char *temp = vocabulary[i];
free(temp);
vocabulary[i] = NULL;
count++;
}
}
}
return count;
}
size_t filter_vocabulary_green(char letter, int position, char **vocabulary, size_t num_words) {
size_t count = 0;
for (size_t i = 0; i < num_words; i++) {
if (vocabulary[i] == NULL) {
continue; // this word has already been removed, skip it
}
if (vocabulary[i][position] == letter) { // this char is in the right spot, skip this word
continue;
}
else { // missing correct letter, remove this word
char *temp = vocabulary[i];
free(temp);
vocabulary[i] = NULL;
count++;
}
}
return count;
}
void free_vocabulary(char **vocabulary, size_t num_words) {
for (size_t i = 0; i < num_words; i++) {
free(vocabulary[i]);
}
free(vocabulary);
}