aaa
Browse files- index.html +232 -222
index.html
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
<head>
|
4 |
<meta charset="UTF-8">
|
5 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6 |
-
<title>Shy Guy Simulator</title>
|
7 |
<style>
|
8 |
body {
|
9 |
font-family: Arial, sans-serif;
|
@@ -21,30 +21,63 @@
|
|
21 |
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
|
22 |
}
|
23 |
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
}
|
29 |
|
30 |
-
#
|
31 |
display: flex;
|
32 |
-
flex-direction: column;
|
33 |
gap: 10px;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
}
|
35 |
|
36 |
button {
|
37 |
padding: 10px 20px;
|
38 |
-
background-color: #
|
39 |
color: white;
|
40 |
border: none;
|
41 |
border-radius: 4px;
|
42 |
cursor: pointer;
|
43 |
-
transition: background-color 0.3s;
|
44 |
}
|
45 |
|
46 |
button:hover {
|
47 |
-
background-color: #
|
48 |
}
|
49 |
|
50 |
#stats {
|
@@ -52,257 +85,234 @@
|
|
52 |
padding: 10px;
|
53 |
background-color: #333;
|
54 |
border-radius: 4px;
|
|
|
|
|
55 |
}
|
56 |
|
57 |
-
.
|
58 |
font-style: italic;
|
59 |
-
color: #
|
60 |
-
|
|
|
|
|
|
|
61 |
}
|
62 |
</style>
|
63 |
</head>
|
64 |
<body>
|
65 |
<div id="game-container">
|
66 |
-
<h1>Shy Guy Simulator</h1>
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
71 |
</div>
|
72 |
-
<div id="story-text"></div>
|
73 |
-
<div id="choices"></div>
|
74 |
</div>
|
75 |
|
76 |
<script>
|
77 |
-
|
78 |
-
|
79 |
-
|
|
|
|
|
|
|
80 |
confidence: 0,
|
81 |
-
|
82 |
-
time: new Date(2024, 0, 1, 20, 0)
|
|
|
|
|
|
|
83 |
};
|
84 |
-
|
85 |
-
this.
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
|
|
|
|
92 |
];
|
93 |
|
94 |
this.initialize();
|
95 |
}
|
96 |
|
97 |
initialize() {
|
|
|
|
|
98 |
this.updateStats();
|
99 |
-
this.loadScene(this.currentScene);
|
100 |
-
setInterval(() => this.showRandomThought(), 15000);
|
101 |
}
|
102 |
|
103 |
-
|
104 |
-
if (this.
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
109 |
|
110 |
-
|
111 |
-
|
112 |
|
113 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
114 |
}
|
115 |
}
|
116 |
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
122 |
}
|
123 |
|
124 |
-
|
125 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
126 |
this.updateStats();
|
127 |
}
|
128 |
|
129 |
-
|
130 |
-
|
131 |
-
|
|
|
|
|
|
|
132 |
|
133 |
-
|
134 |
-
|
135 |
-
const
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
const button = document.createElement('button');
|
141 |
-
button.textContent = choice.text;
|
142 |
-
button.onclick = () => {
|
143 |
-
if (choice.effect) {
|
144 |
-
choice.effect(this.stats);
|
145 |
-
this.updateStats();
|
146 |
-
}
|
147 |
-
this.loadScene(choice.next);
|
148 |
-
};
|
149 |
-
choicesContainer.appendChild(button);
|
150 |
-
}
|
151 |
-
});
|
152 |
}
|
153 |
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
text: "Try to move closer to the dance floor",
|
169 |
-
effect: stats => {
|
170 |
-
stats.confidence += 5;
|
171 |
-
this.advanceTime(10);
|
172 |
-
},
|
173 |
-
next: 'dance_floor'
|
174 |
-
},
|
175 |
-
{
|
176 |
-
text: "Stay by the snacks and observe",
|
177 |
-
effect: stats => {
|
178 |
-
this.advanceTime(20);
|
179 |
-
},
|
180 |
-
next: 'observe'
|
181 |
-
}
|
182 |
-
]
|
183 |
-
},
|
184 |
-
after_drink: {
|
185 |
-
text: "The drink starts to take effect, making you feel a bit warmer and more relaxed. The music seems more inviting now.",
|
186 |
-
choices: [
|
187 |
-
{
|
188 |
-
text: "Get another drink",
|
189 |
-
effect: stats => {
|
190 |
-
stats.drinks++;
|
191 |
-
stats.confidence += 15;
|
192 |
-
this.advanceTime(15);
|
193 |
-
},
|
194 |
-
next: 'more_drinks'
|
195 |
-
},
|
196 |
-
{
|
197 |
-
text: "Start swaying to the music",
|
198 |
-
effect: stats => {
|
199 |
-
stats.confidence += 10;
|
200 |
-
this.advanceTime(10);
|
201 |
-
},
|
202 |
-
next: 'dancing'
|
203 |
-
}
|
204 |
-
]
|
205 |
-
},
|
206 |
-
more_drinks: {
|
207 |
-
text: "You're definitely feeling the drinks now. Your anxiety is lower, but you're also a bit wobbly.",
|
208 |
-
choices: [
|
209 |
-
{
|
210 |
-
text: "Try to approach her",
|
211 |
-
condition: stats => stats.confidence >= 40,
|
212 |
-
effect: stats => this.advanceTime(5),
|
213 |
-
next: 'approach'
|
214 |
-
},
|
215 |
-
{
|
216 |
-
text: "Take a break outside",
|
217 |
-
effect: stats => {
|
218 |
-
stats.confidence -= 10;
|
219 |
-
this.advanceTime(20);
|
220 |
-
},
|
221 |
-
next: 'outside'
|
222 |
-
}
|
223 |
-
]
|
224 |
-
},
|
225 |
-
dance_floor: {
|
226 |
-
text: "You're closer to where she's standing now. The music is louder, and people are dancing around you.",
|
227 |
-
choices: [
|
228 |
-
{
|
229 |
-
text: "Start dancing near her group",
|
230 |
-
effect: stats => {
|
231 |
-
stats.confidence += 15;
|
232 |
-
this.advanceTime(15);
|
233 |
-
},
|
234 |
-
next: 'dancing'
|
235 |
-
},
|
236 |
-
{
|
237 |
-
text: "Retreat to get a drink",
|
238 |
-
effect: stats => {
|
239 |
-
stats.drinks++;
|
240 |
-
stats.confidence += 5;
|
241 |
-
this.advanceTime(10);
|
242 |
-
},
|
243 |
-
next: 'after_drink'
|
244 |
-
}
|
245 |
-
]
|
246 |
-
},
|
247 |
-
dancing: {
|
248 |
-
text: "You're dancing! Not too badly either. You notice she's glancing in your direction occasionally.",
|
249 |
-
choices: [
|
250 |
-
{
|
251 |
-
text: "Make eye contact and smile",
|
252 |
-
effect: stats => {
|
253 |
-
stats.confidence += 20;
|
254 |
-
this.advanceTime(5);
|
255 |
-
},
|
256 |
-
next: 'eye_contact'
|
257 |
-
},
|
258 |
-
{
|
259 |
-
text: "Keep dancing but avoid eye contact",
|
260 |
-
effect: stats => {
|
261 |
-
stats.confidence += 5;
|
262 |
-
this.advanceTime(15);
|
263 |
-
},
|
264 |
-
next: 'continue_dancing'
|
265 |
-
}
|
266 |
-
]
|
267 |
-
},
|
268 |
-
eye_contact: {
|
269 |
-
text: "She smiles back! Your heart is racing, but in a good way.",
|
270 |
-
choices: [
|
271 |
-
{
|
272 |
-
text: "Walk over and say hi",
|
273 |
-
condition: stats => stats.confidence >= 60,
|
274 |
-
next: 'success'
|
275 |
-
},
|
276 |
-
{
|
277 |
-
text: "Panic and get another drink",
|
278 |
-
effect: stats => {
|
279 |
-
stats.drinks++;
|
280 |
-
stats.confidence += 10;
|
281 |
-
this.advanceTime(10);
|
282 |
-
},
|
283 |
-
next: 'more_drinks'
|
284 |
-
}
|
285 |
-
]
|
286 |
-
},
|
287 |
-
success: {
|
288 |
-
text: "Congratulations! You managed to overcome your shyness and talk to her. Turns out, she's been hoping you'd come say hi all evening. Sometimes the hardest part is just taking that first step.",
|
289 |
-
choices: [
|
290 |
-
{
|
291 |
-
text: "Play Again",
|
292 |
-
effect: stats => {
|
293 |
-
stats.confidence = 0;
|
294 |
-
stats.drinks = 0;
|
295 |
-
stats.time = new Date(2024, 0, 1, 20, 0);
|
296 |
-
},
|
297 |
-
next: 'start'
|
298 |
-
}
|
299 |
-
]
|
300 |
}
|
301 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
302 |
}
|
303 |
|
304 |
-
|
305 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
306 |
</script>
|
307 |
</body>
|
308 |
</html>
|
|
|
3 |
<head>
|
4 |
<meta charset="UTF-8">
|
5 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6 |
+
<title>Shy Guy Simulator - AI Edition</title>
|
7 |
<style>
|
8 |
body {
|
9 |
font-family: Arial, sans-serif;
|
|
|
21 |
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
|
22 |
}
|
23 |
|
24 |
+
.chat-container {
|
25 |
+
height: 400px;
|
26 |
+
overflow-y: auto;
|
27 |
+
margin: 20px 0;
|
28 |
+
padding: 10px;
|
29 |
+
background-color: #333;
|
30 |
+
border-radius: 4px;
|
31 |
+
}
|
32 |
+
|
33 |
+
.message {
|
34 |
+
margin: 10px 0;
|
35 |
+
padding: 10px;
|
36 |
+
border-radius: 4px;
|
37 |
+
word-wrap: break-word;
|
38 |
+
}
|
39 |
+
|
40 |
+
.wingman {
|
41 |
+
background-color: #2c5282;
|
42 |
+
margin-right: 20%;
|
43 |
+
}
|
44 |
+
|
45 |
+
.shyguy {
|
46 |
+
background-color: #4a5568;
|
47 |
+
margin-left: 20%;
|
48 |
+
}
|
49 |
+
|
50 |
+
.error {
|
51 |
+
background-color: #c53030;
|
52 |
+
text-align: center;
|
53 |
}
|
54 |
|
55 |
+
#input-container {
|
56 |
display: flex;
|
|
|
57 |
gap: 10px;
|
58 |
+
margin-top: 20px;
|
59 |
+
}
|
60 |
+
|
61 |
+
#user-input {
|
62 |
+
flex-grow: 1;
|
63 |
+
padding: 10px;
|
64 |
+
border: none;
|
65 |
+
border-radius: 4px;
|
66 |
+
background-color: #4a4a4a;
|
67 |
+
color: white;
|
68 |
}
|
69 |
|
70 |
button {
|
71 |
padding: 10px 20px;
|
72 |
+
background-color: #4299e1;
|
73 |
color: white;
|
74 |
border: none;
|
75 |
border-radius: 4px;
|
76 |
cursor: pointer;
|
|
|
77 |
}
|
78 |
|
79 |
button:hover {
|
80 |
+
background-color: #3182ce;
|
81 |
}
|
82 |
|
83 |
#stats {
|
|
|
85 |
padding: 10px;
|
86 |
background-color: #333;
|
87 |
border-radius: 4px;
|
88 |
+
display: flex;
|
89 |
+
justify-content: space-between;
|
90 |
}
|
91 |
|
92 |
+
.typing {
|
93 |
font-style: italic;
|
94 |
+
color: #718096;
|
95 |
+
}
|
96 |
+
|
97 |
+
#api-key-container {
|
98 |
+
margin-bottom: 20px;
|
99 |
}
|
100 |
</style>
|
101 |
</head>
|
102 |
<body>
|
103 |
<div id="game-container">
|
104 |
+
<h1>Shy Guy Simulator - AI Edition</h1>
|
105 |
+
|
106 |
+
<div id="api-key-container">
|
107 |
+
<input type="password" id="api-key" placeholder="Enter your Mistral API key" style="width: 100%; padding: 10px; margin-bottom: 10px;">
|
108 |
+
<button onclick="initializeGame()" id="start-button">Start Game</button>
|
109 |
+
</div>
|
110 |
+
|
111 |
+
<div id="game-content" style="display: none;">
|
112 |
+
<div id="stats">
|
113 |
+
<span>Confidence: <span id="confidence">0</span>%</span>
|
114 |
+
<span>Anxiety: <span id="anxiety">100</span>%</span>
|
115 |
+
<span>Time: <span id="time">8:00 PM</span></span>
|
116 |
+
</div>
|
117 |
+
<div class="chat-container" id="chat-container"></div>
|
118 |
+
<div id="input-container">
|
119 |
+
<input type="text" id="user-input" placeholder="Type your encouragement as wingman...">
|
120 |
+
<button onclick="handleUserInput()">Send</button>
|
121 |
+
</div>
|
122 |
</div>
|
|
|
|
|
123 |
</div>
|
124 |
|
125 |
<script>
|
126 |
+
let game;
|
127 |
+
|
128 |
+
class ShyGuySimulator {
|
129 |
+
constructor(apiKey) {
|
130 |
+
this.apiKey = apiKey;
|
131 |
+
this.state = {
|
132 |
confidence: 0,
|
133 |
+
anxiety: 100,
|
134 |
+
time: new Date(2024, 0, 1, 20, 0),
|
135 |
+
location: 'entrance',
|
136 |
+
hasSpokenToGirl: false,
|
137 |
+
isProcessing: false
|
138 |
};
|
139 |
+
|
140 |
+
this.context = [
|
141 |
+
{
|
142 |
+
role: 'system',
|
143 |
+
content: `You are roleplaying as a shy and anxious guy at a homecoming party.
|
144 |
+
You're standing near the entrance, and the girl you like is across the room.
|
145 |
+
Your responses should reflect your social anxiety and reluctance to approach her.
|
146 |
+
Keep responses concise (max 2-3 sentences) and natural.
|
147 |
+
Express hesitation, worry, and self-doubt while reacting to the wingman's encouragement.`
|
148 |
+
}
|
149 |
];
|
150 |
|
151 |
this.initialize();
|
152 |
}
|
153 |
|
154 |
initialize() {
|
155 |
+
this.addMessage("Hey! I'll be your wingman tonight. I see that girl you like over there - let's help you talk to her!", 'wingman');
|
156 |
+
this.addMessage("I... I don't know about this. Maybe I should just go home...", 'shyguy');
|
157 |
this.updateStats();
|
|
|
|
|
158 |
}
|
159 |
|
160 |
+
async handleInput(userInput) {
|
161 |
+
if (this.state.isProcessing) return;
|
162 |
+
this.state.isProcessing = true;
|
163 |
+
|
164 |
+
try {
|
165 |
+
if (!userInput.trim()) throw new Error("Please enter some text");
|
166 |
+
|
167 |
+
this.addMessage(userInput, 'wingman');
|
168 |
+
this.addLoadingMessage();
|
169 |
+
|
170 |
+
const currentState = `Current confidence: ${this.state.confidence}%, anxiety: ${this.state.anxiety}%, location: ${this.state.location}`;
|
171 |
+
|
172 |
+
this.context.push({
|
173 |
+
role: 'user',
|
174 |
+
content: `${userInput}\n\n${currentState}`
|
175 |
+
});
|
176 |
+
|
177 |
+
const response = await this.callMistralAPI();
|
178 |
|
179 |
+
this.removeLoadingMessage();
|
180 |
+
this.addMessage(response, 'shyguy');
|
181 |
|
182 |
+
this.updateGameState(response);
|
183 |
+
|
184 |
+
this.context.push({
|
185 |
+
role: 'assistant',
|
186 |
+
content: response
|
187 |
+
});
|
188 |
+
|
189 |
+
if (this.context.length > 10) {
|
190 |
+
this.context = [
|
191 |
+
this.context[0],
|
192 |
+
...this.context.slice(-4)
|
193 |
+
];
|
194 |
+
}
|
195 |
+
} catch (error) {
|
196 |
+
this.removeLoadingMessage();
|
197 |
+
this.addMessage(`Error: ${error.message}`, 'error');
|
198 |
+
console.error('Error:', error);
|
199 |
+
} finally {
|
200 |
+
this.state.isProcessing = false;
|
201 |
}
|
202 |
}
|
203 |
|
204 |
+
async callMistralAPI() {
|
205 |
+
try {
|
206 |
+
const response = await fetch('https://api.mistral.ai/v1/chat/completions', {
|
207 |
+
method: 'POST',
|
208 |
+
headers: {
|
209 |
+
'Content-Type': 'application/json',
|
210 |
+
'Authorization': `Bearer ${this.apiKey}`
|
211 |
+
},
|
212 |
+
body: JSON.stringify({
|
213 |
+
model: 'mistral-large-latest',
|
214 |
+
messages: this.context,
|
215 |
+
max_tokens: 150,
|
216 |
+
temperature: 0.7
|
217 |
+
})
|
218 |
+
});
|
219 |
+
|
220 |
+
if (!response.ok) {
|
221 |
+
const error = await response.json();
|
222 |
+
throw new Error(error.error?.message || 'API request failed');
|
223 |
+
}
|
224 |
+
|
225 |
+
const data = await response.json();
|
226 |
+
return data.choices[0].message.content;
|
227 |
+
} catch (error) {
|
228 |
+
if (error.message.includes('API key')) {
|
229 |
+
throw new Error('Invalid API key. Please check your API key and try again.');
|
230 |
+
}
|
231 |
+
throw new Error('Failed to get response from AI. Please try again.');
|
232 |
+
}
|
233 |
}
|
234 |
|
235 |
+
updateGameState(response) {
|
236 |
+
const lowerResponse = response.toLowerCase();
|
237 |
+
|
238 |
+
// Update confidence
|
239 |
+
if (lowerResponse.includes('okay') || lowerResponse.includes('maybe') || lowerResponse.includes('right')) {
|
240 |
+
this.state.confidence = Math.min(100, this.state.confidence + 10);
|
241 |
+
this.state.anxiety = Math.max(0, this.state.anxiety - 5);
|
242 |
+
} else if (lowerResponse.includes('no') || lowerResponse.includes('can\'t') || lowerResponse.includes('scared')) {
|
243 |
+
this.state.confidence = Math.max(0, this.state.confidence - 5);
|
244 |
+
this.state.anxiety = Math.min(100, this.state.anxiety + 10);
|
245 |
+
}
|
246 |
+
|
247 |
+
// Advance time
|
248 |
+
this.state.time = new Date(this.state.time.getTime() + 5 * 60000);
|
249 |
+
|
250 |
this.updateStats();
|
251 |
}
|
252 |
|
253 |
+
updateStats() {
|
254 |
+
document.getElementById('confidence').textContent = this.state.confidence;
|
255 |
+
document.getElementById('anxiety').textContent = this.state.anxiety;
|
256 |
+
document.getElementById('time').textContent =
|
257 |
+
this.state.time.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit' });
|
258 |
+
}
|
259 |
|
260 |
+
addMessage(text, type) {
|
261 |
+
const chat = document.getElementById('chat-container');
|
262 |
+
const messageDiv = document.createElement('div');
|
263 |
+
messageDiv.className = `message ${type}`;
|
264 |
+
messageDiv.textContent = text;
|
265 |
+
chat.appendChild(messageDiv);
|
266 |
+
chat.scrollTop = chat.scrollHeight;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
267 |
}
|
268 |
|
269 |
+
addLoadingMessage() {
|
270 |
+
const chat = document.getElementById('chat-container');
|
271 |
+
const loadingDiv = document.createElement('div');
|
272 |
+
loadingDiv.className = 'message shyguy typing';
|
273 |
+
loadingDiv.id = 'loading-message';
|
274 |
+
loadingDiv.textContent = 'Thinking...';
|
275 |
+
chat.appendChild(loadingDiv);
|
276 |
+
chat.scrollTop = chat.scrollHeight;
|
277 |
+
}
|
278 |
+
|
279 |
+
removeLoadingMessage() {
|
280 |
+
const loadingMessage = document.getElementById('loading-message');
|
281 |
+
if (loadingMessage) {
|
282 |
+
loadingMessage.remove();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
283 |
}
|
284 |
+
}
|
285 |
+
}
|
286 |
+
|
287 |
+
function initializeGame() {
|
288 |
+
const apiKey = document.getElementById('api-key').value.trim();
|
289 |
+
if (!apiKey) {
|
290 |
+
alert('Please enter your Mistral API key');
|
291 |
+
return;
|
292 |
+
}
|
293 |
+
|
294 |
+
document.getElementById('api-key-container').style.display = 'none';
|
295 |
+
document.getElementById('game-content').style.display = 'block';
|
296 |
+
|
297 |
+
game = new ShyGuySimulator(apiKey);
|
298 |
}
|
299 |
|
300 |
+
async function handleUserInput() {
|
301 |
+
if (!game) return;
|
302 |
+
|
303 |
+
const input = document.getElementById('user-input');
|
304 |
+
const text = input.value.trim();
|
305 |
+
if (text) {
|
306 |
+
await game.handleInput(text);
|
307 |
+
input.value = '';
|
308 |
+
}
|
309 |
+
}
|
310 |
+
|
311 |
+
document.getElementById('user-input')?.addEventListener('keypress', function(e) {
|
312 |
+
if (e.key === 'Enter') {
|
313 |
+
handleUserInput();
|
314 |
+
}
|
315 |
+
});
|
316 |
</script>
|
317 |
</body>
|
318 |
</html>
|