WebSocket JSON Protocol
Endpoints
- Game:
/ws - Debug:
/ws/debug
The frontend picks minimax vs alphazero by settings.ai and connects to one of:
- Local:
ws://localhost:{PORT}/ws - Production:
wss://sungyongcho.com/minimax/wsorwss://sungyongcho.com/alphazero/ws
Compatibility Notes
The protocol is frontend-compatible across minimax and AlphaZero, but not byte-identical between backends.
- Shared core request fields (both backends):
type,nextPlayer,board,scores. evaluaterequests requirelastPlay.coordinate(for both backends).- Minimax requires
difficultyformove/test. - AlphaZero currently ignores
difficulty,goal,enableCapture, andenableDoubleThreeRestrictionin request payloads. moveresponse shape differs by backend: AlphaZero includesscoresandevalScores; minimax omits both.
Request Messages
1) move, evaluate, test
The frontend sends one common superset payload shape:
{
"type": "move",
"difficulty": "easy | medium | hard",
// minimax: required for move/test
// alphazero: currently ignored
"nextPlayer": "X | O",
"goal": 5,
// currently ignored by alphazero server
"enableCapture": true,
// currently ignored by alphazero server
"enableDoubleThreeRestriction": true,
"lastPlay": {
"coordinate": { "x": 9, "y": 10 },
"stone": "X"
},
// `lastPlay.coordinate` is required for `evaluate`.
"board": [[".", ".", "..."]],
// Full board state is sent every request (board-state stateless handling; minimax TT/difficulty are per-connection state).
"scores": [
{ "player": "X", "score": 3 },
{ "player": "O", "score": 1 }
],
// `scores` is capture score by player (used by both backends).
// `test` is used by `front/pages/test.vue` (minimax-focused check path).
}
jsonlastPlay semantics differ by request type:
move:lastPlayis the actual last move played. It can be omitted for the first AI move request.evaluate:lastPlay.coordinateis required and specifies the position to evaluate (not the actual last move played).- Frontend behavior: right-click
evaluateis enabled only inminimaxmode; it is disabled inalphazeromode. test: same semantics asmove.
test note: in the minimax backend, difficulty is currently ignored and the handler always uses the hard PVS path.
2) reset
{ "type": "reset" }
jsonResponse Messages
1) move (also used for test)
{
"type": "move",
"status": "success",
"lastPlay": {
"coordinate": { "x": 9, "y": 10 },
"stone": "O"
},
"board": [[".", ".", "..."]],
"capturedStones": [
{ "x": 1, "y": 1, "stone": "X" }
],
"executionTime": { "s": 0.12, "ms": 120.0, "ns": 120000000 },
// Optional by backend: `scores`, `evalScores`
}
jsonlastPlay.stone is the stone that was just placed for this move (not the next player to move).
For move/test responses: AlphaZero includes scores and evalScores; minimax omits both fields.
2) evaluate
{
"type": "evaluate",
"evalScores": [
// NOTE: the inner field shares the name "evalScores" with the outer array — a naming quirk retained for backward compatibility.
{ "player": "O", "evalScores": 0.13, "percentage": 43.5 },
{ "player": "X", "evalScores": -0.13, "percentage": 56.5 }
],
// Frontend mainly uses `player` + `percentage`.
}
jsonevalScores type differs by backend:
- Minimax: raw integer heuristic score.
- AlphaZero: model value as a float.
percentage is a normalized 0-100 evaluation intended for cross-backend UI display (frontend primarily uses this field).
3) error
{
"type": "error",
"error": "Unknown type"
}
json