How to Build Your Own GridMind Client
Every team builds their own client — there's no shared default. The
PYNQ_302-Referee_Match_Client notebook is a working reference implementation,
not something everyone just runs as-is: start from it, extend it, or ignore it entirely and
write your own from scratch in whatever language you like. This page is the part every
team needs, regardless of approach — not an edge case for teams doing something unusual.
There are three layers to a working client, in order of how load-bearing they are:
pynqp2p library's four functions: register(ip, key)
(once, at startup), get_id() (your board's MAC address, used as your
team's identity), send(id, message) (POST a JSON string to a
recipient), and receive_all() (GET every message currently queued
for you, as a list of raw JSON strings). Whatever language or library you use instead,
you're talking to the same relay-server HTTP endpoints (/send, /receive_all)
one way or another — this layer is mandatory for any client to function at all.
pynqp2p or the reference notebook. Any client, in any
language, must produce and consume these exact message shapes to play a match.
pynqsim.SimulationClient's join_competition(team_id) /
flip_card(row, col) / end_turn() mirror
your flips onto a simulated robot arm for spectators. Purely visual — it never affects
scoring and is safe to skip entirely.
The flow below covers layer 2, the part that's actually mandatory. Function names shown
(flip_both, report_result, request_hint)
are the reference notebook's own helper methods around pynqp2p.send()
— if you're writing your own client, send the same wire messages however your code is
structured; the names don't have to match.
pregame_riddle
— no response expected; solving it is entirely up to your team (the reference
notebook auto-solves it with an LLM, but that's optional)free_hint_fragment × N
— assemble these yourself as they arrive; complete once every index from
0 to total - 1 has been seengame_start
— requires your client to have already sent a join message to
the master's lobby (via pynqp2p.send()) before this arrives, so the
operator can confirm your boardActive Team
your_turnflip_both (team, pos1, pos2)
— the two grid positions your vision system chose to flip. Valid only as the
first action of a turn — sending it after you've already flipped once this
turn is a protocol error.card_revealed × 2hint_request (team, object)
— resolves immediately, but the request takes time off your own turn clockreport_result (team, pos1, pos2,
cls1, cls2, claim) — your model's classification of both cards and whether you're
claiming a matchmatch (streak continues,
back to top) or no_match (turn ends)your_turn again (streak) or
wait (turn passed)Waiting Team
waitcard_revealed
× 2 from the active team's flips — your client should log these to its own
memory even though it's not your turnhint_request now
— queued server-side, resolves via
hint_response/hint_rejected the instant
your turn starts, before your clock beginsyour_turn when the active
team's turn endsgame_over
— final scores, no further messages expected