sgongora27 commited on
Commit
33cda60
1 Parent(s): 56a4453

Update prompts

Browse files
Files changed (4) hide show
  1. app.py +8 -8
  2. example_worlds.py +6 -2
  3. prompts.py +23 -16
  4. world.py +93 -11
app.py CHANGED
@@ -45,14 +45,14 @@ def game_loop(message, history):
45
  game_log_dictionary[number_of_turns] = {}
46
  game_log_dictionary[number_of_turns]["date"] = time.ctime(time.time())
47
  game_log_dictionary[number_of_turns]["previous_symbolic_world_state"] = jsonpickle.encode(world, unpicklable=False)
48
- game_log_dictionary[number_of_turns]["previous_rendered_world_state"] = world.render_world()
49
  game_log_dictionary[number_of_turns]["user_input"] = message
50
 
51
 
52
  answer = ""
53
 
54
  # Get the changes in the world
55
- prompt_update = prompt_world_update(world.render_world(), message, language=language)
56
  response_update = reasoning_model.prompt_model(prompt_update)
57
 
58
  # Show the detected changes in the fictional world
@@ -69,13 +69,13 @@ def game_loop(message, history):
69
  # World update
70
  world.update(response_update)
71
  game_log_dictionary[number_of_turns]["updated_symbolic_world_state"] = jsonpickle.encode(world, unpicklable=True)
72
- game_log_dictionary[number_of_turns]["updated_rendered_world_state"] = world.render_world()
73
 
74
  if last_player_position is not world.player.location:
75
  #Narrate new scene
76
  last_player_position = world.player.location
77
  new_scene_narration = narrative_model.prompt_model(
78
- prompt_narrate_current_scene(world.render_world(),
79
  previous_narrations = world.player.visited_locations[world.player.location.name],
80
  language=language)
81
 
@@ -90,7 +90,7 @@ def game_loop(message, history):
90
  print (f"Error: {e}")
91
 
92
 
93
- print(f"\n🌎 World state 🌍\n>Player input: {message}\n{world.render_world()}\n")
94
 
95
  if world.check_objective():
96
  if language=='es':
@@ -129,15 +129,15 @@ game_log_dictionary["world_id"] = world_id
129
  game_log_dictionary["narrative_model_name"] = narrative_model_name
130
  game_log_dictionary["reasoning_model_name"] = reasoning_model_name
131
 
132
- print(f"\n🌎 World state 🌍\n{world.render_world()}\n")
133
  game_log_dictionary[0] = {}
134
  game_log_dictionary[0]["date"] = time.ctime(time.time())
135
  game_log_dictionary[0]["initial_symbolic_world_state"] = jsonpickle.encode(world, unpicklable=True)
136
- game_log_dictionary[0]["initial_rendered_world_state"] = world.render_world()
137
 
138
  #Generate a description of the starting scene
139
  starting_narration = narrative_model.prompt_model(
140
- prompt_narrate_current_scene(world.render_world(),
141
  previous_narrations = world.player.visited_locations[world.player.location.name],
142
  language=language,
143
  starting_scene=True))
 
45
  game_log_dictionary[number_of_turns] = {}
46
  game_log_dictionary[number_of_turns]["date"] = time.ctime(time.time())
47
  game_log_dictionary[number_of_turns]["previous_symbolic_world_state"] = jsonpickle.encode(world, unpicklable=False)
48
+ game_log_dictionary[number_of_turns]["previous_rendered_world_state"] = world.render_world(language=language)
49
  game_log_dictionary[number_of_turns]["user_input"] = message
50
 
51
 
52
  answer = ""
53
 
54
  # Get the changes in the world
55
+ prompt_update = prompt_world_update(world.render_world(language=language), message, language=language)
56
  response_update = reasoning_model.prompt_model(prompt_update)
57
 
58
  # Show the detected changes in the fictional world
 
69
  # World update
70
  world.update(response_update)
71
  game_log_dictionary[number_of_turns]["updated_symbolic_world_state"] = jsonpickle.encode(world, unpicklable=True)
72
+ game_log_dictionary[number_of_turns]["updated_rendered_world_state"] = world.render_world(language=language)
73
 
74
  if last_player_position is not world.player.location:
75
  #Narrate new scene
76
  last_player_position = world.player.location
77
  new_scene_narration = narrative_model.prompt_model(
78
+ prompt_narrate_current_scene(world.render_world(language=language),
79
  previous_narrations = world.player.visited_locations[world.player.location.name],
80
  language=language)
81
 
 
90
  print (f"Error: {e}")
91
 
92
 
93
+ print(f"\n🌎 World state 🌍\n>Player input: {message}\n{world.render_world(language=language)}\n")
94
 
95
  if world.check_objective():
96
  if language=='es':
 
129
  game_log_dictionary["narrative_model_name"] = narrative_model_name
130
  game_log_dictionary["reasoning_model_name"] = reasoning_model_name
131
 
132
+ print(f"\n🌎 World state 🌍\n{world.render_world(language=language)}\n")
133
  game_log_dictionary[0] = {}
134
  game_log_dictionary[0]["date"] = time.ctime(time.time())
135
  game_log_dictionary[0]["initial_symbolic_world_state"] = jsonpickle.encode(world, unpicklable=True)
136
+ game_log_dictionary[0]["initial_rendered_world_state"] = world.render_world(language=language)
137
 
138
  #Generate a description of the starting scene
139
  starting_narration = narrative_model.prompt_model(
140
+ prompt_narrate_current_scene(world.render_world(language=language),
141
  previous_narrations = world.player.visited_locations[world.player.location.name],
142
  language=language,
143
  starting_scene=True))
example_worlds.py CHANGED
@@ -216,8 +216,11 @@ def get_world_2_spanish() -> World:
216
  ["Un estanque de agua cristalina", "El agua es tan clara que funciona como un espejo"],
217
  gettable=False)
218
  item_3 = Item("Un muro de llamas",
219
- ["Las llamas son fuertes y dan mucho calor", "Tiene una altura de 3 metros"],
220
  gettable=False)
 
 
 
221
  puzzle_1 = Puzzle("Puzzle",
222
  ["Un encanto mágico que genera un muro intraspasable", "Mágicamente, al acercarse aparecen unas letras azules que explican cuál es el acertijo a resolver"],
223
  "Hay que susurrar el nombre del río que baña la costa sur de la Banda Oriental", "Rio de la Plata")
@@ -241,9 +244,10 @@ def get_world_2_spanish() -> World:
241
  ["El héroe nacional de Uruguay", "Está cansado, de estar tanto tiempo encerrado"],
242
  inventory = [],
243
  location = place_3)
 
244
  player = Character("Venancio",
245
  ["Un gaucho uruguayo de 40 años de edad", "Pertenece a los soldados de Artigas", "Tiene el poder mágico de invocar una ola gigante de agua con la que puede apagar fuegos o humedecer la tierra"],
246
- inventory = [],
247
  location= place_1)
248
 
249
  the_world = World(player)
 
216
  ["Un estanque de agua cristalina", "El agua es tan clara que funciona como un espejo"],
217
  gettable=False)
218
  item_3 = Item("Un muro de llamas",
219
+ ["Las llamas son fuertes y dan mucho calor", "Tiene una altura de 3 metros", "Es imposible cruzarlas, ni caminando, ni corriendo, ni saltando."],
220
  gettable=False)
221
+ item_4 = Item("Guitarra",
222
+ ["Una guitarra clásica con 6 cuerdas", "Suena muy bien"])
223
+
224
  puzzle_1 = Puzzle("Puzzle",
225
  ["Un encanto mágico que genera un muro intraspasable", "Mágicamente, al acercarse aparecen unas letras azules que explican cuál es el acertijo a resolver"],
226
  "Hay que susurrar el nombre del río que baña la costa sur de la Banda Oriental", "Rio de la Plata")
 
244
  ["El héroe nacional de Uruguay", "Está cansado, de estar tanto tiempo encerrado"],
245
  inventory = [],
246
  location = place_3)
247
+
248
  player = Character("Venancio",
249
  ["Un gaucho uruguayo de 40 años de edad", "Pertenece a los soldados de Artigas", "Tiene el poder mágico de invocar una ola gigante de agua con la que puede apagar fuegos o humedecer la tierra"],
250
+ inventory = [item_4],
251
  location= place_1)
252
 
253
  the_world = World(player)
prompts.py CHANGED
@@ -109,13 +109,11 @@ def prompt_world_update (world_state: str, input: str, language: str = 'en') ->
109
  return prompt
110
 
111
  def prompt_world_update_spanish (world_state: str, input: str) -> str:
112
- prompt = f"""Eres un narrador. Estás manejando un mundo ficticio, y el jugador puede interactuar con él. Este es el estado del mundo en este momento:
113
- {world_state}\n\n
114
- Explica los cambios en el mundo a partir de las acciones del jugador en esta entrada "{input}".
115
 
116
  Aquí hay algunas aclaraciones:
117
- (A) Si un pasaje está bloqueado, significa que el jugador debe desbloquearlo antes de poder acceder al lugar. Aunque el jugador te diga que va a acceder al lugar bloqueado, tienes que estar seguro de que está cumpliendo con lo pedido para permitirle desbloquear el acceso, por ejemplo usando una llave o resolviendo un puzzle.
118
- (B) Presta atención a a la descripción de los componentes y sus capacidades.
119
  (C) No asumas que lo que dice el jugador siempre tiene sentido; quizás esas acciones intentan hacer algo que el mundo no lo permite.
120
  (D) Sigue siempre el siguiente formato con las tres categorías, usando "None" en cada caso si no hay cambios y repite la categoría por cada caso:
121
  - Moved object: <object> now is in <new_location>
@@ -124,63 +122,72 @@ def prompt_world_update_spanish (world_state: str, input: str) -> str:
124
  (E) Por último, puedes agregar una narración de los cambios detecados en el estado del mundo (¡sin hacer avanzar la historia y sin crear detalles no incluidos en el estado del mundo!) usando el formato: #<tu mensaje final>#
125
  (F) Dentro de la sección de narración que agregues al final, entre símbolos #, también puedes responder preguntas que haga el jugador en su entrada, sobre los objetos o personajes que puede ver, o el lugar en el que se encuentra.
126
 
127
- Aquí hay algunos ejemplos sobre el formato, descritos en los puntos (D) y (E):
128
 
129
- Ejemplo 1
130
  - Moved object: <hacha> now is in <Inventory>
131
  - Blocked passages now available: None
132
  - Your location changed: None
133
  # Guardaste el hacha en tu bolso. Sientes la diferencia de peso luego de haberla guardado #
134
 
135
- Ejemplo 2
136
  - Moved object: None
137
  - Blocked passages now available: <Sótano>
138
  - Your location changed: None
139
  # El sótano, que estaba bloqueado, ahora está accesible #
140
 
141
- Ejemplo 3
142
  - Moved object: None
143
  - Blocked passages now available: None
144
  - Your location changed: <Jardín>
145
  # Entras al Jardín #
146
 
147
- Ejemplo 4
148
  - Moved object: <banana> now is in <Inventory>, <botella> now is in <Inventory>, <hacha> now is in <Hall principal>
149
  - Blocked passages now available: None
150
  - Your location changed: None
151
  # Guardaste la banana y la botella en tu bolso. El hacha quedó en el Hall principal #
152
 
153
- Ejemplo 5
154
  - Moved object: <banana> now is in <Inventory>, <botella> now is in <Inventory>, <hacha> now is in <Hall principal>
155
  - Blocked passages now available: <Pequeña habitación>
156
  - Your location changed: None
157
  # Guardaste la banana y la botella en tu bolso. El hacha quedó en el Hall principal. Además, la pequeña habitación ahora está accesible. #
158
 
159
- Ejemplo 6
160
  - Moved object: <banana> now is in <Inventory>, <botella> now is in <Inventory>, <hacha> now is in <Hall principal>
161
  - Blocked passages now available: <Pequeña habitación>
162
  - Your location changed: <Pequeña habitación>
163
  # Guardaste la banana y la botella en tu bolso. El hacha quedó en el Hall principal. Además, la pequeña habitación ahora está accesible e ingresaste a ella #
164
 
165
- Ejemplo 7
166
  - Moved object: <libro> now is in <John>, <lápiz> now is in <Inventory>
167
  - Blocked passages now available: None
168
  - Your location changed: None
169
  # John ahora tiene el libro. Tú guardaste el lápiz en tu bolso #
170
 
171
- Ejemplo 8
172
  - Moved object: <computadora> now is in <Susan>
173
  - Blocked passages now available: None
174
  - Your location changed: None
175
  # Susan guardó la computadora en su bolso #
176
 
177
- Ejemplo 9
178
  - Moved object: None
179
  - Blocked passages now available: None
180
  - Your location changed: None
181
  # No pasa nada... #
182
 
183
- """
 
 
 
 
 
 
 
 
 
184
 
185
  return prompt
186
 
 
109
  return prompt
110
 
111
  def prompt_world_update_spanish (world_state: str, input: str) -> str:
112
+ prompt = f"""Eres un narrador. Estás manejando un mundo ficticio, y el jugador puede interactuar con él. Siguiendo un formato específico, que voy a explicarte más abajo, tu tarea es encontrar los cambios en el mundo a raíz de las acciones del jugador. En específico, tendrás que encontrar qué objetos cambiaron de lugar, qué pasajes entre lugares se desbloquearon y si el jugador se movió de lugar.
 
 
113
 
114
  Aquí hay algunas aclaraciones:
115
+ (A) Presta atención a a la descripción de los componentes y sus capacidades.
116
+ (B) Si un pasaje está bloqueado, significa que el jugador debe desbloquearlo antes de poder acceder al lugar. Aunque el jugador te diga que va a acceder al lugar bloqueado, tienes que estar seguro de que está cumpliendo con lo pedido para permitirle desbloquear el acceso, por ejemplo usando una llave o resolviendo un puzzle.
117
  (C) No asumas que lo que dice el jugador siempre tiene sentido; quizás esas acciones intentan hacer algo que el mundo no lo permite.
118
  (D) Sigue siempre el siguiente formato con las tres categorías, usando "None" en cada caso si no hay cambios y repite la categoría por cada caso:
119
  - Moved object: <object> now is in <new_location>
 
122
  (E) Por último, puedes agregar una narración de los cambios detecados en el estado del mundo (¡sin hacer avanzar la historia y sin crear detalles no incluidos en el estado del mundo!) usando el formato: #<tu mensaje final>#
123
  (F) Dentro de la sección de narración que agregues al final, entre símbolos #, también puedes responder preguntas que haga el jugador en su entrada, sobre los objetos o personajes que puede ver, o el lugar en el que se encuentra.
124
 
125
+ Aquí hay algunos ejemplos (con la aclaración entre paréntesis sobre qué podría haber intentado hacer el jugador) sobre el formato, descritos en los puntos (D) y (E):
126
 
127
+ Ejemplo 1 (El jugador guarda el hacha en su inventario)
128
  - Moved object: <hacha> now is in <Inventory>
129
  - Blocked passages now available: None
130
  - Your location changed: None
131
  # Guardaste el hacha en tu bolso. Sientes la diferencia de peso luego de haberla guardado #
132
 
133
+ Ejemplo 2 (El jugador desbloquea el pasaje al Sótano)
134
  - Moved object: None
135
  - Blocked passages now available: <Sótano>
136
  - Your location changed: None
137
  # El sótano, que estaba bloqueado, ahora está accesible #
138
 
139
+ Ejemplo 3 (El jugador ahora está en el Jardín)
140
  - Moved object: None
141
  - Blocked passages now available: None
142
  - Your location changed: <Jardín>
143
  # Entras al Jardín #
144
 
145
+ Ejemplo 4 (El jugador guarda objetos y deja el hacha en el lugar)
146
  - Moved object: <banana> now is in <Inventory>, <botella> now is in <Inventory>, <hacha> now is in <Hall principal>
147
  - Blocked passages now available: None
148
  - Your location changed: None
149
  # Guardaste la banana y la botella en tu bolso. El hacha quedó en el Hall principal #
150
 
151
+ Ejemplo 5 (El jugador guarda objetos, deja el hacha en el lugar y desbloquea el pasaje a la Pequeña habitación)
152
  - Moved object: <banana> now is in <Inventory>, <botella> now is in <Inventory>, <hacha> now is in <Hall principal>
153
  - Blocked passages now available: <Pequeña habitación>
154
  - Your location changed: None
155
  # Guardaste la banana y la botella en tu bolso. El hacha quedó en el Hall principal. Además, la pequeña habitación ahora está accesible. #
156
 
157
+ Ejemplo 6 (El jugador guarda objetos, deja el hacha en el lugar, desbloquea el pasaje y se mueve a la Pequeña habitación)
158
  - Moved object: <banana> now is in <Inventory>, <botella> now is in <Inventory>, <hacha> now is in <Hall principal>
159
  - Blocked passages now available: <Pequeña habitación>
160
  - Your location changed: <Pequeña habitación>
161
  # Guardaste la banana y la botella en tu bolso. El hacha quedó en el Hall principal. Además, la pequeña habitación ahora está accesible e ingresaste a ella #
162
 
163
+ Ejemplo 7 (El jugador guarda el lápiz y le da un libro a John)
164
  - Moved object: <libro> now is in <John>, <lápiz> now is in <Inventory>
165
  - Blocked passages now available: None
166
  - Your location changed: None
167
  # John ahora tiene el libro. Tú guardaste el lápiz en tu bolso #
168
 
169
+ Ejemplo 8 (El jugador le da la computadora a Susan)
170
  - Moved object: <computadora> now is in <Susan>
171
  - Blocked passages now available: None
172
  - Your location changed: None
173
  # Susan guardó la computadora en su bolso #
174
 
175
+ Ejemplo 9 (El jugador hace algo que no tiene como resultado el efecto que esperaba)
176
  - Moved object: None
177
  - Blocked passages now available: None
178
  - Your location changed: None
179
  # No pasa nada... #
180
 
181
+ Ejemplo 10 (El jugador hace una pregunta)
182
+ - Moved object: None
183
+ - Blocked passages now available: None
184
+ - Your location changed: None
185
+ # Respuesta a la pregunta del jugador #
186
+
187
+
188
+ Ahora, expresa los cambios en el mundo siguiendo el formato pedido, teniendo en cuenta que el jugador ingresó esta entrada "{input}" a partir de este estado del mundo:
189
+
190
+ {world_state}"""
191
 
192
  return prompt
193
 
world.py CHANGED
@@ -228,9 +228,91 @@ class World:
228
  for character in characters:
229
  self.add_character(character)
230
 
231
- def render_world(self, *, detail_components:bool = True) -> str:
232
  """Return the fictional world as a natural language description, using simple sentences.
233
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
234
  The components described are only those the player can see in the current location.
235
  If detail_components is False, then the descriptions for each component are not included.
236
  """
@@ -240,12 +322,12 @@ class World:
240
  characters_in_the_scene = [character for character in self.characters.values() if character.location is player_location]
241
 
242
 
243
- world_description = f'You are in <{player_location.name}>\n'
244
 
245
  if reachable_locations:
246
- world_description += f'From <{player_location.name}> you can access: {(", ").join(reachable_locations)}\n'
247
  else:
248
- world_description += f'From <{player_location.name}> you can access: None\n'
249
 
250
  if blocked_passages:
251
  world_description += f'From <{player_location.name}> there are blocked passages to: {(", ").join(blocked_passages)}\n'
@@ -253,19 +335,19 @@ class World:
253
  world_description += f'From <{player_location.name}> there are blocked passages to: None\n'
254
 
255
  if self.player.inventory:
256
- world_description += f'You have the following items in your inventory: {(", ").join([f"<{i.name}>" for i in self.player.inventory])}\n'
257
  else:
258
- world_description += f'You have the following items in your inventory: None\n'
259
 
260
  if player_location.items:
261
- world_description += f'If you look around, you can see the following items: {(", ").join([f"<{i.name}>" for i in player_location.items])}\n'
262
  else:
263
- world_description += f'If you look around, you can see the following items: None\n'
264
 
265
  if characters_in_the_scene:
266
- world_description += f'You can see some people: {(", ").join([f"<{c.name}>" for c in characters_in_the_scene])}'
267
  else:
268
- world_description += f'You can see some people: None'
269
 
270
  details = ""
271
  if detail_components:
@@ -275,7 +357,7 @@ class World:
275
  details += "\nHere is a description of each component.\n"
276
  details += f"<{player_location.name}>: This is the player's location. {('. ').join(player_location.descriptions)}.\n"
277
  details += "Characters:\n"
278
- details += f"- <Player>: The player is acting as {self.player.name}. {('. ').join(self.player.descriptions)}.\n"
279
  if len(characters_in_the_scene)>0:
280
  for character in characters_in_the_scene:
281
  details += f"- <{character.name}>: {('. ').join(character.descriptions)}."
 
228
  for character in characters:
229
  self.add_character(character)
230
 
231
+ def render_world(self, *, language:str = 'en', detail_components:bool = True) -> str:
232
  """Return the fictional world as a natural language description, using simple sentences.
233
 
234
+ The components described are only those the player can see in the current location.
235
+ If detail_components is False, then the descriptions for each component are not included.
236
+ """
237
+ rendered_world = ''
238
+
239
+ if language == 'es':
240
+ rendered_world = self.__render_world_spanish(detail_components = detail_components)
241
+ else:
242
+ rendered_world = self.__render_world_english(detail_components = detail_components)
243
+
244
+ return rendered_world
245
+
246
+ def __render_world_spanish(self, *, detail_components:bool = True) -> str:
247
+ """Return the fictional world as a natural language description, using simple sentences in Spanish.
248
+
249
+ The components described are only those the player can see in the current location.
250
+ If detail_components is False, then the descriptions for each component are not included.
251
+ """
252
+ player_location = self.player.location
253
+ reachable_locations = [f"<{p.name}>" for p in player_location.connecting_locations]
254
+ blocked_passages = [f"<{p}> bloqueado por <{player_location.blocked_locations[p][1].name}>" for p in player_location.blocked_locations.keys()]
255
+ characters_in_the_scene = [character for character in self.characters.values() if character.location is player_location]
256
+
257
+
258
+ world_description = f'El jugador está en <{player_location.name}>\n'
259
+
260
+ if reachable_locations:
261
+ world_description += f'Desde <{player_location.name}> el jugador puede ir a: {(", ").join(reachable_locations)}\n'
262
+ else:
263
+ world_description += f'Desde <{player_location.name}> el jugador puede ir a: None\n'
264
+
265
+ if blocked_passages:
266
+ world_description += f'Desde <{player_location.name}> hay pasajes bloqueados hacia: {(", ").join(blocked_passages)}\n'
267
+ else:
268
+ world_description += f'Desde <{player_location.name}> hay pasajes bloqueados hacia: None\n'
269
+
270
+ if self.player.inventory:
271
+ world_description += f'El jugador tiene los siguientes objetos en su inventario: {(", ").join([f"<{i.name}>" for i in self.player.inventory])}\n'
272
+ else:
273
+ world_description += f'El jugador tiene los siguientes objetos en su inventario: None\n'
274
+
275
+ if player_location.items:
276
+ world_description += f'El jugador puede ver los siguientes objetos: {(", ").join([f"<{i.name}>" for i in player_location.items])}\n'
277
+ else:
278
+ world_description += f'El jugador puede ver los siguientes objetos: None\n'
279
+
280
+ if characters_in_the_scene:
281
+ world_description += f'El jugador puede ver a los siguientes personajes: {(", ").join([f"<{c.name}>" for c in characters_in_the_scene])}'
282
+ else:
283
+ world_description += f'El jugador puede ver a los siguientes personajes: None'
284
+
285
+ details = ""
286
+ if detail_components:
287
+ items_in_the_scene = player_location.items + self.player.inventory + [blocked_values[1] for blocked_values in player_location.blocked_locations.values() if isinstance(blocked_values[1], Item)]
288
+ puzzles_in_the_scene = [blocked_values[1] for blocked_values in player_location.blocked_locations.values() if isinstance(blocked_values[1], Puzzle)]
289
+
290
+ details += "\nAquí hay una descripción de cada componente.\n"
291
+ details += f"<{player_location.name}>: Este es el lugar en el que está el jugador. {('. ').join(player_location.descriptions)}.\n"
292
+ details += "Personajes:\n"
293
+ details += f"- <Jugador>: El jugador está actuando como <{self.player.name}>. {('. ').join(self.player.descriptions)}.\n"
294
+ if len(characters_in_the_scene)>0:
295
+ for character in characters_in_the_scene:
296
+ details += f"- <{character.name}>: {('. ').join(character.descriptions)}."
297
+ if len(character.inventory)>0:
298
+ details += f"Este personaje tiene los siguientes objetos en su inventario: {(', ').join([f'<{i.name}>' for i in character.inventory])}\n"
299
+ items_in_the_scene+= character.inventory
300
+ else:
301
+ details += "\n"
302
+ if len(items_in_the_scene)>0:
303
+ details+="Objetos:\n"
304
+ for item in items_in_the_scene:
305
+ details += f"- <{item.name}>: {('. ').join(item.descriptions)}\n"
306
+ if len(puzzles_in_the_scene)>0:
307
+ details+="Puzzles:\n"
308
+ for puzzle in puzzles_in_the_scene:
309
+ details+= f'- <{puzzle.name}>: {(". ").join(puzzle.descriptions)}. El acertijo a resolver es: "{puzzle.problem}". La respuesta esperada, que NO PUEDES decirle al jugador (JAMÁS) es: "{puzzle.answer}".\n'
310
+
311
+ return world_description + '\n' + details
312
+
313
+ def __render_world_english(self, *, detail_components:bool = True) -> str:
314
+ """Return the fictional world as a natural language description, using simple sentences in English.
315
+
316
  The components described are only those the player can see in the current location.
317
  If detail_components is False, then the descriptions for each component are not included.
318
  """
 
322
  characters_in_the_scene = [character for character in self.characters.values() if character.location is player_location]
323
 
324
 
325
+ world_description = f'The player is in <{player_location.name}>\n'
326
 
327
  if reachable_locations:
328
+ world_description += f'From <{player_location.name}> the player can access: {(", ").join(reachable_locations)}\n'
329
  else:
330
+ world_description += f'From <{player_location.name}> the player can access: None\n'
331
 
332
  if blocked_passages:
333
  world_description += f'From <{player_location.name}> there are blocked passages to: {(", ").join(blocked_passages)}\n'
 
335
  world_description += f'From <{player_location.name}> there are blocked passages to: None\n'
336
 
337
  if self.player.inventory:
338
+ world_description += f'The player has the following objects in the inventory: {(", ").join([f"<{i.name}>" for i in self.player.inventory])}\n'
339
  else:
340
+ world_description += f'The player has the following objects in the inventory: None\n'
341
 
342
  if player_location.items:
343
+ world_description += f'The player can see the following objects: {(", ").join([f"<{i.name}>" for i in player_location.items])}\n'
344
  else:
345
+ world_description += f'The player can see the following objects: None\n'
346
 
347
  if characters_in_the_scene:
348
+ world_description += f'The player can see the following characters: {(", ").join([f"<{c.name}>" for c in characters_in_the_scene])}'
349
  else:
350
+ world_description += f'The player can see the following characters: None'
351
 
352
  details = ""
353
  if detail_components:
 
357
  details += "\nHere is a description of each component.\n"
358
  details += f"<{player_location.name}>: This is the player's location. {('. ').join(player_location.descriptions)}.\n"
359
  details += "Characters:\n"
360
+ details += f"- <Player>: The player is acting as <{self.player.name}>. {('. ').join(self.player.descriptions)}.\n"
361
  if len(characters_in_the_scene)>0:
362
  for character in characters_in_the_scene:
363
  details += f"- <{character.name}>: {('. ').join(character.descriptions)}."