Skip to content

Commit

Permalink
Merge pull request #3 from amiller68/board_rendering
Browse files Browse the repository at this point in the history
feat: board rendering
  • Loading branch information
amiller68 authored Jan 23, 2024
2 parents 7daccd2 + 482417c commit b69760a
Show file tree
Hide file tree
Showing 8 changed files with 145 additions and 31 deletions.
42 changes: 39 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,43 @@ Right now all the web app does is allow you to create a game, and view the prett

See [https://krondor-chess.shuttleapp.rs/](https://krondor-chess.shuttleapp.rs) for deployed version

TODOS:
## Requirements
- Rust & Cargo
- [Shuttle](https://docs.shuttle.rs/getting-started/installation)
- Docker

- [ ] Rendering chess boards
- [ ] Making moves against boards
## Local development and usage

Run code checks:
```bash
make check
```

Run tests:
```bash
make test
```

Prepare SQLX queries:
```bash
./bin/queries.sh
```

Run locally:
```bash
./bin/run.sh
```

## Deployment

You'll need to get an Api key if you want to deploy to [Shuttle.rs](https://console.shuttle.rs/). It's easy and free to get one :)

In order to deploy to Shuttle.rs run:
```bash
cargo shuttle deploy
```
Remember to ensure your repository isn't dirty, your code passes checks, and your migrations are properly version controlled!

### CI/CD

This repository comes with workflows for deploying to Shuttle.rs from GitHub. These will run on pushing to `main` if you set up the `SHUTTLE_API_KEY` secret for GitHub actions in your repository.
9 changes: 8 additions & 1 deletion bin/postgres.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,19 @@ POSTGRES_VOLUME_NAME="krondor-chess-postgres-data"

POSTGRES_ROOT_USER="postgres"
POSTGRES_ROOT_PASSWORD="postgres"
POSTGRES_DATABASE="krondor-chess-db"

DATABASE_URL="postgres://${POSTGRES_ROOT_USER}:${POSTGRES_ROOT_PASSWORD}@localhost:5432/${POSTGRES_DATABASE}"

CONTAINER_RUNTIME="podman"
if which docker &>/dev/null; then
CONTAINER_RUNTIME="docker"
fi

function database-url {
echo ${DATABASE_URL}
}

function run {
start-postgres-container
}
Expand Down Expand Up @@ -41,7 +48,7 @@ function create-postgres-container {
--name ${POSTGRES_CONTAINER_NAME} \
--env POSTGRES_USER=${POSTGRES_ROOT_USER} \
--env POSTGRES_PASSWORD=${POSTGRES_ROOT_PASSWORD} \
--env POSTGRES_DB=postgres \
--env POSTGRES_DB=${POSTGRES_DATABASE} \
--publish 5432:5432 \
--volume ${POSTGRES_VOLUME_NAME}:/var/lib/postgresql/data \
--detach \
Expand Down
3 changes: 1 addition & 2 deletions bin/queries.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

set -o errexit

export DATABASE_URL="postgres://postgres:postgres@localhost:5432/postgres"

export DATABASE_URL=$(bin/postgres.sh database-url)
make postgres

sqlx database setup
Expand Down
3 changes: 1 addition & 2 deletions bin/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

set -o errexit

export DATABASE_URL="postgres://postgres:postgres@localhost:5432/postgres"

export DATABASE_URL=$(bin/postgres.sh database-url)
make postgres

cargo shuttle run
72 changes: 65 additions & 7 deletions src/api/models/api_board.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,82 @@
use std::convert::TryFrom;

use pleco::board::Board;
use pleco::core::sq::SQ as Sq;
use pleco::core::Piece;

use crate::database::models::PartialGameWithFen;

pub struct ApiBoard {
pub id: String,
pub pretty_string: String,
id: String,
html: String,
}

impl ApiBoard {
pub fn id(&self) -> &str {
&self.id
}

pub fn html(&self) -> &str {
&self.html
}
}

impl TryFrom<PartialGameWithFen> for ApiBoard {
type Error = ApiBoardError;

fn try_from(game: PartialGameWithFen) -> Result<Self, Self::Error> {
let id = game.id().to_string();
let board = Board::from_fen(game.current_fen())
.map_err(|e| ApiBoardError::FenBuilder(format!("{:?}", e)))?;
// TODO: Board rendering here
let pretty_string = board.pretty_string();
Ok(Self { id, pretty_string })
let html = render_html_board(game.current_fen())?;
Ok(Self { id, html })
}
}

fn render_html_board(fen: &str) -> Result<String, ApiBoardError> {
let board = Board::from_fen(fen).map_err(|e| ApiBoardError::FenBuilder(format!("{:?}", e)))?;

let mut html_board = String::new();
html_board.push_str("<table class='chess-board'>");

for rank in (0..8).rev() {
html_board.push_str("<tr class='chess-row'>");
for file in 0..8 {
let square = Sq::from(rank * 8 + file);
let piece = board.piece_at_sq(square);
let class = if square.on_light_square() {
"light-square"
} else {
"dark-square"
};

let piece_string = render_html_piece(piece);

html_board.push_str(&format!(
"<td class='chess-cell {}'>{}</td>",
class, piece_string
));
}
html_board.push_str("</tr>");
}

html_board.push_str("</table>");
Ok(html_board)
}

fn render_html_piece(piece: Piece) -> String {
match piece {
Piece::None => " ".to_string(),
Piece::WhitePawn => "♙".to_string(),
Piece::WhiteKnight => "♘".to_string(),
Piece::WhiteBishop => "♗".to_string(),
Piece::WhiteRook => "♖".to_string(),
Piece::WhiteQueen => "♕".to_string(),
Piece::WhiteKing => "♔".to_string(),
Piece::BlackPawn => "♟︎".to_string(),
Piece::BlackKnight => "♞".to_string(),
Piece::BlackBishop => "♝".to_string(),
Piece::BlackRook => "♜".to_string(),
Piece::BlackQueen => "♛".to_string(),
Piece::BlackKing => "♚".to_string(),
}
}

Expand Down
13 changes: 0 additions & 13 deletions static/not_found.html

This file was deleted.

27 changes: 27 additions & 0 deletions static/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,30 @@ table, th, td {
border: 1px solid black;
padding: 0.25rem;
}

.chess-board {
border-collapse: collapse;
margin: auto; /* Center the board horizontally */
}

.chess-row {
height: 50px; /* Adjust the height of rows */
}

.chess-cell {
width: 50px; /* Adjust the width of cells */
height: 50px; /* Ensure cells are square */
text-align: center; /* Center the piece character */
vertical-align: middle; /* Align the character vertically */
font-size: 36px; /* Increase the size of the piece character */
font-weight: bold; /* Optional: Makes the piece character bold */
border: 1px solid #333; /* Adds a border to each cell */
}

.light-square {
background-color: #f0d9b5; /* Light color for light squares */
}

.dark-square {
background-color: #b58863; /* Dark color for dark squares */
}
7 changes: 4 additions & 3 deletions templates/board.html
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
<!-- templates/board.html -->
{% extends "base.html" %}

{% block content %}
<h1>Board</h1>

<div id="board-{{ api_board.id }}">
{{ api_board.pretty_string }}
{% let board_html = api_board.html() %}
{% let board_id = api_board.id() %}
<div id="board-{{ board_id }}">
{{ board_html|safe }}
</div>

{% endblock %}

0 comments on commit b69760a

Please sign in to comment.