kwabs22 commited on
Commit
94b8cb6
·
1 Parent(s): 482bc30

Load config fixed

Browse files
Files changed (1) hide show
  1. app.py +154 -106
app.py CHANGED
@@ -1,5 +1,6 @@
1
  import gradio as gr
2
  import random
 
3
 
4
  # Default configuration template
5
  default_config = {
@@ -105,19 +106,6 @@ def generate_story_and_timeline():
105
 
106
  #-----------------------------------------------------------------------------------------------------------------------------------
107
 
108
- class GameState:
109
- def __init__(self, description, choices, transitions, conditions=None, npcs=None, consequences=None):
110
- self.description = description
111
- self.choices = choices
112
- self.transitions = transitions
113
- self.conditions = conditions if conditions else {}
114
- self.npcs = npcs if npcs else []
115
- self.consequences = consequences if consequences else {}
116
-
117
- def apply_consequence(self, choice, player):
118
- if choice in self.consequences:
119
- self.consequences[choice](player)
120
-
121
  class Player:
122
  def __init__(self):
123
  self.inventory = []
@@ -136,78 +124,78 @@ class Player:
136
  # Define the states
137
  all_states = {
138
  'village': {
139
- 'start': GameState(
140
- "You wake up in a small village. You hear a rumor about a lost treasure.",
141
- ['explore village', 'gather supplies', 'rest'],
142
- {'explore village': 'village_rumor', 'gather supplies': 'village_supplies', 'rest': 'village_start'},
143
- consequences={
144
  'gather supplies': lambda player: player.add_item('basic supplies')
145
  }
146
- ),
147
- 'rumor': GameState(
148
- "You hear more details about the treasure hidden in the ancient ruins nearby.",
149
- ['decide to go', 'ignore'],
150
- {'decide to go': 'village_supplies', 'ignore': 'village_start'},
151
- consequences={
152
  'decide to go': lambda player: player.update_knowledge('treasure location')
153
  }
154
- ),
155
- 'supplies': GameState(
156
- "You gather supplies for your journey.",
157
- ['head to forest', 'stay in village'],
158
- {'head to forest': 'forest_forest', 'stay in village': 'village_start'}
159
- ),
160
  },
161
  'forest': {
162
- 'forest': GameState(
163
- "You enter the dense forest, heading towards the ruins.",
164
- ['travel further', 'return to village'],
165
- {'travel further': 'ruins_ruins', 'return to village': 'village_start'}
166
- ),
167
  },
168
  'ruins': {
169
- 'ruins': GameState(
170
- "You reach the ancient ruins. The entrance is dark and eerie.",
171
- ['enter ruins', 'return to forest'],
172
- {'enter ruins': 'ruins_explore', 'return to forest': 'forest_forest'}
173
- ),
174
- 'explore': GameState(
175
- "You explore the ruins, encountering traps and puzzles.",
176
- ['solve puzzle', 'avoid traps'],
177
- {'solve puzzle': 'ruins_hiddenPassage', 'avoid traps': 'ruins_ruins'}
178
- ),
179
- 'hiddenPassage': GameState(
180
- "You solve a challenging puzzle and unlock a hidden passage.",
181
- ['enter passage', 'go back'],
182
- {'enter passage': 'ruins_treasureRoom', 'go back': 'ruins_explore'}
183
- ),
184
- 'treasureRoom': GameState(
185
- "You enter the treasure room and find the treasure chest.",
186
- ['take treasure', 'leave'],
187
- {'take treasure': 'ruins_celebrate', 'leave': 'ruins_ruins'},
188
- consequences={
189
  'take treasure': lambda player: player.add_item('treasure')
190
  }
191
- ),
192
- 'celebrate': GameState(
193
- "You celebrate your discovery and decide to bring the treasure back to the village.",
194
- ['return to village'],
195
- {'return to village': 'village_return'}
196
- ),
197
  },
198
  'village_return': {
199
- 'village_return': GameState(
200
- "You return to the village with the treasure and share it with the villagers.",
201
- ['end adventure'],
202
- {'end adventure': 'end_end'}
203
- ),
204
  },
205
  'end': {
206
- 'end': GameState(
207
- "Your adventure ends here. The villagers are grateful and everyone's lives improve.",
208
- [],
209
- {}
210
- ),
211
  }
212
  }
213
 
@@ -215,7 +203,7 @@ def validate_transitions(all_states):
215
  errors = []
216
  for location, states in all_states.items():
217
  for state_key, state in states.items():
218
- for transition_key, transition_state in state.transitions.items():
219
  # Check if the transition is to another location
220
  if transition_state in all_states:
221
  trans_location, trans_state = transition_state, 'start' # Assuming 'start' state for new locations
@@ -231,29 +219,35 @@ def validate_transitions(all_states):
231
  return errors
232
 
233
  path_errors = validate_transitions(all_states)
234
- # if path_errors:
235
- # for error in path_errors:
236
- # print(error)
237
- # else:
238
- # print("All transitions are valid.")
239
 
240
  class GameSession:
241
- def __init__(self):
242
  self.player = Player()
243
- self.current_location = 'village'
244
- self.current_state = 'start'
245
  self.game_log = []
246
 
247
  def make_choice(self, choice_index):
248
  state = all_states[self.current_location][self.current_state]
249
- if 0 <= choice_index < len(state.choices):
250
- choice = state.choices[choice_index]
251
- next_state = state.transitions[choice]
252
 
253
  self.game_log.append(f"You chose: {choice}")
254
- self.game_log.append(state.description)
255
 
256
- state.apply_consequence(choice, self.player)
 
 
 
 
 
 
257
 
258
  if '_' in next_state:
259
  self.current_location, self.current_state = next_state.split('_')
@@ -266,11 +260,11 @@ class GameSession:
266
 
267
  def get_current_state_info(self):
268
  state = all_states[self.current_location][self.current_state]
269
- choices = [f"{idx + 1}. {choice}" for idx, choice in enumerate(state.choices)]
270
- return state.description, choices, "\n".join(self.game_log)
271
 
272
- def start_game():
273
- game_session = GameSession()
274
  description, choices, game_log = game_session.get_current_state_info()
275
  return description, choices, game_log, game_session
276
 
@@ -279,11 +273,56 @@ def make_choice(choice, game_session):
279
  description, choices, game_log = game_session.get_current_state_info()
280
  return description, choices, "Please select a choice before proceeding.", game_session
281
 
282
- choice_index = game_session.get_current_state_info()[1].index(choice)
283
  result = game_session.make_choice(choice_index)
284
 
285
  return result[0], gr.update(choices=result[1]), result[2], game_session
286
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
287
  initgameinfo = start_game()
288
 
289
 
@@ -368,26 +407,28 @@ with gr.Blocks() as demo:
368
  gr.HTML("Some Kinds of game skeletons ideas - Timelines, Graph as State machine paths, Economy ecosystem")
369
  gr.HTML("One prompt to be used to test models - <br>Please make 10 python lists for the types of media files and their purposes in a game and then use those lists to random generate a timeline of 20 items when the function is called <br>Great next suggest ways to improve this function to create better timelines")
370
  with gr.Tab("Generate Timeline"):
371
- gr.HTML("Placeholder")
372
- gr.Markdown("# Story and Timeline Generator")
373
- gr.Markdown("Click the button to generate a random timeline and story based on UI elements and story events.")
374
-
375
- with gr.Row():
376
- timeline_output = gr.Textbox(label="Timeline", lines=20)
377
- story_output = gr.Textbox(label="Generated Story", lines=20)
378
-
379
- generate_button = gr.Button("Generate Story and Timeline")
380
- generate_button.click(generate_story_and_timeline, inputs=[], outputs=[timeline_output, story_output])
381
- with gr.Tab("Test Example State Machine"):
382
- gr.HTML("Placeholder")
 
383
  with gr.Row():
384
  with gr.Column(scale=2):
385
  gr.Markdown("# Text-based Adventure Game")
 
386
  description = gr.Textbox(label="Current Situation", lines=4, value=initgameinfo[0])
387
  choices = gr.Radio(label="Your Choices", choices=initgameinfo[1])
388
  submit_btn = gr.Button("Make Choice")
389
  game_log = gr.Textbox(label="Game Log", lines=20, value=initgameinfo[2])
390
- game_session = gr.State(value=initgameinfo[3])
391
  submit_btn.click(
392
  make_choice,
393
  inputs=[choices, game_session],
@@ -395,10 +436,16 @@ with gr.Blocks() as demo:
395
  )
396
  with gr.Column(scale=1):
397
  gr.Markdown("# Debugging")
398
- gr.Textbox(label="Path Errors", lines=4, value=path_errors)
399
  with gr.Accordion("Config (Game Spoiler)", open=False):
400
- custom_config = gr.Textbox(label="", value=all_states, lines=8)
401
- custom_configbtn = gr.Button("Load a new config")
 
 
 
 
 
 
402
 
403
 
404
  with gr.Tab("Asset Generation"):
@@ -415,6 +462,7 @@ with gr.Blocks() as demo:
415
  gr.HTML("Images Generation Portraits = https://huggingface.co/spaces/okaris/omni-zero")
416
  gr.HTML("Images Generation General = https://huggingface.co/spaces/stabilityai/stable-diffusion-3-medium, https://huggingface.co/spaces/PixArt-alpha/PixArt-Sigma, https://huggingface.co/spaces/stabilityai/stable-diffusion, https://www.craiyon.com/, https://huggingface.co/spaces/prodia/sdxl-stable-diffusion-xl")
417
  gr.HTML("Images Generation Posters with text - https://huggingface.co/spaces/GlyphByT5/Glyph-SDXL-v2")
 
418
  gr.HTML("SVG Generation = Coding models - ")
419
  gr.HTML("Placeholder for huggingface spaces that can assist <br> https://huggingface.co/spaces/gokaygokay/Florence-2 <br>")
420
  gr.HTML("Placeholder for models small enough to run on cpu here in this space that can assist")
 
1
  import gradio as gr
2
  import random
3
+ import json
4
 
5
  # Default configuration template
6
  default_config = {
 
106
 
107
  #-----------------------------------------------------------------------------------------------------------------------------------
108
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
  class Player:
110
  def __init__(self):
111
  self.inventory = []
 
124
  # Define the states
125
  all_states = {
126
  'village': {
127
+ 'start': {
128
+ "description": "You wake up in a small village. You hear a rumor about a lost treasure.",
129
+ "choices": ['explore village', 'gather supplies', 'rest'],
130
+ "transitions": {'explore village': 'village_rumor', 'gather supplies': 'village_supplies', 'rest': 'village_start'},
131
+ "consequences": {
132
  'gather supplies': lambda player: player.add_item('basic supplies')
133
  }
134
+ },
135
+ 'rumor': {
136
+ "description": "You hear more details about the treasure hidden in the ancient ruins nearby.",
137
+ "choices": ['decide to go', 'ignore'],
138
+ "transitions": {'decide to go': 'village_supplies', 'ignore': 'village_start'},
139
+ "consequences": {
140
  'decide to go': lambda player: player.update_knowledge('treasure location')
141
  }
142
+ },
143
+ 'supplies': {
144
+ "description": "You gather supplies for your journey.",
145
+ "choices": ['head to forest', 'stay in village'],
146
+ "transitions": {'head to forest': 'forest_forest', 'stay in village': 'village_start'}
147
+ },
148
  },
149
  'forest': {
150
+ 'forest': {
151
+ "description": "You enter the dense forest, heading towards the ruins.",
152
+ "choices": ['travel further', 'return to village'],
153
+ "transitions": {'travel further': 'ruins_ruins', 'return to village': 'village_start'}
154
+ },
155
  },
156
  'ruins': {
157
+ 'ruins': {
158
+ "description": "You reach the ancient ruins. The entrance is dark and eerie.",
159
+ "choices": ['enter ruins', 'return to forest'],
160
+ "transitions": {'enter ruins': 'ruins_explore', 'return to forest': 'forest_forest'}
161
+ },
162
+ 'explore': {
163
+ "description": "You explore the ruins, encountering traps and puzzles.",
164
+ "choices": ['solve puzzle', 'avoid traps'],
165
+ "transitions": {'solve puzzle': 'ruins_hiddenPassage', 'avoid traps': 'ruins_ruins'}
166
+ },
167
+ 'hiddenPassage': {
168
+ "description": "You solve a challenging puzzle and unlock a hidden passage.",
169
+ "choices": ['enter passage', 'go back'],
170
+ "transitions": {'enter passage': 'ruins_treasureRoom', 'go back': 'ruins_explore'}
171
+ },
172
+ 'treasureRoom': {
173
+ "description": "You enter the treasure room and find the treasure chest.",
174
+ "choices": ['take treasure', 'leave'],
175
+ "transitions": {'take treasure': 'ruins_celebrate', 'leave': 'ruins_ruins'},
176
+ "consequences": {
177
  'take treasure': lambda player: player.add_item('treasure')
178
  }
179
+ },
180
+ 'celebrate': {
181
+ "description": "You celebrate your discovery and decide to bring the treasure back to the village.",
182
+ "choices": ['return to village'],
183
+ "transitions": {'return to village': 'village_return'}
184
+ },
185
  },
186
  'village_return': {
187
+ 'village_return': {
188
+ "description": "You return to the village with the treasure and share it with the villagers.",
189
+ "choices": ['end adventure'],
190
+ "transitions": {'end adventure': 'end_end'}
191
+ },
192
  },
193
  'end': {
194
+ 'end': {
195
+ "description": "Your adventure ends here. The villagers are grateful and everyone's lives improve.",
196
+ "choices": [],
197
+ "transitions": {}
198
+ },
199
  }
200
  }
201
 
 
203
  errors = []
204
  for location, states in all_states.items():
205
  for state_key, state in states.items():
206
+ for transition_key, transition_state in state['transitions'].items():
207
  # Check if the transition is to another location
208
  if transition_state in all_states:
209
  trans_location, trans_state = transition_state, 'start' # Assuming 'start' state for new locations
 
219
  return errors
220
 
221
  path_errors = validate_transitions(all_states)
222
+ if path_errors:
223
+ for error in path_errors:
224
+ print(error)
225
+ else:
226
+ print("All transitions are valid.")
227
 
228
  class GameSession:
229
+ def __init__(self, starting_location='village', starting_state='start'):
230
  self.player = Player()
231
+ self.current_location = starting_location
232
+ self.current_state = starting_state
233
  self.game_log = []
234
 
235
  def make_choice(self, choice_index):
236
  state = all_states[self.current_location][self.current_state]
237
+ if 0 <= choice_index < len(state['choices']):
238
+ choice = state['choices'][choice_index]
239
+ next_state = state['transitions'][choice]
240
 
241
  self.game_log.append(f"You chose: {choice}")
242
+ self.game_log.append(state['description'])
243
 
244
+ if 'consequences' in state and choice in state['consequences']:
245
+ if state['consequences'][choice]:
246
+ state['consequences'][choice](self.player)
247
+ else:
248
+ # Handle empty consequence, e.g., log a message or provide a default action
249
+ print(f"No consequence for choice: {choice}")
250
+ # You can add any default action here if needed
251
 
252
  if '_' in next_state:
253
  self.current_location, self.current_state = next_state.split('_')
 
260
 
261
  def get_current_state_info(self):
262
  state = all_states[self.current_location][self.current_state]
263
+ choices = [f"{idx + 1}. {choice}" for idx, choice in enumerate(state['choices'])]
264
+ return state['description'], choices, "\n".join(self.game_log)
265
 
266
+ def start_game(starting_location='village', starting_state='start'):
267
+ game_session = GameSession(starting_location, starting_state)
268
  description, choices, game_log = game_session.get_current_state_info()
269
  return description, choices, game_log, game_session
270
 
 
273
  description, choices, game_log = game_session.get_current_state_info()
274
  return description, choices, "Please select a choice before proceeding.", game_session
275
 
276
+ choice_index = int(choice.split('.')[0]) - 1
277
  result = game_session.make_choice(choice_index)
278
 
279
  return result[0], gr.update(choices=result[1]), result[2], game_session
280
 
281
+ def load_game(custom_config=None):
282
+ global all_states
283
+ if custom_config:
284
+ try:
285
+ new_config = json.loads(custom_config)
286
+
287
+ all_states = new_config
288
+
289
+ # Determine the starting location and state
290
+ starting_location = next(iter(all_states.keys()))
291
+ starting_state = next(iter(all_states[starting_location].keys()))
292
+
293
+ game_session = GameSession(starting_location, starting_state)
294
+ description, choices, game_log = game_session.get_current_state_info()
295
+ new_path_errors = validate_transitions(all_states)
296
+
297
+ return gr.update(value=f"Custom configuration loaded successfully! \n{new_path_errors}"), game_log, description, gr.update(choices=choices), game_session, gr.update(value=custom_config)
298
+ except json.JSONDecodeError as e:
299
+ # Get the line number and column of the error
300
+ lineno, colno = e.lineno, e.colno
301
+
302
+ # Get the problematic line
303
+ lines = custom_config.split('\n')
304
+ error_line = lines[lineno - 1] if lineno <= len(lines) else ""
305
+
306
+ # Create a pointer to the error location
307
+ pointer = ' ' * (colno - 1) + '^'
308
+
309
+ error_message = f"Invalid JSON format in custom configuration:\n"
310
+ error_message += f"Error at line {lineno}, column {colno}:\n"
311
+ error_message += f"{error_line}\n"
312
+ error_message += f"{pointer}\n"
313
+ error_message += f"Error details: {str(e)}"
314
+
315
+ return gr.update(value=error_message), gr.update(), gr.update(), None, gr.update(value=custom_config)
316
+ except Exception as e:
317
+ return gr.update(value=f"Error loading custom configuration: {str(e)}"), gr.update(), gr.update(), None, gr.update(value=custom_config)
318
+
319
+ # If no custom config, start with the default configuration
320
+ starting_location = next(iter(all_states.keys()))
321
+ starting_state = next(iter(all_states[starting_location].keys()))
322
+ game_session = GameSession(starting_location, starting_state)
323
+ description, choices, game_log = game_session.get_current_state_info()
324
+ return description, gr.update(choices=choices), game_log, game_session, gr.update()
325
+
326
  initgameinfo = start_game()
327
 
328
 
 
407
  gr.HTML("Some Kinds of game skeletons ideas - Timelines, Graph as State machine paths, Economy ecosystem")
408
  gr.HTML("One prompt to be used to test models - <br>Please make 10 python lists for the types of media files and their purposes in a game and then use those lists to random generate a timeline of 20 items when the function is called <br>Great next suggest ways to improve this function to create better timelines")
409
  with gr.Tab("Generate Timeline"):
410
+ with gr.Tab("Without Asset generation consideration"):
411
+ gr.Markdown("# Story and Timeline Generator")
412
+ gr.Markdown("Click the button to generate a random timeline and story based on UI elements and story events.")
413
+
414
+ with gr.Row():
415
+ timeline_output = gr.Textbox(label="Timeline", lines=20)
416
+ story_output = gr.Textbox(label="Generated Story", lines=20)
417
+
418
+ generate_button = gr.Button("Generate Story and Timeline")
419
+ generate_button.click(generate_story_and_timeline, inputs=[], outputs=[timeline_output, story_output])
420
+ with gr.Tab("Asset generation considered"):
421
+ gr.HTML("placeholder")
422
+ with gr.Tab("Test Example State Machine"):
423
  with gr.Row():
424
  with gr.Column(scale=2):
425
  gr.Markdown("# Text-based Adventure Game")
426
+
427
  description = gr.Textbox(label="Current Situation", lines=4, value=initgameinfo[0])
428
  choices = gr.Radio(label="Your Choices", choices=initgameinfo[1])
429
  submit_btn = gr.Button("Make Choice")
430
  game_log = gr.Textbox(label="Game Log", lines=20, value=initgameinfo[2])
431
+ game_session = gr.State(value=initgameinfo[3])
432
  submit_btn.click(
433
  make_choice,
434
  inputs=[choices, game_session],
 
436
  )
437
  with gr.Column(scale=1):
438
  gr.Markdown("# Debugging")
439
+ error_box = gr.Textbox(label="Path Errors", lines=4, value=path_errors)
440
  with gr.Accordion("Config (Game Spoiler)", open=False):
441
+ custom_config = gr.Textbox(label="Custom Configuration (JSON)", value=json.dumps(all_states, default=lambda o: o.__dict__, indent=2), lines=8)
442
+ custom_configbtn = gr.Button("Load Custom Config")
443
+
444
+ custom_configbtn.click(
445
+ load_game,
446
+ inputs=[custom_config],
447
+ outputs=[error_box, game_log, description, choices, game_session, custom_config]
448
+ )
449
 
450
 
451
  with gr.Tab("Asset Generation"):
 
462
  gr.HTML("Images Generation Portraits = https://huggingface.co/spaces/okaris/omni-zero")
463
  gr.HTML("Images Generation General = https://huggingface.co/spaces/stabilityai/stable-diffusion-3-medium, https://huggingface.co/spaces/PixArt-alpha/PixArt-Sigma, https://huggingface.co/spaces/stabilityai/stable-diffusion, https://www.craiyon.com/, https://huggingface.co/spaces/prodia/sdxl-stable-diffusion-xl")
464
  gr.HTML("Images Generation Posters with text - https://huggingface.co/spaces/GlyphByT5/Glyph-SDXL-v2")
465
+ gr.HTML("Images Generation Very Specific position and shape - https://huggingface.co/spaces/linoyts/scribble-sdxl-flash")
466
  gr.HTML("SVG Generation = Coding models - ")
467
  gr.HTML("Placeholder for huggingface spaces that can assist <br> https://huggingface.co/spaces/gokaygokay/Florence-2 <br>")
468
  gr.HTML("Placeholder for models small enough to run on cpu here in this space that can assist")