add tutorial and fix the end
Browse files- client/src/main.jsx +2 -0
- client/src/pages/Home.jsx +1 -1
- client/src/pages/tutorial/Tutorial.jsx +73 -0
- client/yarn.lock +12 -0
- server/server.py +23 -10
client/src/main.jsx
CHANGED
@@ -6,6 +6,7 @@ import CssBaseline from "@mui/material/CssBaseline";
|
|
6 |
import { theme } from "./theme";
|
7 |
import { Home } from "./pages/Home";
|
8 |
import { Game } from "./pages/Game";
|
|
|
9 |
import "./index.css";
|
10 |
|
11 |
ReactDOM.createRoot(document.getElementById("root")).render(
|
@@ -15,6 +16,7 @@ ReactDOM.createRoot(document.getElementById("root")).render(
|
|
15 |
<Routes>
|
16 |
<Route path="/" element={<Home />} />
|
17 |
<Route path="/game" element={<Game />} />
|
|
|
18 |
</Routes>
|
19 |
</BrowserRouter>
|
20 |
</ThemeProvider>
|
|
|
6 |
import { theme } from "./theme";
|
7 |
import { Home } from "./pages/Home";
|
8 |
import { Game } from "./pages/Game";
|
9 |
+
import { Tutorial } from "./pages/tutorial/Tutorial";
|
10 |
import "./index.css";
|
11 |
|
12 |
ReactDOM.createRoot(document.getElementById("root")).render(
|
|
|
16 |
<Routes>
|
17 |
<Route path="/" element={<Home />} />
|
18 |
<Route path="/game" element={<Game />} />
|
19 |
+
<Route path="/tutorial" element={<Tutorial />} />
|
20 |
</Routes>
|
21 |
</BrowserRouter>
|
22 |
</ThemeProvider>
|
client/src/pages/Home.jsx
CHANGED
@@ -37,7 +37,7 @@ export function Home() {
|
|
37 |
<Button
|
38 |
variant="outlined"
|
39 |
size="large"
|
40 |
-
onClick={() => navigate("/
|
41 |
sx={{
|
42 |
fontSize: "1.2rem",
|
43 |
padding: "12px 36px",
|
|
|
37 |
<Button
|
38 |
variant="outlined"
|
39 |
size="large"
|
40 |
+
onClick={() => navigate("/tutorial")}
|
41 |
sx={{
|
42 |
fontSize: "1.2rem",
|
43 |
padding: "12px 36px",
|
client/src/pages/tutorial/Tutorial.jsx
ADDED
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { Box, Typography, Button, Chip } from "@mui/material";
|
2 |
+
import { useNavigate } from "react-router-dom";
|
3 |
+
import PlayArrowIcon from "@mui/icons-material/PlayArrow";
|
4 |
+
|
5 |
+
export function Tutorial() {
|
6 |
+
const navigate = useNavigate();
|
7 |
+
|
8 |
+
return (
|
9 |
+
<Box
|
10 |
+
sx={{
|
11 |
+
height: "100vh",
|
12 |
+
width: "100%",
|
13 |
+
display: "flex",
|
14 |
+
flexDirection: "column",
|
15 |
+
alignItems: "center",
|
16 |
+
justifyContent: "center",
|
17 |
+
gap: 4,
|
18 |
+
padding: 4,
|
19 |
+
backgroundColor: "background.default",
|
20 |
+
color: "text.primary",
|
21 |
+
}}
|
22 |
+
>
|
23 |
+
<Typography variant="h2" component="h1" textAlign="center" gutterBottom>
|
24 |
+
How to play?
|
25 |
+
</Typography>
|
26 |
+
|
27 |
+
<Box sx={{ maxWidth: "800px", textAlign: "center" }}>
|
28 |
+
<Typography variant="h5" paragraph>
|
29 |
+
Since the rise of AI, the world is desolate. Your sister,{" "}
|
30 |
+
<Chip label="Sarah" size="small" />, is traversing these{" "}
|
31 |
+
<Chip label="wastelands" size="small" /> in search of food.
|
32 |
+
</Typography>
|
33 |
+
<Typography variant="h5" paragraph>
|
34 |
+
You are her little sister, you stayed in the bunker and you help Sarah
|
35 |
+
make decisions.
|
36 |
+
</Typography>
|
37 |
+
-
|
38 |
+
<Typography variant="body1" paragraph>
|
39 |
+
When <Chip label="Sarah" size="small" /> calls you, you have two ways
|
40 |
+
to help her:
|
41 |
+
</Typography>
|
42 |
+
<Typography variant="body1" paragraph sx={{ mb: 4 }}>
|
43 |
+
1. Choose one of the suggested responses by clicking on it
|
44 |
+
<br />
|
45 |
+
2. Use your voice to speak directly to{" "}
|
46 |
+
<Chip label="Sarah" size="small" /> by clicking the "Try to convince{" "}
|
47 |
+
<Chip label="Sarah" size="small" />" button
|
48 |
+
</Typography>
|
49 |
+
-
|
50 |
+
<Typography variant="body1" paragraph>
|
51 |
+
As her sibling and a scientist, you need to find the right words and
|
52 |
+
tone to help her understand the urgency of climate change, while
|
53 |
+
maintaining your close relationship.
|
54 |
+
</Typography>
|
55 |
+
</Box>
|
56 |
+
|
57 |
+
<Button
|
58 |
+
variant="contained"
|
59 |
+
size="large"
|
60 |
+
onClick={() => navigate("/game")}
|
61 |
+
sx={{
|
62 |
+
mt: 4,
|
63 |
+
fontSize: "1.2rem",
|
64 |
+
padding: "12px 24px",
|
65 |
+
}}
|
66 |
+
>
|
67 |
+
Start the game
|
68 |
+
</Button>
|
69 |
+
</Box>
|
70 |
+
);
|
71 |
+
}
|
72 |
+
|
73 |
+
export default Tutorial;
|
client/yarn.lock
CHANGED
@@ -2,6 +2,18 @@
|
|
2 |
# yarn lockfile v1
|
3 |
|
4 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
"@ampproject/remapping@^2.2.0":
|
6 |
version "2.3.0"
|
7 |
resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.3.0.tgz#ed441b6fa600072520ce18b43d2c8cc8caecc7f4"
|
|
|
2 |
# yarn lockfile v1
|
3 |
|
4 |
|
5 |
+
"@11labs/client@0.0.5":
|
6 |
+
version "0.0.5"
|
7 |
+
resolved "https://registry.yarnpkg.com/@11labs/client/-/client-0.0.5.tgz#4785466ed06fed8dca843df733db55f04f76a40e"
|
8 |
+
integrity sha512-quxnacC90t3mCpMBD+Nvp+PEv59428ys9ICeY3qv0GzhyurHfPg1HWHt4sr4fC6KL6iUU0rlZe9npq7zH+RPmw==
|
9 |
+
|
10 |
+
"@11labs/react@^0.0.5":
|
11 |
+
version "0.0.5"
|
12 |
+
resolved "https://registry.yarnpkg.com/@11labs/react/-/react-0.0.5.tgz#adb7884878f7b687185192bb837682eb164973e5"
|
13 |
+
integrity sha512-jeB7r0Zn/YiX0tESthmwpCpSqiEz5HYRK7ztH7M6yQx0MfTffs5McS7sU8swBqMxT62bNuDs1VTHmcZfbNXd4Q==
|
14 |
+
dependencies:
|
15 |
+
"@11labs/client" "0.0.5"
|
16 |
+
|
17 |
"@ampproject/remapping@^2.2.0":
|
18 |
version "2.3.0"
|
19 |
resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.3.0.tgz#ed441b6fa600072520ce18b43d2c8cc8caecc7f4"
|
server/server.py
CHANGED
@@ -162,6 +162,13 @@ async def chat_endpoint(chat_message: ChatMessage):
|
|
162 |
is_death = game_state.radiation_level >= MAX_RADIATION
|
163 |
if is_death:
|
164 |
llm_response.choices = []
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
165 |
# Pour la mort, on ne garde qu'un seul prompt d'image
|
166 |
if len(llm_response.image_prompts) > 1:
|
167 |
llm_response.image_prompts = [llm_response.image_prompts[0]]
|
@@ -169,16 +176,22 @@ async def chat_endpoint(chat_message: ChatMessage):
|
|
169 |
# Add segment to history (before victory check to include final state)
|
170 |
game_state.add_to_history(llm_response.story_text, previous_choice, llm_response.image_prompts)
|
171 |
|
172 |
-
#
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
182 |
|
183 |
# Pour la première étape, on ne garde qu'un seul prompt d'image
|
184 |
if game_state.story_beat == 0 and len(llm_response.image_prompts) > 1:
|
|
|
162 |
is_death = game_state.radiation_level >= MAX_RADIATION
|
163 |
if is_death:
|
164 |
llm_response.choices = []
|
165 |
+
llm_response.story_text = (
|
166 |
+
"In the desolate wastelands, Sarah's journey comes to a tragic end. "
|
167 |
+
"Despite her courage and determination, the harsh environment proved "
|
168 |
+
"too formidable. Her story, though brief, was filled with bravery and "
|
169 |
+
"hope. She will be remembered as a beacon of resilience in a world "
|
170 |
+
"that had lost its way."
|
171 |
+
)
|
172 |
# Pour la mort, on ne garde qu'un seul prompt d'image
|
173 |
if len(llm_response.image_prompts) > 1:
|
174 |
llm_response.image_prompts = [llm_response.image_prompts[0]]
|
|
|
176 |
# Add segment to history (before victory check to include final state)
|
177 |
game_state.add_to_history(llm_response.story_text, previous_choice, llm_response.image_prompts)
|
178 |
|
179 |
+
# THERE IS NOT ESCAPE HAHA
|
180 |
+
# # Check for victory condition
|
181 |
+
# if not is_death and game_state.story_beat >= 5:
|
182 |
+
# # Chance de victoire augmente avec le nombre de steps
|
183 |
+
# victory_chance = (game_state.story_beat - 4) * 0.02 # 20% de chance par step après le 5ème
|
184 |
+
# if random.random() < victory_chance:
|
185 |
+
# llm_response.is_victory = True
|
186 |
+
# llm_response.choices = []
|
187 |
+
# llm_response.story_text = (
|
188 |
+
# "Sarah triumphs over the wastelands. Her journey was tough, but she "
|
189 |
+
# "emerged stronger and hopeful. The horizon now promises a new beginning. "
|
190 |
+
# "You have won, and Sarah's story continues with renewed strength."
|
191 |
+
# )
|
192 |
+
# # Pour la victoire, on ne garde qu'un seul prompt d'image
|
193 |
+
# if len(llm_response.image_prompts) > 1:
|
194 |
+
# llm_response.image_prompts = [llm_response.image_prompts[0]]
|
195 |
|
196 |
# Pour la première étape, on ne garde qu'un seul prompt d'image
|
197 |
if game_state.story_beat == 0 and len(llm_response.image_prompts) > 1:
|