-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.py
More file actions
169 lines (135 loc) · 4.65 KB
/
Copy pathapp.py
File metadata and controls
169 lines (135 loc) · 4.65 KB
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
import os
import json
import numpy as np
from flask import Flask, request, jsonify, send_from_directory
import random
from ai_solver import AISolver
app = Flask(__name__, static_folder='.')
# --- Models ---
vocab = []
embeddings = None
word_to_index = {}
target_word = ""
target_vector = None
target_similarities = None
sorted_indices = None
# AI Instance
ai_solver = None
def load_game_model():
global vocab, embeddings, word_to_index
print("Loading game model...")
with open("vocab.json", "r") as f:
vocab = json.load(f)
word_to_index = {word: i for i, word in enumerate(vocab)}
raw = np.fromfile("embeddings.bin", dtype=np.float32)
dim = raw.shape[0] // len(vocab)
embeddings = raw.reshape(len(vocab), dim)
norms = np.linalg.norm(embeddings, axis=1, keepdims=True)
norms[norms == 0] = 1.0
embeddings = embeddings / norms
print("Game model loaded.")
def init_ai():
global ai_solver
if not ai_solver:
ai_solver = AISolver()
def start_new_game():
global target_word, target_vector, target_similarities, sorted_indices
idx = random.randint(0, len(vocab) - 1)
target_word = vocab[idx]
target_vector = embeddings[idx]
print(f"New game started! Target: {target_word}")
# Pre-calc distances for the user
target_similarities = np.dot(embeddings, target_vector)
sorted_indices = np.argsort(target_similarities)[::-1]
# Reset AI for this new game
if ai_solver:
ai_solver.reset_session()
@app.route('/')
def index():
return send_from_directory('.', 'index.html')
@app.route('/<path:path>')
def serve_static(path):
return send_from_directory('.', path)
@app.route('/api/new_game', methods=['POST'])
def new_game():
start_new_game()
bg_points = []
if ai_solver:
# Sample 1000 random points for cosmic background
try:
total = len(ai_solver.vocab)
indices = np.random.choice(total, 1000, replace=False)
bg_points = ai_solver.projected_embeddings[indices].tolist()
except Exception as e:
print(f"Error generating background: {e}")
return jsonify({
"message": "New game started",
"debug_word": target_word,
"background": bg_points
})
@app.route('/api/guess', methods=['POST'])
def guess():
global ai_solver
if not target_word:
start_new_game()
data = request.json
guess_word = data.get('word', '').lower().strip()
if guess_word not in word_to_index:
return jsonify({"error": "Word not found in vocabulary"}), 404
idx = word_to_index[guess_word]
# Determine rank
rank_idx = np.where(sorted_indices == idx)[0][0]
rank = int(rank_idx) + 1
# Update AI state if it exists, so it learns from user moves too
if ai_solver:
if guess_word in ai_solver.word_to_idx:
ai_idx = ai_solver.word_to_idx[guess_word]
ai_solver.process_result(ai_idx, rank)
# Get 3D coords for graph
coords = None
target_coords = None
if ai_solver:
if guess_word in ai_solver.word_to_idx:
ai_idx = ai_solver.word_to_idx[guess_word]
coords = ai_solver.projected_embeddings[ai_idx].tolist()
if rank == 1 and target_word in ai_solver.word_to_idx:
t_idx = ai_solver.word_to_idx[target_word]
target_coords = ai_solver.projected_embeddings[t_idx].tolist()
return jsonify({
"word": guess_word,
"rank": rank,
"distance": rank,
"coords": coords,
"target_coords": target_coords
})
@app.route('/api/ai/guess', methods=['POST'])
def ai_guess():
global ai_solver
if not ai_solver:
return jsonify({"error": "AI not initialized"}), 500
# AI decides what to guess
idx, reasoning = ai_solver.get_next_guess()
word = ai_solver.vocab[idx]
# Get rank (assuming game is running)
if word not in word_to_index:
return jsonify({"error": "AI word mismatch"}), 500
game_idx = word_to_index[word]
rank_idx = np.where(sorted_indices == game_idx)[0][0]
rank = int(rank_idx) + 1
# Update AI internal state with the result
ai_solver.process_result(idx, rank)
# Get 3D coords
coords = ai_solver.projected_embeddings[idx].tolist()
# Also need to add to frontend history
return jsonify({
"word": word,
"reasoning": reasoning,
"rank": rank,
"distance": rank,
"coords": coords
})
if __name__ == '__main__':
load_game_model()
init_ai()
start_new_game()
app.run(host='0.0.0.0', port=8080, debug=True)