feat: add configurable speed and expanded grid presets for snake
- Add per-game speed setting with presets (Slow/Normal/Fast/Insane) - Add speed selector UI in snake lobby - Expand grid presets with Tiny (15x15) and XL (50x30) - Auto-calculate cell size based on grid dimensions - Preserve speed setting in rematch games
This commit is contained in:
@@ -13,7 +13,7 @@ import (
|
||||
const createGame = `-- name: CreateGame :one
|
||||
INSERT INTO games (id, board, current_turn, status)
|
||||
VALUES (?, ?, ?, ?)
|
||||
RETURNING id, board, current_turn, status, winner_user_id, winning_cells, created_at, updated_at, rematch_game_id, game_type, grid_width, grid_height, max_players, game_mode, score
|
||||
RETURNING id, board, current_turn, status, winner_user_id, winning_cells, created_at, updated_at, rematch_game_id, game_type, grid_width, grid_height, max_players, game_mode, score, snake_speed
|
||||
`
|
||||
|
||||
type CreateGameParams struct {
|
||||
@@ -47,6 +47,7 @@ func (q *Queries) CreateGame(ctx context.Context, arg CreateGameParams) (Game, e
|
||||
&i.MaxPlayers,
|
||||
&i.GameMode,
|
||||
&i.Score,
|
||||
&i.SnakeSpeed,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
@@ -87,7 +88,7 @@ func (q *Queries) DeleteGame(ctx context.Context, id string) error {
|
||||
}
|
||||
|
||||
const getActiveGames = `-- name: GetActiveGames :many
|
||||
SELECT id, board, current_turn, status, winner_user_id, winning_cells, created_at, updated_at, rematch_game_id, game_type, grid_width, grid_height, max_players, game_mode, score FROM games WHERE game_type = 'connect4' AND status < 2
|
||||
SELECT id, board, current_turn, status, winner_user_id, winning_cells, created_at, updated_at, rematch_game_id, game_type, grid_width, grid_height, max_players, game_mode, score, snake_speed FROM games WHERE game_type = 'connect4' AND status < 2
|
||||
`
|
||||
|
||||
func (q *Queries) GetActiveGames(ctx context.Context) ([]Game, error) {
|
||||
@@ -115,6 +116,7 @@ func (q *Queries) GetActiveGames(ctx context.Context) ([]Game, error) {
|
||||
&i.MaxPlayers,
|
||||
&i.GameMode,
|
||||
&i.Score,
|
||||
&i.SnakeSpeed,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -130,7 +132,7 @@ func (q *Queries) GetActiveGames(ctx context.Context) ([]Game, error) {
|
||||
}
|
||||
|
||||
const getGame = `-- name: GetGame :one
|
||||
SELECT id, board, current_turn, status, winner_user_id, winning_cells, created_at, updated_at, rematch_game_id, game_type, grid_width, grid_height, max_players, game_mode, score FROM games WHERE id = ?
|
||||
SELECT id, board, current_turn, status, winner_user_id, winning_cells, created_at, updated_at, rematch_game_id, game_type, grid_width, grid_height, max_players, game_mode, score, snake_speed FROM games WHERE id = ?
|
||||
`
|
||||
|
||||
func (q *Queries) GetGame(ctx context.Context, id string) (Game, error) {
|
||||
@@ -152,6 +154,7 @@ func (q *Queries) GetGame(ctx context.Context, id string) (Game, error) {
|
||||
&i.MaxPlayers,
|
||||
&i.GameMode,
|
||||
&i.Score,
|
||||
&i.SnakeSpeed,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
@@ -192,7 +195,7 @@ func (q *Queries) GetGamePlayers(ctx context.Context, gameID string) ([]GamePlay
|
||||
}
|
||||
|
||||
const getGamesByUserID = `-- name: GetGamesByUserID :many
|
||||
SELECT g.id, g.board, g.current_turn, g.status, g.winner_user_id, g.winning_cells, g.created_at, g.updated_at, g.rematch_game_id, g.game_type, g.grid_width, g.grid_height, g.max_players, g.game_mode, g.score FROM games g
|
||||
SELECT g.id, g.board, g.current_turn, g.status, g.winner_user_id, g.winning_cells, g.created_at, g.updated_at, g.rematch_game_id, g.game_type, g.grid_width, g.grid_height, g.max_players, g.game_mode, g.score, g.snake_speed FROM games g
|
||||
JOIN game_players gp ON g.id = gp.game_id
|
||||
WHERE gp.user_id = ?
|
||||
ORDER BY g.updated_at DESC
|
||||
@@ -223,6 +226,7 @@ func (q *Queries) GetGamesByUserID(ctx context.Context, userID sql.NullString) (
|
||||
&i.MaxPlayers,
|
||||
&i.GameMode,
|
||||
&i.Score,
|
||||
&i.SnakeSpeed,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ type Game struct {
|
||||
MaxPlayers int64
|
||||
GameMode int64
|
||||
Score int64
|
||||
SnakeSpeed int64
|
||||
}
|
||||
|
||||
type GamePlayer struct {
|
||||
|
||||
@@ -11,9 +11,9 @@ import (
|
||||
)
|
||||
|
||||
const createSnakeGame = `-- name: CreateSnakeGame :one
|
||||
INSERT INTO games (id, board, current_turn, status, game_type, grid_width, grid_height, max_players, game_mode)
|
||||
VALUES (?, ?, 0, ?, 'snake', ?, ?, 8, ?)
|
||||
RETURNING id, board, current_turn, status, winner_user_id, winning_cells, created_at, updated_at, rematch_game_id, game_type, grid_width, grid_height, max_players, game_mode, score
|
||||
INSERT INTO games (id, board, current_turn, status, game_type, grid_width, grid_height, max_players, game_mode, snake_speed)
|
||||
VALUES (?, ?, 0, ?, 'snake', ?, ?, 8, ?, ?)
|
||||
RETURNING id, board, current_turn, status, winner_user_id, winning_cells, created_at, updated_at, rematch_game_id, game_type, grid_width, grid_height, max_players, game_mode, score, snake_speed
|
||||
`
|
||||
|
||||
type CreateSnakeGameParams struct {
|
||||
@@ -23,6 +23,7 @@ type CreateSnakeGameParams struct {
|
||||
GridWidth sql.NullInt64
|
||||
GridHeight sql.NullInt64
|
||||
GameMode int64
|
||||
SnakeSpeed int64
|
||||
}
|
||||
|
||||
func (q *Queries) CreateSnakeGame(ctx context.Context, arg CreateSnakeGameParams) (Game, error) {
|
||||
@@ -33,6 +34,7 @@ func (q *Queries) CreateSnakeGame(ctx context.Context, arg CreateSnakeGameParams
|
||||
arg.GridWidth,
|
||||
arg.GridHeight,
|
||||
arg.GameMode,
|
||||
arg.SnakeSpeed,
|
||||
)
|
||||
var i Game
|
||||
err := row.Scan(
|
||||
@@ -51,6 +53,7 @@ func (q *Queries) CreateSnakeGame(ctx context.Context, arg CreateSnakeGameParams
|
||||
&i.MaxPlayers,
|
||||
&i.GameMode,
|
||||
&i.Score,
|
||||
&i.SnakeSpeed,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
@@ -91,7 +94,7 @@ func (q *Queries) DeleteSnakeGame(ctx context.Context, id string) error {
|
||||
}
|
||||
|
||||
const getActiveSnakeGames = `-- name: GetActiveSnakeGames :many
|
||||
SELECT id, board, current_turn, status, winner_user_id, winning_cells, created_at, updated_at, rematch_game_id, game_type, grid_width, grid_height, max_players, game_mode, score FROM games WHERE game_type = 'snake' AND status < 2 AND game_mode = 0
|
||||
SELECT id, board, current_turn, status, winner_user_id, winning_cells, created_at, updated_at, rematch_game_id, game_type, grid_width, grid_height, max_players, game_mode, score, snake_speed FROM games WHERE game_type = 'snake' AND status < 2 AND game_mode = 0
|
||||
`
|
||||
|
||||
func (q *Queries) GetActiveSnakeGames(ctx context.Context) ([]Game, error) {
|
||||
@@ -119,6 +122,7 @@ func (q *Queries) GetActiveSnakeGames(ctx context.Context) ([]Game, error) {
|
||||
&i.MaxPlayers,
|
||||
&i.GameMode,
|
||||
&i.Score,
|
||||
&i.SnakeSpeed,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -134,7 +138,7 @@ func (q *Queries) GetActiveSnakeGames(ctx context.Context) ([]Game, error) {
|
||||
}
|
||||
|
||||
const getSnakeGame = `-- name: GetSnakeGame :one
|
||||
SELECT id, board, current_turn, status, winner_user_id, winning_cells, created_at, updated_at, rematch_game_id, game_type, grid_width, grid_height, max_players, game_mode, score FROM games WHERE id = ? AND game_type = 'snake'
|
||||
SELECT id, board, current_turn, status, winner_user_id, winning_cells, created_at, updated_at, rematch_game_id, game_type, grid_width, grid_height, max_players, game_mode, score, snake_speed FROM games WHERE id = ? AND game_type = 'snake'
|
||||
`
|
||||
|
||||
func (q *Queries) GetSnakeGame(ctx context.Context, id string) (Game, error) {
|
||||
@@ -156,6 +160,7 @@ func (q *Queries) GetSnakeGame(ctx context.Context, id string) (Game, error) {
|
||||
&i.MaxPlayers,
|
||||
&i.GameMode,
|
||||
&i.Score,
|
||||
&i.SnakeSpeed,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
5
db/migrations/005_add_snake_speed.sql
Normal file
5
db/migrations/005_add_snake_speed.sql
Normal file
@@ -0,0 +1,5 @@
|
||||
-- +goose Up
|
||||
ALTER TABLE games ADD COLUMN snake_speed INTEGER NOT NULL DEFAULT 7;
|
||||
|
||||
-- +goose Down
|
||||
ALTER TABLE games DROP COLUMN snake_speed;
|
||||
@@ -172,6 +172,7 @@ func (p *SnakePersister) SaveSnakeGame(sg *snake.SnakeGame) error {
|
||||
GridWidth: gridWidth,
|
||||
GridHeight: gridHeight,
|
||||
GameMode: int64(sg.Mode),
|
||||
SnakeSpeed: int64(sg.Speed),
|
||||
})
|
||||
return err
|
||||
}
|
||||
@@ -224,6 +225,7 @@ func (p *SnakePersister) LoadSnakeGame(id string) (*snake.SnakeGame, error) {
|
||||
Status: snake.Status(row.Status),
|
||||
Mode: snake.GameMode(row.GameMode),
|
||||
Score: int(row.Score),
|
||||
Speed: int(row.SnakeSpeed),
|
||||
}
|
||||
|
||||
if row.RematchGameID.Valid {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
-- name: CreateSnakeGame :one
|
||||
INSERT INTO games (id, board, current_turn, status, game_type, grid_width, grid_height, max_players, game_mode)
|
||||
VALUES (?, ?, 0, ?, 'snake', ?, ?, 8, ?)
|
||||
INSERT INTO games (id, board, current_turn, status, game_type, grid_width, grid_height, max_players, game_mode, snake_speed)
|
||||
VALUES (?, ?, 0, ?, 'snake', ?, ?, 8, ?, ?)
|
||||
RETURNING *;
|
||||
|
||||
-- name: GetSnakeGame :one
|
||||
|
||||
Reference in New Issue
Block a user