-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsemantle_solver.py
117 lines (77 loc) · 3.19 KB
/
semantle_solver.py
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
from Semantle_Website_Game import Semantle_Website_Game
from tqdm import tqdm
import numpy as np
import json
class Semantle_Solver():
def __init__(self, num_landmarks = 5, allowed_guesses = 50, struggle = False, digits = 2):
with open("embed_vec_filtered.npy", "rb") as filtered_npy_reader:
self.word_embedding = np.load(filtered_npy_reader)
with open("filtered_word2index.json", "r") as filtered_json_reader:
self.word_list = np.array(json.load(filtered_json_reader))
self.word2index = dict((w, i) for i, w in enumerate(self.word_list))
self.game = Semantle_Website_Game(struggle, digits)
self.landmark_words = np.random.choice(self.word_list, size = num_landmarks, replace = False)
print(self.landmark_words)
self.landmark_similarities = []
self.guessed_indices = []
self.all_indices = np.array([i for i in range(len(self.word_list))])
self.SIM_ERROR_MATRIX = np.zeros((len(self.word_list), 1))
self.allowed_guesses = allowed_guesses
def guess_landmarks(self):
for w in tqdm(self.landmark_words):
sim_score, _, done = self.game.advance_state(w)
if done:
Exception(f"Landmark {w} is the word?!")
self.landmark_similarities.append(sim_score)
self.calc_similarity_diffs(w, sim_score)
print(self.landmark_similarities)
def calc_similarity_diffs(self, word, sim_score):
word_vector = self.word_embedding[self.word2index[word]]
vec_sims = self.cosine_similarity(word_vector, self.word_embedding)
adjusted_sim_abs = np.abs(vec_sims - sim_score)
self.SIM_ERROR_MATRIX = self.SIM_ERROR_MATRIX + adjusted_sim_abs
def normalize(self, v):
norm=np.linalg.norm(v, axis = -1)
norm += np.float32(norm == 0.)
return norm
def cosine_similarity(self, x, y):
x_norm = self.normalize(x)
y_norm = self.normalize(y)
return (np.sum(x * y, axis = -1) / (x_norm * y_norm))[..., np.newaxis]
def live_play(self):
print("Guessing Landmarks...")
self.guess_landmarks()
print("Beginning Actual Guesses")
total_guesses = 0
while self.allowed_guesses > 0:
# Find current guess
current_guess_index = int(np.argmin(self.SIM_ERROR_MATRIX))
current_guess = self.word_list[current_guess_index]
# Guess
print(f"Guessing {current_guess} with index {current_guess_index}")
sim_score, sim_validity, done_check = self.game.advance_state(current_guess)
if sim_validity:
print(sim_score)
total_guesses += 1
# If done, print results
if done_check:
print(f'Success! Word is {current_guess}!!! Guessed in {total_guesses} attempts after landmark')
break
# Add high value to similarity error of current guess
# to ensure this index is not guessed again
self.SIM_ERROR_MATRIX = self.SIM_ERROR_MATRIX + (np.float32(self.all_indices == current_guess_index) * 1000.)[..., np.newaxis]
if sim_validity:
# If not done and word exists, update similarity error matrix
self.calc_similarity_diffs(current_guess, sim_score)
# decrement allowed guesses
self.allowed_guesses -= 1
if self.allowed_guesses == 0:
print(f"Failed after {total_guesses} allowed attempts")
if __name__ == "__main__":
solver = Semantle_Solver(
num_landmarks = 5,
allowed_guesses = 50,
struggle=True,
digits = 1
)
solver.live_play()