Skip to content

Commit

Permalink
Merge pull request #2 from projeto-de-algoritmos-2024/refactor/backend
Browse files Browse the repository at this point in the history
Refactor/backend
  • Loading branch information
iagorrr authored Dec 2, 2024
2 parents 55875f5 + adc4730 commit 6816bbe
Show file tree
Hide file tree
Showing 5 changed files with 163 additions and 191 deletions.
56 changes: 56 additions & 0 deletions backend/api/src/cell_piece.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use crate::coordinate::Coordinate;
use serde::{Deserialize, Serialize};
use std::mem::swap;

#[derive(Serialize, Deserialize, Debug, Eq, Copy, Clone, PartialEq, PartialOrd, Ord, Hash)]
pub struct CellPiece {
pub u: bool,
pub l: bool,
pub d: bool,
pub r: bool,
pub can_rotate: bool,
}

impl CellPiece {
pub fn rotate(&mut self) {
/*
U L L L
L R -> U R - > D R -> D U
D D U R
*/
swap(&mut self.u, &mut self.l);
swap(&mut self.l, &mut self.d);
swap(&mut self.r, &mut self.d);
}
}

pub fn can_connect(u_pos: &Coordinate, u: &CellPiece, v_pos: &Coordinate, v: &CellPiece) -> bool {
if u_pos == v_pos {
return true;
}

let d_x: i32 = u_pos.x - v_pos.x;
let d_y: i32 = u_pos.y - v_pos.y;

if d_x != 0 && d_y != 0 {
// diagonal
return false;
}

if d_x != 0 {
if d_x > 0 {
// v above u
return u.u && v.d;
} else {
// v below u
return u.d && v.u;
}
} else {
if d_y > 0 {
// v at left of u
return u.l && v.r;
} else {
return u.r && v.l;
}
}
}
15 changes: 15 additions & 0 deletions backend/api/src/coordinate.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use serde::{Deserialize, Serialize};

// 5 directions, center, up, right, down, left (clockwise)
pub const DELTA_X: [i32; 5] = [0, -1, 0, 1, 0];
pub const DELTA_Y: [i32; 5] = [0, 0, 1, 0, -1];

#[derive(Serialize, Deserialize, Debug, Clone, Hash, Eq, PartialEq, Copy, Ord, PartialOrd)]
pub struct Coordinate {
pub x: i32,
pub y: i32,
}

pub fn calc_manhattan_negative_distance(u: &Coordinate, v: &Coordinate) -> i32 {
-((u.x - v.x).abs() + (u.y - v.y).abs())
}
68 changes: 4 additions & 64 deletions backend/api/src/game.rs
Original file line number Diff line number Diff line change
@@ -1,74 +1,14 @@
use crate::cell_piece::CellPiece;
use crate::coordinate::Coordinate;
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Debug, Eq, Copy, Clone, PartialEq, PartialOrd, Ord, Hash)]
pub struct CellPiece {
pub u: bool,
pub l: bool,
pub d: bool,
pub r: bool,
pub can_rotate: bool,
}

impl CellPiece {
pub fn rotate(&mut self) {
let rotated_piece: CellPiece = CellPiece {
u: self.l,
r: self.u,
d: self.r,
l: self.d,
can_rotate: self.can_rotate,
};
// TODO: Clone this properly !
self.u = rotated_piece.u;
self.r = rotated_piece.r;
self.d = rotated_piece.d;
self.l = rotated_piece.l;
}
}

pub fn can_connect(u_x: i32, u_y: i32, u: &CellPiece, v_x: i32, v_y: i32, v: &CellPiece) -> bool {
if u_x == v_x && u_y == v_y {
return true;
}

let d_x: i32 = u_x - v_x;
let d_y: i32 = u_y - v_y;

if d_x != 0 && d_y != 0 {
// diagonal
return false;
}

if d_x != 0 {
if d_x > 0 {
// v above u
return u.u && v.d;
} else {
// v below u
return u.d && v.u;
}
} else {
if d_y > 0 {
// v at left of u
return u.l && v.r;
} else {
return u.r && v.l;
}
}
}

pub type CellGrid = Vec<Vec<CellPiece>>;

#[derive(Serialize, Deserialize, Debug)]
pub struct GameSchema {
pub number_of_rows: i32,
pub number_of_columns: i32,

pub initial_x: i32,
pub initial_y: i32,
pub source: Coordinate,

pub target_x: i32,
pub target_y: i32,
pub goal: Coordinate,

pub grid: CellGrid,
}
35 changes: 17 additions & 18 deletions backend/api/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
mod game;
use game::GameSchema;
use solver::Coordinate;

mod solver;
use solver::is_solved;
use solver::{is_solved, solve};

use actix_web::{
get,
Expand All @@ -12,13 +11,22 @@ use actix_web::{
};

use std::env;

use std::time::Duration;

use tokio::time::timeout;

mod cell_piece;

mod coordinate;

#[get("/solver")]
async fn solver_endpoint(data: web::Json<GameSchema>) -> impl Responder {
let result = timeout(Duration::from_secs(13), solver::solver(&data.0)).await;
// TODO: MAKE SURE IT'S A RECTANGLE MAP
let result = timeout(
Duration::from_secs(13),
solve(&data.0.source, &data.0.goal, &data.0.grid),
)
.await;
return match result {
Ok(ret) => match ret {
Some(ret) => HttpResponse::Ok().json(ret),
Expand All @@ -29,23 +37,14 @@ async fn solver_endpoint(data: web::Json<GameSchema>) -> impl Responder {
}

#[get("/is_solved")]
async fn is_solvable_endpoint(game: web::Json<GameSchema>) -> impl Responder {
solver::print_grid(&game.0.grid);
return HttpResponse::Ok().json(is_solved(
&game.0.grid,
Coordinate {
x: game.initial_x,
y: game.initial_y,
},
Coordinate {
x: game.0.target_x,
y: game.0.target_y,
},
));
async fn is_solved_endpoint(game: web::Json<GameSchema>) -> impl Responder {
return HttpResponse::Ok().json(is_solved(&game.0.source, &game.0.goal, &game.0.grid));
}

#[actix_web::main]
async fn main() -> std::io::Result<()> {
// Defines which port to run the API based in ENVIRONMENT variable
// BACKEND_API_PORT, if no such variable is fond 8086 is used
let backend_api_port: u16 = match env::var("BACKEND_API_PORT") {
Ok(val) => val.parse::<u16>().unwrap(),
Err(_e) => 8086,
Expand All @@ -54,7 +53,7 @@ async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.service(solver_endpoint)
.service(is_solvable_endpoint)
.service(is_solved_endpoint)
})
.bind(("0.0.0.0", backend_api_port))?
.run()
Expand Down
Loading

0 comments on commit 6816bbe

Please sign in to comment.