Spaces:
Running
Running
Fixed drop down options for human
Browse files
app.py
CHANGED
@@ -597,6 +597,8 @@ with gr.Blocks() as interface:
|
|
597 |
|
598 |
# Create gr.State for interactive games
|
599 |
game_state = gr.State(value=None)
|
|
|
|
|
600 |
|
601 |
# Interactive game components (initially hidden)
|
602 |
with gr.Column(visible=False) as interactive_panel:
|
@@ -616,22 +618,22 @@ with gr.Blocks() as interface:
|
|
616 |
gr.Markdown("### Your Move")
|
617 |
|
618 |
# Player 0 move selection
|
619 |
-
|
620 |
choices=[],
|
621 |
-
label="Player 0
|
622 |
visible=False,
|
623 |
interactive=True,
|
624 |
)
|
625 |
|
626 |
# Player 1 move selection
|
627 |
-
|
628 |
choices=[],
|
629 |
-
label="Player 1
|
630 |
visible=False,
|
631 |
interactive=True,
|
632 |
)
|
633 |
|
634 |
-
|
635 |
"Submit Move",
|
636 |
variant="primary",
|
637 |
visible=False
|
@@ -644,7 +646,7 @@ with gr.Blocks() as interface:
|
|
644 |
|
645 |
# Standard game simulation (non-interactive)
|
646 |
play_button = gr.Button("🎮 Start Game", variant="primary")
|
647 |
-
|
648 |
|
649 |
game_output = gr.Textbox(
|
650 |
label="Game Log",
|
@@ -662,7 +664,7 @@ with gr.Blocks() as interface:
|
|
662 |
has_human = (p1_key == "human" or p2_key == "human")
|
663 |
return (
|
664 |
gr.update(visible=has_human), # interactive_panel
|
665 |
-
gr.update(visible=has_human), #
|
666 |
gr.update(visible=not has_human), # play_button (single-shot)
|
667 |
)
|
668 |
|
@@ -671,7 +673,7 @@ with gr.Blocks() as interface:
|
|
671 |
player_type_dropdown.change(
|
672 |
check_for_human_players,
|
673 |
inputs=[p1_type, p2_type],
|
674 |
-
outputs=[interactive_panel,
|
675 |
)
|
676 |
|
677 |
# Standard single-shot game
|
@@ -716,87 +718,121 @@ with gr.Blocks() as interface:
|
|
716 |
player2_model=p2_model,
|
717 |
rounds=rounds,
|
718 |
seed=seed,
|
719 |
-
)
|
720 |
-
|
721 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
722 |
|
723 |
return (
|
724 |
state, # game_state
|
|
|
|
|
725 |
log, # board_display
|
726 |
-
gr.update(choices=
|
727 |
-
gr.update(choices=
|
728 |
-
gr.update(visible=True), #
|
729 |
gr.update(visible=True), # reset_game_btn
|
730 |
)
|
731 |
except Exception as e:
|
732 |
return (
|
733 |
None, # game_state
|
|
|
|
|
734 |
f"Error starting interactive game: {e}", # board_display
|
735 |
-
gr.update(choices=[], visible=False), #
|
736 |
-
gr.update(choices=[], visible=False), #
|
737 |
-
gr.update(visible=False), #
|
738 |
gr.update(visible=False), # reset_game_btn
|
739 |
)
|
740 |
|
741 |
-
def submit_human_move_handler(p0_action, p1_action, state):
|
742 |
"""Process human moves and advance the game."""
|
743 |
try:
|
744 |
from ui.gradio_config_generator import submit_human_move
|
745 |
|
746 |
if not state:
|
747 |
-
return
|
|
|
|
|
|
|
|
|
|
|
|
|
748 |
|
|
|
749 |
log_append, new_state, next_p0, next_p1 = submit_human_move(
|
750 |
action_p0=p0_action,
|
751 |
action_p1=p1_action,
|
752 |
state=state,
|
753 |
)
|
754 |
|
755 |
-
#
|
756 |
-
|
757 |
-
|
|
|
|
|
|
|
|
|
758 |
|
759 |
-
# Check if game is finished
|
760 |
-
game_over = new_state.get("terminated", False) or
|
|
|
|
|
761 |
|
762 |
return (
|
763 |
new_state, # game_state
|
|
|
|
|
764 |
log_append, # board_display (append to current)
|
765 |
-
gr.update(choices=
|
766 |
-
gr.update(choices=
|
767 |
-
gr.update(visible=not game_over), #
|
768 |
gr.update(visible=True), # reset_game_btn (always visible to restart)
|
769 |
)
|
770 |
except Exception as e:
|
771 |
-
return
|
|
|
|
|
|
|
772 |
|
773 |
def reset_interactive_game():
|
774 |
"""Reset the interactive game state."""
|
775 |
return (
|
776 |
None, # game_state
|
|
|
|
|
777 |
"Game reset. Click 'Start Interactive Game' to begin a new game.", # board_display
|
778 |
-
gr.update(choices=[], visible=False), #
|
779 |
-
gr.update(choices=[], visible=False), #
|
780 |
-
gr.update(visible=False), #
|
781 |
gr.update(visible=False), # reset_game_btn
|
782 |
)
|
783 |
|
784 |
# Wire up interactive game handlers
|
785 |
-
|
786 |
start_interactive_game,
|
787 |
inputs=[game_dropdown, p1_type, p2_type, p1_model, p2_model, rounds_slider],
|
788 |
-
outputs=[game_state, board_display,
|
789 |
)
|
790 |
|
791 |
-
|
792 |
submit_human_move_handler,
|
793 |
-
inputs=[
|
794 |
-
outputs=[game_state, board_display,
|
795 |
)
|
796 |
|
797 |
reset_game_btn.click(
|
798 |
reset_interactive_game,
|
799 |
-
outputs=[game_state, board_display,
|
800 |
)
|
801 |
|
802 |
with gr.Tab("Leaderboard"):
|
|
|
597 |
|
598 |
# Create gr.State for interactive games
|
599 |
game_state = gr.State(value=None)
|
600 |
+
human_choices_p0 = gr.State([])
|
601 |
+
human_choices_p1 = gr.State([])
|
602 |
|
603 |
# Interactive game components (initially hidden)
|
604 |
with gr.Column(visible=False) as interactive_panel:
|
|
|
618 |
gr.Markdown("### Your Move")
|
619 |
|
620 |
# Player 0 move selection
|
621 |
+
human_move_p0 = gr.Dropdown(
|
622 |
choices=[],
|
623 |
+
label="Your move (Player 0)",
|
624 |
visible=False,
|
625 |
interactive=True,
|
626 |
)
|
627 |
|
628 |
# Player 1 move selection
|
629 |
+
human_move_p1 = gr.Dropdown(
|
630 |
choices=[],
|
631 |
+
label="Your move (Player 1)",
|
632 |
visible=False,
|
633 |
interactive=True,
|
634 |
)
|
635 |
|
636 |
+
submit_btn = gr.Button(
|
637 |
"Submit Move",
|
638 |
variant="primary",
|
639 |
visible=False
|
|
|
646 |
|
647 |
# Standard game simulation (non-interactive)
|
648 |
play_button = gr.Button("🎮 Start Game", variant="primary")
|
649 |
+
start_btn = gr.Button("🎯 Start Interactive Game", variant="secondary", visible=False)
|
650 |
|
651 |
game_output = gr.Textbox(
|
652 |
label="Game Log",
|
|
|
664 |
has_human = (p1_key == "human" or p2_key == "human")
|
665 |
return (
|
666 |
gr.update(visible=has_human), # interactive_panel
|
667 |
+
gr.update(visible=has_human), # start_btn
|
668 |
gr.update(visible=not has_human), # play_button (single-shot)
|
669 |
)
|
670 |
|
|
|
673 |
player_type_dropdown.change(
|
674 |
check_for_human_players,
|
675 |
inputs=[p1_type, p2_type],
|
676 |
+
outputs=[interactive_panel, start_btn, play_button],
|
677 |
)
|
678 |
|
679 |
# Standard single-shot game
|
|
|
718 |
player2_model=p2_model,
|
719 |
rounds=rounds,
|
720 |
seed=seed,
|
721 |
+
)
|
722 |
+
|
723 |
+
# Store choices in state for reliable mapping
|
724 |
+
p0_choices = legal_p0 # [(action_id, label), ...]
|
725 |
+
p1_choices = legal_p1 # [(action_id, label), ...]
|
726 |
+
|
727 |
+
# For Gradio dropdowns: use (label, value) pairs so user sees labels but selects action IDs
|
728 |
+
p0_dropdown_choices = [(label, action_id) for action_id, label in p0_choices]
|
729 |
+
p1_dropdown_choices = [(label, action_id) for action_id, label in p1_choices]
|
730 |
+
|
731 |
+
# Show/hide dropdowns based on whether each player is human
|
732 |
+
p0_is_human = (p1_key == "human")
|
733 |
+
p1_is_human = (p2_key == "human")
|
734 |
|
735 |
return (
|
736 |
state, # game_state
|
737 |
+
p0_choices, # human_choices_p0
|
738 |
+
p1_choices, # human_choices_p1
|
739 |
log, # board_display
|
740 |
+
gr.update(choices=p0_dropdown_choices, visible=p0_is_human, value=None), # human_move_p0
|
741 |
+
gr.update(choices=p1_dropdown_choices, visible=p1_is_human, value=None), # human_move_p1
|
742 |
+
gr.update(visible=True), # submit_btn
|
743 |
gr.update(visible=True), # reset_game_btn
|
744 |
)
|
745 |
except Exception as e:
|
746 |
return (
|
747 |
None, # game_state
|
748 |
+
[], # human_choices_p0
|
749 |
+
[], # human_choices_p1
|
750 |
f"Error starting interactive game: {e}", # board_display
|
751 |
+
gr.update(choices=[], visible=False), # human_move_p0
|
752 |
+
gr.update(choices=[], visible=False), # human_move_p1
|
753 |
+
gr.update(visible=False), # submit_btn
|
754 |
gr.update(visible=False), # reset_game_btn
|
755 |
)
|
756 |
|
757 |
+
def submit_human_move_handler(p0_action, p1_action, state, choices_p0, choices_p1):
|
758 |
"""Process human moves and advance the game."""
|
759 |
try:
|
760 |
from ui.gradio_config_generator import submit_human_move
|
761 |
|
762 |
if not state:
|
763 |
+
return (
|
764 |
+
state, [], [], "No game running.",
|
765 |
+
gr.update(choices=[], visible=False),
|
766 |
+
gr.update(choices=[], visible=False),
|
767 |
+
gr.update(visible=False),
|
768 |
+
gr.update(visible=False)
|
769 |
+
)
|
770 |
|
771 |
+
# p0_action and p1_action are now directly the integer action IDs from dropdown
|
772 |
log_append, new_state, next_p0, next_p1 = submit_human_move(
|
773 |
action_p0=p0_action,
|
774 |
action_p1=p1_action,
|
775 |
state=state,
|
776 |
)
|
777 |
|
778 |
+
# Store new choices in state
|
779 |
+
new_choices_p0 = next_p0 # [(action_id, label), ...]
|
780 |
+
new_choices_p1 = next_p1 # [(action_id, label), ...]
|
781 |
+
|
782 |
+
# Convert to Gradio dropdown format: (label, value) pairs
|
783 |
+
p0_dropdown_choices = [(label, action_id) for action_id, label in new_choices_p0]
|
784 |
+
p1_dropdown_choices = [(label, action_id) for action_id, label in new_choices_p1]
|
785 |
|
786 |
+
# Check if game is finished (no more legal actions)
|
787 |
+
game_over = (new_state.get("terminated", False) or
|
788 |
+
new_state.get("truncated", False) or
|
789 |
+
(len(new_choices_p0) == 0 and len(new_choices_p1) == 0))
|
790 |
|
791 |
return (
|
792 |
new_state, # game_state
|
793 |
+
new_choices_p0, # human_choices_p0
|
794 |
+
new_choices_p1, # human_choices_p1
|
795 |
log_append, # board_display (append to current)
|
796 |
+
gr.update(choices=p0_dropdown_choices, visible=len(p0_dropdown_choices) > 0 and not game_over, value=None), # human_move_p0
|
797 |
+
gr.update(choices=p1_dropdown_choices, visible=len(p1_dropdown_choices) > 0 and not game_over, value=None), # human_move_p1
|
798 |
+
gr.update(visible=not game_over), # submit_btn
|
799 |
gr.update(visible=True), # reset_game_btn (always visible to restart)
|
800 |
)
|
801 |
except Exception as e:
|
802 |
+
return (
|
803 |
+
state, choices_p0, choices_p1, f"Error processing move: {e}",
|
804 |
+
gr.update(), gr.update(), gr.update(), gr.update()
|
805 |
+
)
|
806 |
|
807 |
def reset_interactive_game():
|
808 |
"""Reset the interactive game state."""
|
809 |
return (
|
810 |
None, # game_state
|
811 |
+
[], # human_choices_p0
|
812 |
+
[], # human_choices_p1
|
813 |
"Game reset. Click 'Start Interactive Game' to begin a new game.", # board_display
|
814 |
+
gr.update(choices=[], visible=False), # human_move_p0
|
815 |
+
gr.update(choices=[], visible=False), # human_move_p1
|
816 |
+
gr.update(visible=False), # submit_btn
|
817 |
gr.update(visible=False), # reset_game_btn
|
818 |
)
|
819 |
|
820 |
# Wire up interactive game handlers
|
821 |
+
start_btn.click(
|
822 |
start_interactive_game,
|
823 |
inputs=[game_dropdown, p1_type, p2_type, p1_model, p2_model, rounds_slider],
|
824 |
+
outputs=[game_state, human_choices_p0, human_choices_p1, board_display, human_move_p0, human_move_p1, submit_btn, reset_game_btn],
|
825 |
)
|
826 |
|
827 |
+
submit_btn.click(
|
828 |
submit_human_move_handler,
|
829 |
+
inputs=[human_move_p0, human_move_p1, game_state, human_choices_p0, human_choices_p1],
|
830 |
+
outputs=[game_state, human_choices_p0, human_choices_p1, board_display, human_move_p0, human_move_p1, submit_btn, reset_game_btn],
|
831 |
)
|
832 |
|
833 |
reset_game_btn.click(
|
834 |
reset_interactive_game,
|
835 |
+
outputs=[game_state, human_choices_p0, human_choices_p1, board_display, human_move_p0, human_move_p1, submit_btn, reset_game_btn],
|
836 |
)
|
837 |
|
838 |
with gr.Tab("Leaderboard"):
|