quarto_gen/quarto/client/protocol.py
2026-02-13 21:25:05 +01:00

82 lines
1.9 KiB
Python

from __future__ import annotations
from dataclasses import dataclass
from typing import Optional, Union
@dataclass
class HelloServer:
description: str
@dataclass
class NewGame:
player1: str
player2: str
@dataclass
class MoveBroadcast:
square: Optional[int]
value: int # piece index or 16/17
@dataclass
class GameOver:
reason: str # "VICTORY" | "DRAW" | "DISCONNECT"
winner: Optional[str]
@dataclass
class UnknownCommand:
raw: str
ServerMessage = Union[HelloServer, NewGame, MoveBroadcast, GameOver, UnknownCommand]
def parse_server_line(line: str) -> ServerMessage:
parts = line.strip().split("~")
if not parts:
return UnknownCommand(raw=line)
cmd = parts[0]
if cmd == "HELLO" and len(parts) == 2:
return HelloServer(description=parts[1])
if cmd == "NEWGAME" and len(parts) == 3:
return NewGame(player1=parts[1], player2=parts[2])
if cmd == "MOVE":
if len(parts) == 2:
try:
value = int(parts[1])
except ValueError:
return UnknownCommand(raw=line)
return MoveBroadcast(square=None, value=value)
if len(parts) == 3:
try:
square = int(parts[1])
value = int(parts[2])
except ValueError:
return UnknownCommand(raw=line)
return MoveBroadcast(square=square, value=value)
if cmd == "GAMEOVER":
if len(parts) == 2:
return GameOver(reason=parts[1], winner=None)
if len(parts) == 3:
return GameOver(reason=parts[1], winner=parts[2])
return UnknownCommand(raw=line)
def format_hello(description: str) -> str:
return f"HELLO~{description}"
def format_queue() -> str:
return "QUEUE"
def format_move_initial(piece: int) -> str:
return f"MOVE~{piece}"
def format_move_normal(square: int, m_value: int) -> str:
return f"MOVE~{square}~{m_value}"