semantrix / game_transformer.py
Javierss
Change words format
5b2d6bc
raw
history blame
8.29 kB
# %%
import json
import gzip
import random
from datetime import datetime
import numpy as np
from gensim.models import KeyedVectors
from hints import curiosity, hint
from tracking import (
calculate_moving_average,
calculate_tendency_slope,
)
from sentence_transformers import SentenceTransformer
import warnings
warnings.filterwarnings(action="ignore", category=UserWarning, module="gensim")
class Semantrix:
model = KeyedVectors(768)
model_st = SentenceTransformer(
"sentence-transformers/paraphrase-multilingual-mpnet-base-v2"
)
config_file_path = "config/lang.json"
secret_file_path = "config/secret.json"
possible_words_file_path = "config/possible_words.json"
data_path = "data/"
class DictWrapper:
def __init__(self, data_dict):
self.__dict__.update(data_dict)
def __init__(self, lang=0):
self.embeddings_dict = {}
with open(self.config_file_path, "r") as file:
self.Config_full = json.load(file)
with open(self.secret_file_path, "r") as file:
self.secret = json.load(file)
self.lang = lang
if self.lang == 1:
self.Config = self.DictWrapper(self.Config_full["ENG"]["Game"])
self.secret_dict = self.secret["ENG"]
else:
self.Config = self.DictWrapper(self.Config_full["SPA"]["Game"])
self.secret_dict = self.secret["SPA"]
with open(self.data_path + "ranking.txt", "w+") as file:
file.write("---------------------------")
with open(self.possible_words_file_path, "r", encoding="utf-8") as json_file:
self.possible_words = json.load(json_file)
def prepare_game(self, difficulty):
self.secret_list = (
self.secret_dict["basic"]
if difficulty <= 2
else self.secret_dict["advanced"]
)
self.secret = self.secret_list.pop(random.randint(0, len(self.secret_list) - 1))
self.secret = self.secret.lower()
self.words = [self.Config.secret_word]
self.scores = [10]
if self.secret not in self.embeddings_dict.keys():
self.embeddings_dict[self.secret] = self.model_st.encode(
self.secret, convert_to_tensor=True
)
self.model.add_vector(
self.secret, self.embeddings_dict[self.secret].tolist()
)
self.word_vect = [self.embeddings_dict[self.secret].tolist()]
self.win = False
self.n = 0
self.recent_hint = 0
self.f_dev_avg = 0
self.last_hint = -1
self.difficulty = difficulty
if self.difficulty == 1:
self.n = 3
def preproc_vectors(self, repeated):
ascending_indices = np.argsort(self.scores)
descending_indices = list(ascending_indices[::-1])
ranking_data = []
k = len(self.words) - 1
if repeated != -1:
k = repeated
ranking_data.append(["#" + str(k), self.words[k], self.scores[k]])
ranking_data.append("---------------------------")
for i in descending_indices:
if i == 0:
continue
ranking_data.append(["#" + str(i), self.words[i], self.scores[i]])
with open(self.data_path + "ranking.txt", "w+") as file:
for item in ranking_data:
file.write("%s\n" % item)
def play_game(self, word):
word = word.lower()
if word == "give_up":
text = (
"[lose]"
+ self.Config.Feedback_9
+ self.secret
+ "\n\n"
+ self.Config.Feedback_10
)
return text
if word in self.words:
repeated = self.words.index(word)
else:
repeated = -1
self.words.append(word)
if word not in self.embeddings_dict.keys():
if word not in self.possible_words:
self.words.pop(len(self.words) - 1)
feedback = (
"I don't know that word. Try again."
if self.lang == 1
else "No conozco esa palabra. Inténtalo de nuevo."
)
feedback += (
"[rank]" + open(self.data_path + "ranking.txt", "r").read()
if len(self.words) > 1
else "\n\n"
)
return feedback
else:
embedding = self.model_st.encode(word, convert_to_tensor=True)
self.embeddings_dict[word] = embedding
self.model.add_vector(word, embedding.tolist())
score = round(
np.interp(
np.log(self.model.similarity(self.secret, word) * 10),
[0, np.log(10)],
[0, 10],
),
2,
)
if repeated == -1:
self.word_vect.append(self.embeddings_dict[word].tolist())
self.scores.append(score)
if score <= 2.5:
feedback = self.Config.Feedback_0 + str(score)
elif score > 2.5 and score <= 4.0:
feedback = self.Config.Feedback_1 + str(score)
elif score > 4.0 and score <= 6.0:
feedback = self.Config.Feedback_2 + str(score)
elif score > 6.0 and score <= 7.5:
feedback = self.Config.Feedback_3 + str(score)
elif score > 7.5 and score <= 8.0:
feedback = self.Config.Feedback_4 + str(score)
elif score > 8.0 and score < 10.0:
feedback = self.Config.Feedback_5 + str(score)
else:
self.win = True
feedback = "[win]" + self.Config.Feedback_8
self.words[0] = self.secret
self.words.pop(len(self.words) - 1)
self.word_vect.pop(len(self.word_vect) - 1)
self.scores.pop(len(self.scores) - 1)
if score > self.scores[len(self.scores) - 2] and self.win == False:
feedback += "\n" + self.Config.Feedback_6
elif score < self.scores[len(self.scores) - 2] and self.win == False:
feedback += "\n" + self.Config.Feedback_7
if self.difficulty != 4:
mov_avg = calculate_moving_average(self.scores[1:], 5)
if len(mov_avg) > 1 and self.win == False:
f_dev = calculate_tendency_slope(mov_avg)
f_dev_avg = calculate_moving_average(f_dev, 3)
if f_dev_avg[len(f_dev_avg) - 1] < 0 and self.recent_hint == 0:
i = random.randint(0, len(self.Config.hint_intro) - 1)
feedback += "\n\n[hint]" + self.Config.hint_intro[i]
hint_text, self.n, self.last_hint = hint(
self.secret,
self.n,
self.model_st,
self.last_hint,
self.lang,
(
self.DictWrapper(self.Config_full["ENG"]["Hint"])
if self.lang == 1
else self.DictWrapper(self.Config_full["SPA"]["Hint"])
),
)
feedback += "\n" + hint_text
self.recent_hint = 3
if self.recent_hint != 0:
self.recent_hint -= 1
self.preproc_vectors(repeated)
feedback += "[rank]" + open(self.data_path + "ranking.txt", "r").read()
if self.win:
bold_display = 0
if self.win:
with open(self.data_path + "ranking.txt", "r") as original_file:
file_content = original_file.readlines()
new_file_name = self.secret + "_" + str(datetime.now()) + ".txt"
with open(self.data_path + "plays/" + new_file_name, "w+") as new_file:
new_file.writelines(file_content[2:])
return feedback
def curiosity(self):
feedback = curiosity(
self.secret,
(
self.DictWrapper(self.Config_full["ENG"]["Hint"])
if self.lang == 1
else self.DictWrapper(self.Config_full["SPA"]["Hint"])
),
)
return feedback