Skip to content

Commit

Permalink
#39 Making move WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
Dominux committed Jan 8, 2023
1 parent f9b5745 commit 6a623d1
Show file tree
Hide file tree
Showing 29 changed files with 268 additions and 30 deletions.
3 changes: 2 additions & 1 deletion gamelib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ use errors::GameResult;
use field::build_field;
pub use field::FieldType;
use group::Group;
use history::{HistoryManager, StoredGame, StoredGameMeta, StoredGameMove, StoredGameMoveType};
use history::HistoryManager;
pub use history::{StoredGame, StoredGameMeta, StoredGameMove, StoredGameMoveType};
pub use point::PlayerColor;

mod aliases;
Expand Down
2 changes: 2 additions & 0 deletions server/Cargo.lock

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

6 changes: 3 additions & 3 deletions server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ axum = "0.6.1"

serde = { version = "1.0.152", features = [ "derive" ] }

sea-orm = { version = "^0", features = [ "sqlx-postgres", "runtime-tokio-rustls", "macros" ] }
sea-orm = { version = "^0", features = [ "sqlx-postgres", "runtime-tokio-rustls", "macros", "postgres-array" ] }

thiserror = "1.0.38"

uuid = { version = "1.2.2", features = ["serde", "v4"] }

entity = {path="src/common/db/entity"}
migration = {path="src/common/db/migration"}
entity = {path="./libs/entity"}
migration = {path="./libs/migration"}
spherical_go_game_lib = {path="../gamelib"}

[dev-dependencies]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
sea-orm = { version = "^0", features = [ "sqlx-postgres", "runtime-tokio-rustls", "macros" ] }
sea-orm = { version = "^0", features = [ "sqlx-postgres", "runtime-tokio-rustls", "macros", "postgres-array" ] }

serde = { version = "1.0.152", features = [ "derive" ] }

migration = {path="../migration"}
spherical_go_game_lib = {path="../../../gamelib"}
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
use migration::FieldType;
use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize};
use spherical_go_game_lib::{SizeType, StoredGameMeta};

#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]
#[sea_orm(table_name = "histories")]
Expand All @@ -24,6 +25,8 @@ pub enum Relation {
on_delete = "Cascade"
)]
Games,
#[sea_orm(has_many = "super::history_records::Entity")]
HistoryRecords,
}

impl Related<super::games::Entity> for Entity {
Expand All @@ -32,4 +35,19 @@ impl Related<super::games::Entity> for Entity {
}
}

impl Related<super::history_records::Entity> for Entity {
fn to() -> RelationDef {
Relation::HistoryRecords.def()
}
}

impl ActiveModelBehavior for ActiveModel {}

impl Into<StoredGameMeta> for Model {
fn into(self) -> StoredGameMeta {
StoredGameMeta {
field_type: self.field_type.into(),
size: self.size as SizeType,
}
}
}
File renamed without changes.
48 changes: 48 additions & 0 deletions server/libs/entity/src/history_records.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.10.6
use std::collections::HashSet;

use sea_orm::entity::prelude::*;
use serde::{Deserialize, Serialize};
use spherical_go_game_lib::{PointID, StoredGameMove, StoredGameMoveType};

#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]
#[sea_orm(table_name = "history_records")]
pub struct Model {
#[sea_orm(primary_key, auto_increment = false)]
pub id: Uuid,
pub history_id: Uuid,
pub point_id: i32,
pub died_points_ids: Vec<i32>,
}

#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
pub enum Relation {
#[sea_orm(
belongs_to = "super::histories::Entity",
from = "Column::HistoryId",
to = "super::histories::Column::Id",
on_update = "NoAction",
on_delete = "Cascade"
)]
Histories,
}

impl Related<super::histories::Entity> for Entity {
fn to() -> RelationDef {
Relation::Histories.def()
}
}

impl ActiveModelBehavior for ActiveModel {}

impl Into<StoredGameMove> for Model {
fn into(self) -> StoredGameMove {
// TODO: update logic once you add other move types to the db table
StoredGameMove {
move_type: StoredGameMoveType::Move,
point_id: Some(self.point_id as PointID),
died: HashSet::from_iter(self.died_points_ids.into_iter().map(|p| p as PointID)),
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub mod games;
pub mod histories;
pub mod history_records;
pub mod rooms;
pub mod users;
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ async-std = { version = "^1", features = ["attributes", "tokio1"] }

serde = { version = "1.0.152", features = [ "derive" ] }

spherical_go_game_lib = {path="../../../gamelib"}

[dependencies.sea-orm-migration]
version = "^0.10.0"
features = [ "runtime-tokio-rustls", "sqlx-postgres" ]
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ mod m20220101_000001_create_table;
mod m20230103_213731_games;
mod m20230104_155530_rooms;
mod m20230106_155413_histories;
mod m20230108_204629_history_records;

pub use m20230106_155413_histories::FieldType;

Expand All @@ -17,6 +18,7 @@ impl MigratorTrait for Migrator {
Box::new(m20230103_213731_games::Migration),
Box::new(m20230104_155530_rooms::Migration),
Box::new(m20230106_155413_histories::Migration),
Box::new(m20230108_204629_history_records::Migration),
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use sea_orm_migration::{
sea_orm::{DeriveActiveEnum, EnumIter},
};
use serde::{Deserialize, Serialize};
use spherical_go_game_lib::FieldType as GameLibFieldType;

use crate::m20230103_213731_games::Game;

Expand Down Expand Up @@ -65,3 +66,12 @@ pub enum FieldType {
#[sea_orm(num_value = 1)]
GridSphere,
}

impl Into<GameLibFieldType> for FieldType {
fn into(self) -> GameLibFieldType {
match self {
Self::Regular => GameLibFieldType::Regular,
Self::GridSphere => GameLibFieldType::GridSphere,
}
}
}
60 changes: 60 additions & 0 deletions server/libs/migration/src/m20230108_204629_history_records.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
use sea_orm_migration::prelude::*;

use crate::m20230106_155413_histories::History;

#[derive(DeriveMigrationName)]
pub struct Migration;

#[async_trait::async_trait]
impl MigrationTrait for Migration {
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.create_table(
Table::create()
.table(HistoryRecord::Table)
.if_not_exists()
.col(
ColumnDef::new(HistoryRecord::Id)
.uuid()
.not_null()
.primary_key(),
)
.col(ColumnDef::new(HistoryRecord::HistoryID).uuid().not_null())
.foreign_key(
ForeignKey::create()
.name("fk-history_record-history-id")
.on_delete(ForeignKeyAction::Cascade)
.from_col(HistoryRecord::HistoryID)
.to(History::Table, History::Id),
)
.col(ColumnDef::new(HistoryRecord::PointID).integer().not_null())
.col(
ColumnDef::new(HistoryRecord::DiedPointsIds)
.array(ColumnType::Integer(None))
.not_null(),
)
.to_owned(),
)
.await
}

async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
manager
.drop_table(Table::drop().table(HistoryRecord::Table).to_owned())
.await
}
}

/// Learn more at https://docs.rs/sea-query#iden
#[derive(Iden)]
#[iden = "history_records"]
enum HistoryRecord {
Table,
Id,
#[iden = "history_id"]
HistoryID,
#[iden = "point_id"]
PointID,
#[iden = "died_points_ids"]
DiedPointsIds,
}
File renamed without changes.
8 changes: 7 additions & 1 deletion server/src/apps/games/schemas.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use entity::games::Model as Game;
use migration::FieldType;
use serde::{Deserialize, Serialize};
use spherical_go_game_lib::SizeType;
use spherical_go_game_lib::{PointID, SizeType};

#[derive(Debug, Deserialize)]
pub struct CreateGameSchema {
Expand All @@ -28,3 +28,9 @@ impl From<Game> for GameWithWSLink {
Self { game, ws_link }
}
}

#[derive(Debug, Serialize, Deserialize)]
pub struct MoveSchema {
pub game_id: uuid::Uuid,
pub point_id: PointID,
}
49 changes: 48 additions & 1 deletion server/src/apps/games/services.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use sea_orm::DbConn;
use spherical_go_game_lib::{Game as Gamelib, StoredGame, StoredGameMeta};

use super::schemas::CreateGameSchema;
use super::schemas::{CreateGameSchema, MoveSchema};
use crate::{
apps::{
games::{repositories::GamesRepository, schemas::GameWithWSLink},
Expand Down Expand Up @@ -73,4 +74,50 @@ impl<'a> GameService<'a> {

Ok(game.into())
}

pub async fn make_move(
&self,
move_schema: MoveSchema,
user: AuthenticatedUser,
) -> DGSResult<()> {
// Getting room
let room = self.rooms_repo.get_by_game_id(move_schema.game_id).await?;

// Checking if user is one of room players
if user.user_id != room.player1_id && Some(user.user_id) != room.player2_id {
return Err(DGSError::UserIsNotRoomPlayer);
}

// Getting game and history
let game = self.repo.get(move_schema.game_id).await?;
let history = self
.histories_repo
.get_by_game_id(move_schema.game_id)
.await?;

// Validating
{
// Checking if game is ended
if game.is_ended {
return Err(DGSError::GameEnded);
}

// Checking if player can make a move
match history.records.len() % 2 {
0 if user.user_id != room.player1_id => return Err(DGSError::NotPlayerTurn),
1 if user.user_id == room.player1_id => return Err(DGSError::NotPlayerTurn),
_ => (),
};
}

// Finally making move
let died_stones = {
let mut game = Gamelib::new_from_history(history.into())?;
game.make_move(&move_schema.point_id)?
};

// Saving result as a history record

todo!()
}
}
20 changes: 14 additions & 6 deletions server/src/apps/histories/repositories.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use entity::histories;
use entity::{histories, history_records};
use sea_orm::{ActiveModelTrait, ActiveValue, ColumnTrait, DbConn, EntityTrait, QueryFilter};

use super::schemas::CreateHistorySchema;
use super::schemas::{CreateHistorySchema, HistoryWithRecords};
use crate::common::errors::{DGSError, DGSResult};

pub struct HistoriesRepository<'a> {
Expand All @@ -26,14 +26,22 @@ impl<'a> HistoriesRepository<'a> {
Ok(history)
}

pub async fn get_by_game_id(&self, game_id: uuid::Uuid) -> DGSResult<histories::Model> {
Ok(histories::Entity::find()
pub async fn get_by_game_id(&self, game_id: uuid::Uuid) -> DGSResult<HistoryWithRecords> {
// Getting a history itself
let history = histories::Entity::find()
.filter(histories::Column::GameId.eq(game_id))
.one(self.db)
.await?
.ok_or(DGSError::NotFound(format!(
"history with game id {game_id}"
)))?
.into())
)))?;

// Getting its records
let records = history_records::Entity::find()
.filter(history_records::Column::HistoryId.eq(history.id))
.all(self.db)
.await?;

Ok(HistoryWithRecords { history, records })
}
}
18 changes: 17 additions & 1 deletion server/src/apps/histories/schemas.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use entity::{histories, history_records};
use migration::FieldType;
use spherical_go_game_lib::SizeType;
use spherical_go_game_lib::{SizeType, StoredGame};

#[derive(Debug)]
pub struct CreateHistorySchema {
Expand All @@ -17,3 +18,18 @@ impl CreateHistorySchema {
}
}
}

#[derive(Debug)]
pub struct HistoryWithRecords {
pub history: histories::Model,
pub records: Vec<history_records::Model>,
}

impl Into<StoredGame> for HistoryWithRecords {
fn into(self) -> StoredGame {
StoredGame {
meta: self.history.into(),
moves: self.records.into_iter().map(|rec| rec.into()).collect(),
}
}
}
Loading

0 comments on commit 6a623d1

Please sign in to comment.