feat(snake): optimize duels and persist customizations
Build and Push Docker Container / build-and-push (push) Successful in 7m29s
Build and Push Docker Container / build-and-push (push) Successful in 7m29s
- Add deadline-aware iterative duel search with bitboards and tuple bodies. - Reuse transposition bounds and move-order hints across search depths. - Persist snake colors, heads, and tails in SQLite and PostgreSQL. - Restore customization metadata when hydrating dashboard replays. - Cover duel deadlines, cache reuse, schema storage, and replay output.
This commit is contained in:
@@ -76,6 +76,7 @@ CREATE TABLE IF NOT EXISTS game_snakes (
|
||||
snake_id TEXT NOT NULL,
|
||||
snake_name TEXT,
|
||||
is_you BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
customizations JSONB NOT NULL DEFAULT '{}'::jsonb,
|
||||
PRIMARY KEY (game_id, snake_id)
|
||||
);
|
||||
|
||||
@@ -114,6 +115,7 @@ ALTER TABLE games ADD COLUMN IF NOT EXISTS quality_tier TEXT;
|
||||
ALTER TABLE games ADD COLUMN IF NOT EXISTS quality_reasons JSONB;
|
||||
ALTER TABLE turns ADD COLUMN IF NOT EXISTS my_thinking JSONB;
|
||||
ALTER TABLE snake_turns ADD COLUMN IF NOT EXISTS latency TEXT;
|
||||
ALTER TABLE game_snakes ADD COLUMN IF NOT EXISTS customizations JSONB NOT NULL DEFAULT '{}'::jsonb;
|
||||
"""
|
||||
|
||||
# Force TOAST compression on the large JSONB columns so that even
|
||||
@@ -458,14 +460,22 @@ class PostgresqlGameplayBackend(GameplayBackendTemplate):
|
||||
async with pool.acquire() as conn:
|
||||
async with conn.transaction():
|
||||
await conn.executemany("""
|
||||
INSERT INTO game_snakes (game_id, snake_id, snake_name, is_you)
|
||||
VALUES ($1,$2,$3,$4)
|
||||
INSERT INTO game_snakes (
|
||||
game_id, snake_id, snake_name, is_you, customizations
|
||||
) VALUES ($1,$2,$3,$4,$5)
|
||||
ON CONFLICT (game_id, snake_id) DO UPDATE SET
|
||||
snake_name = EXCLUDED.snake_name,
|
||||
is_you = EXCLUDED.is_you
|
||||
is_you = EXCLUDED.is_you,
|
||||
customizations = EXCLUDED.customizations
|
||||
""",
|
||||
[
|
||||
(game_id, snake.get("id"), snake.get("name"), snake.get("id") == you.get("id"))
|
||||
(
|
||||
game_id,
|
||||
snake.get("id"),
|
||||
snake.get("name"),
|
||||
snake.get("id") == you.get("id"),
|
||||
snake.get("customizations") or {},
|
||||
)
|
||||
for snake in snakes if snake.get("id") is not None
|
||||
],
|
||||
)
|
||||
@@ -739,6 +749,7 @@ class PostgresqlGameplayBackend(GameplayBackendTemplate):
|
||||
COALESCE(gs.snake_name, st.snake_name) AS snake_name,
|
||||
st.health, st.length, st.head_x, st.head_y, st.body AS body_json,
|
||||
COALESCE(gs.is_you, st.is_you) AS is_you,
|
||||
COALESCE(gs.customizations, '{}'::jsonb) AS customizations_json,
|
||||
st.inferred_move, st.latency
|
||||
FROM snake_turns AS st
|
||||
LEFT JOIN game_snakes AS gs
|
||||
|
||||
Reference in New Issue
Block a user