| import gradio as gr | |
| import numpy as np | |
| ENFORCE_RULES = False | |
| MAX_EVENTS = 10 | |
| board_state = np.full((3, 3), "") | |
| turn_state = ["X", 0] | |
| event_log = [] | |
| def place(evt: gr.SelectData, gr_request: gr.Request): | |
| if evt.value: | |
| return board_state, "\n".join(event_log) | |
| client_id = hash(gr_request.client.host[0]) | |
| if ENFORCE_RULES and client_id == turn_state[1]: | |
| return board_state, update_events("may not move twice in a row") | |
| turn_state[1] = client_id | |
| row, column = evt.index | |
| board_state[row, column] = turn_state[0] | |
| if (board_state[row,:] == turn_state[0]).all() or (board_state[:,column] == turn_state[0]).all(): | |
| return board_state, update_events("has won!!!!") | |
| turn_state[0] = "O" if turn_state[0] == "X" else "X" | |
| return board_state, update_events("made the last move") | |
| def reset(gr_request: gr.Request): | |
| board_state.fill("") | |
| turn_state[0] = "X" | |
| turn_state[1] = hash(gr_request.client.host[0]) | |
| return board_state, update_events("has reset the board state") | |
| def update_events(message=None): | |
| if message: | |
| event_log.append(f"player {turn_state[1] % 10000} {message}, {turn_state[0]} moves next") | |
| if len(event_log) > MAX_EVENTS: | |
| event_log.pop(0) | |
| return "\n".join(event_log) | |
| def refresh_display(): | |
| return board_state, "\n".join(event_log) | |
| with gr.Blocks(analytics_enabled=False) as demo: | |
| events = gr.Textbox(interactive=False, label="Turn") | |
| board = gr.Dataframe(interactive=False, type="array") | |
| board.select(place, [], [board, events]) | |
| reset_button = gr.Button(value="Reset Board") | |
| reset_button.click(reset, [], [board, events]) | |
| demo.load(refresh_display, [], [board, events], every=10, show_progress=False) | |
| demo.queue() | |
| demo.launch() |