import gradio as gr import formatters from game_manager import games, new_game with gr.Blocks(css="style.css") as app: started = gr.Variable(False) player = gr.Variable() last_update = gr.Variable(0) with gr.Column() as opening: gr.Markdown("# Crossword GPT") gr.Markdown( """ Welcome to Crossword GPT, a game that dynamically creates a crossword and uses GPT to create clues. - At the start of the game, a crossword puzzle will be created, with single word already solved. - At any time, a riddle with three clues will be shown, corresponding to three words that branch off the solved part of the puzzle. Riddles are regenerated every 30 seconds if not solved. - You can play against friends, in which case enter a shared room name below. To play alone, leave the fields blank and start the game. - Game ends when there is no more space to add words. Winner in competitive mode is the player with the most words. """ ) room_name = gr.Text(label="Room Name") player_name = gr.Text(label="Player Name") start_btn = gr.Button("Let's Go!") with gr.Column(visible=False) as game_col: with gr.Row(): with gr.Column(min_width=500): grid = gr.HTML() score_table = gr.DataFrame(headers=["team", "score"], label="Scores") with gr.Column(): clue1 = gr.Textbox(label="Clue 1", elem_id="clue-1") clue2 = gr.Textbox(label="Clue 2", elem_id="clue-2") clue3 = gr.Textbox(label="Clue 3", elem_id="clue-3") guess = gr.Textbox( label="Guess", placeholder="Answer any clue here...", elem_id="guess", ) guess_btn = gr.Button("Guess") def start_game(data): game = new_game(data[room_name]) game.add_player(data[player_name]) return { game_col: gr.update(visible=True), opening: gr.update(visible=False), room_name: game.room_name, player: data[player_name], } start_btn.click( start_game, {room_name, player_name}, [game_col, opening, player, room_name], ) def submit_guess(data): game = games[data[room_name]] game.player_guess(data[player], data[guess]) guess.submit(submit_guess, {room_name, player, guess}, None) guess.submit( None, None, None, _js="""() => {document.querySelector("gradio-app").querySelector("#guess textarea").setSelectionRange(0, 9999)}""", status_tracker=None, ) guess_btn.click(submit_guess, {room_name, player, guess}, None) guess_btn.click( None, None, None, _js="""() => {document.querySelector("gradio-app").querySelector("#guess textarea").setSelectionRange(0, 9999)}""", status_tracker=None, ) def update_game(data): if data[room_name] is None or data[room_name] not in games: return {grid: gr.skip()} game = games[data[room_name]] no_up = data[last_update] == game.last_update_index return { grid: gr.skip() if no_up else formatters.crossword(game.grid, game.clues), score_table: [[k, v] for k, v in game.player_scores.items()], clue1: formatters.clue_riddle(game.clues[0]), clue2: formatters.clue_riddle(game.clues[1]), clue3: formatters.clue_riddle(game.clues[2]), } start_btn.click( update_game, {room_name, last_update}, [grid, clue1, clue2, clue3, score_table], every=1, ) app.queue().launch()