Skip to content

Commit

Permalink
feat: bust a move
Browse files Browse the repository at this point in the history
  • Loading branch information
amiller68 committed Jan 25, 2024
1 parent 724e6ba commit aedee9b
Show file tree
Hide file tree
Showing 25 changed files with 451 additions and 269 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

This file was deleted.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ clippy:
postgres:
./bin/postgres.sh run

.PHONY: postgres-clean
postgres-clean:
./bin/postgres.sh clean

.PHONY: test
test:
cargo test --all --workspace --bins --tests --benches
7 changes: 7 additions & 0 deletions migrations/20240124210837_drop_fens_table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
-- We don't need the current_fen_id column anymore for games
ALTER TABLE games DROP COLUMN current_fen_id;
-- We don't need the fen_id column anymore for moves
ALTER TABLE moves DROP COLUMN fen_id;

-- We dont need the fens table anymore
DROP TABLE fens;
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
-- ALTER THE MOVES TABLE

-- Drop Unique constraint on moves (game_id, move_number)
ALTER TABLE moves DROP CONSTRAINT moves_game_id_move_number_key;

-- Drop our index on moves (game_id)
DROP INDEX idx_moves_game_id;

-- Drop the game_id, move, and move_number columns
ALTER TABLE moves DROP COLUMN game_id;
ALTER TABLE moves DROP COLUMN move_number;
ALTER TABLE moves DROP COLUMN move;

-- Insert just a plain fen column that should be unique
ALTER TABLE moves ADD COLUMN board TEXT UNIQUE NOT NULL;

-- RENAME THE MOVES TABLE TO POSITIONS

-- Rename the entire moves table to positions
-- This will describe every unqiue position that a game has been in
ALTER TABLE moves RENAME TO positions;

-- CREATE A NEW MOVES TABLE

-- Create a new table, also called moves, to track moves made in a game
CREATE TABLE IF NOT EXISTS moves (
id UUID PRIMARY KEY NOT NULL DEFAULT uuid_generate_v4(),
-- The game id
game_id UUID NOT NULL REFERENCES games(id) ON DELETE CASCADE,
-- The position of the game and the last move made
position_id UUID NOT NULL REFERENCES positions(id) ON DELETE CASCADE,
-- TODO: do we need this? This information is available within the FEN of the position
-- The move number of the game
move_number INTEGER NOT NULL,
created_at TIMESTAMP WITHOUT TIME ZONE NOT NULL DEFAULT CURRENT_TIMESTAMP,
-- enforce uniqueness on point in a game. also implement an index
UNIQUE (game_id, move_number)
);
1 change: 0 additions & 1 deletion src/api/games/board/mod.rs

This file was deleted.

60 changes: 0 additions & 60 deletions src/api/games/board/read_board.rs

This file was deleted.

65 changes: 65 additions & 0 deletions src/api/games/make_move.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
use askama::Template;
use axum::{
extract::{Path, State},
response::{IntoResponse, Response},
Form,
};
use sqlx::types::Uuid;

use crate::api::models::ApiBoard;
use crate::database::models::{Game, GameError};
use crate::AppState;

#[derive(serde::Deserialize)]
pub struct MakeMoveRequest {
#[serde(rename = "uciMove")]
uci_move: String,
}

pub async fn handler(
State(state): State<AppState>,
Path(game_id): Path<Uuid>,
Form(request): Form<MakeMoveRequest>,
) -> Result<impl IntoResponse, ReadBoardError> {
let uci_move = request.uci_move;
let mut conn = state.database().begin().await?;
let maybe_board = Game::make_move(&mut conn, game_id, &uci_move).await;
let board = match maybe_board {
Ok(board) => board,
Err(e) => match e {
GameError::InvalidMove(_, board) => board,
_ => return Err(e.into()),
},
};
// If we got here, then either we made a valid move
// or no changes were made to the database (invalid move)
conn.commit().await?;

let api_board = ApiBoard {
board,
game_id: game_id.to_string(),
};

Ok(TemplateApiBoard { api_board })
}

#[derive(Template)]
#[template(path = "board.html")]
struct TemplateApiBoard {
api_board: ApiBoard,
}

#[derive(Debug, thiserror::Error)]
pub enum ReadBoardError {
#[error("sqlx error: {0}")]
Sqlx(#[from] sqlx::Error),
#[error("game error: {0}")]
Game(#[from] GameError),
}

impl IntoResponse for ReadBoardError {
fn into_response(self) -> Response {
let body = format!("{}", self);
(axum::http::StatusCode::INTERNAL_SERVER_ERROR, body).into_response()
}
}
3 changes: 2 additions & 1 deletion src/api/games/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod board;
pub mod create_game;
pub mod make_move;
pub mod read_all_games;
pub mod read_game;
Loading

0 comments on commit aedee9b

Please sign in to comment.