diff --git a/src/api/game_handling.rs b/src/api/game_handling.rs index 541ec5b..59476b1 100644 --- a/src/api/game_handling.rs +++ b/src/api/game_handling.rs @@ -23,7 +23,9 @@ pub async fn fetch_game(socket: &mut WebSocket, url: &String, game_hodler: &Game } pub async fn create_game(socket: &mut WebSocket, player_id: String, color: &Tile, game_hodler: &GameHodler) { - let url = Game::generate_url(); + //Just to prevent collissions (Rare af but yaknow, just in case.) + let map_size = game_hodler.games.lock().unwrap().len(); + let url = format!("{}{}", Game::generate_url(), map_size); println!("\n{} created game: {}\n", player_id, url); game_hodler .games @@ -42,15 +44,6 @@ pub async fn create_game(socket: &mut WebSocket, player_id: String, color: &Tile } } -pub async fn check_exists(socket: &mut WebSocket, url: &String, game_hodler: &GameHodler) { - let games = game_hodler.games.lock().unwrap().to_owned(); - let exists = games.get(url).is_some(); - - if socket.send(Message::Text(format!("{}", exists))).await.is_err() { - return; - } -} - pub async fn join_game(_socket: &mut WebSocket, url: &String, player_id: &String, game_hodler: &GameHodler){ let mut binding = game_hodler .games diff --git a/src/api/game_packets.rs b/src/api/game_packets.rs index a702fa3..b9787c0 100644 --- a/src/api/game_packets.rs +++ b/src/api/game_packets.rs @@ -18,10 +18,6 @@ pub (crate) enum GamePacket { player_id: String, color: Tile, }, - //Call to check if game exists (Unused) - CheckExists { - url: String, - }, //Call to fetch game state FetchGame { url: String, diff --git a/src/api/handle_socket.rs b/src/api/handle_socket.rs index 793c5ba..21828ff 100644 --- a/src/api/handle_socket.rs +++ b/src/api/handle_socket.rs @@ -4,7 +4,7 @@ use axum:: }; use crate:: { - api::{game_handling::{check_exists, create_game, fetch_game}, move_handling::*}, + api::{game_handling::{create_game, fetch_game}, move_handling::*}, rules::game_hodler::GameHodler, }; @@ -36,31 +36,33 @@ pub async fn handle_socket(mut socket: WebSocket, game_hodler: GameHodler) { }; match packet { - //recieve and process movement action + //recieve and process movement action. GamePacket::Action { url, move_p, move_a } => { do_move( &game_hodler, &url, &move_p, &move_a).await; } + //Create a new game. GamePacket::CreateGame {player_id, color} => { create_game(&mut socket, player_id, &color, &game_hodler).await; } - GamePacket::CheckExists { url } => { - check_exists(&mut socket, &url, &game_hodler).await; + //Response on create a new game. + GamePacket::GameCreated { url } => { + if socket.send(Message::Text(url)).await.is_err() { + return; + } } - //Send current gamestate + //Send current gamestate. GamePacket::FetchGame { url } => { fetch_game(&mut socket, &url, &game_hodler).await; } + //Request to join a game. GamePacket::JoinGame { url , player_id} => { join_game(&mut socket, &url, &player_id, &game_hodler).await; } + //Get possible moves. GamePacket::FetchMoves { url, h, c, x, y, aggr, player} => { fetch_moves(&mut socket, &game_hodler, &url, &h, &c, &x, &y, &aggr, &player).await; } - GamePacket::GameCreated { url } => { - if socket.send(Message::Text(url)).await.is_err() { - return; - } - }, + //Previously made moves. GamePacket::FetchPreviousMoves { url } => { fetch_previous_moves(&mut socket, &game_hodler, &url).await; } diff --git a/src/api/move_handling.rs b/src/api/move_handling.rs index fd3f910..63638d8 100644 --- a/src/api/move_handling.rs +++ b/src/api/move_handling.rs @@ -57,7 +57,6 @@ pub async fn do_move(game_hodler: &GameHodler, url: &String, move_p: &MovementAc } let moved_p: bool = Tile::passive_move(board_p, (move_p.x1, move_p.y1), (move_p.x2, move_p.y2)); - //println!("moved_p: {moved_p}"); //Make move on a let board_a = game @@ -70,9 +69,7 @@ pub async fn do_move(game_hodler: &GameHodler, url: &String, move_p: &MovementAc return; } - let moved_a: bool = - Tile::aggressive_move(board_a, (move_a.x1, move_a.y1), (move_a.x2, move_a.y2)); - //println!("moved_a: {moved_a}"); + let moved_a: bool = Tile::aggressive_move(board_a, (move_a.x1, move_a.y1), (move_a.x2, move_a.y2)); //If either move fail. if !moved_p || !moved_a { @@ -111,7 +108,6 @@ pub async fn fetch_moves(socket: &mut WebSocket, game_hodler: &GameHodler, url: let game = binding2.get(url).unwrap(); let mut move_list = format!("{:?}", Tile::get_possible_moves(b, *aggr, (*x, *y))); - //println!("fetch_moves: {}", move_list); /* We may not fetch moves if: It's not your turn, diff --git a/src/rules/game_board.rs b/src/rules/game_board.rs index 4234f7b..aa58b06 100644 --- a/src/rules/game_board.rs +++ b/src/rules/game_board.rs @@ -34,7 +34,7 @@ impl Board { } /* - Detta returnar: + This returns: [W][W][W][W] [ ][ ][ ][ ] [ ][ ][ ][ ] diff --git a/src/rules/game_instance.rs b/src/rules/game_instance.rs index 03b2931..a9b3cd8 100644 --- a/src/rules/game_instance.rs +++ b/src/rules/game_instance.rs @@ -82,17 +82,20 @@ impl Game { } Some(Tile::Empty) => unimplemented!(), None => { - if self.player_b != "None" && self.player_w != "None" { //Full lobby - return false; - } else if self.player_b == player_id || self.player_w == player_id { //Duplicate entries. - return false; - } else if self.player_b == "None" { + //Join as Black if vacant. + if self.player_b == "None" && self.player_w != player_id{ self.player_b = player_id.clone(); return true; - } else if self.player_w == "None" { + } + + //Join as White if vacant. + if self.player_w == "None" && self.player_b != player_id { self.player_w = player_id.clone(); return true; } + + //If full or you already in the game. + return false; } }; return false; diff --git a/src/rules/game_tile.rs b/src/rules/game_tile.rs index 07ab430..3b7fc3f 100644 --- a/src/rules/game_tile.rs +++ b/src/rules/game_tile.rs @@ -20,7 +20,7 @@ impl Tile { let boardstate = b.get_state(); let mut movelist: Vec<(i8, i8)> = Vec::new(); - //Om vår tile är tom har vi nada moves. + //If our tile is empty we have nada moves. if boardstate[cur_pos.0 as usize][cur_pos.1 as usize] == Tile::Empty{ return movelist; } @@ -52,6 +52,7 @@ impl Tile { return movelist; } + //This is ugly but eh. pub fn is_valid(state: &[[Tile; 4]; 4], cur_pos: (i8, i8), new_pos: (i8, i8), size: &i8, aggr: bool, (dy, dx): (&i8, &i8)) -> bool { //Check if in range. let newy = new_pos.0 as usize; @@ -67,37 +68,36 @@ impl Tile { //Passive if !aggr { - return state[newy][newx] == Tile::Empty; + return state[newy][newx] == Tile::Empty && state[step_y][step_x] == Tile::Empty; } - if aggr{ - //Knuffa ej våra egna stenar. + if aggr { + //We may not push our own rocks. if state[newy][newx] == state[cur_pos.0 as usize][cur_pos.1 as usize] { return false; } - //future rock positions: + //future rock positions if pushed: let rock_y = cur_pos.0 + (*size + 1) * dy; let rock_x = cur_pos.1 + (*size + 1) * dx; - //In case stenen vi puttar faller av boarden. + //In case the rock is pushed off the board. if (rock_y) > 3 || (rock_x) > 3 || (rock_y) < 0 || (rock_x) < 0 { return true; } + //Check if a rock is behind our new position if we're pushing a rock. If it's empty we good. if *size == 1 && state[newy][newx] != Tile::Empty { - //Checka om det finns en sten bakom stenen vi puttar. Om Tomt we good. return state[rock_y as usize][rock_x as usize] == Tile::Empty; } else if *size == 2 && state[step_y][step_x] != Tile::Empty { //If a future rock position is not empty then the move is not valid. if state[rock_y as usize][rock_x as usize] != Tile::Empty{ return false; } - //Checka om det finns en sten bakom stenen vi puttar. + //Checka if there is a rock where we're going. return state[newy][newx] == Tile::Empty; } } - return true; } @@ -106,13 +106,15 @@ impl Tile { let dx = new_pos.1 - cur_pos.1; let dy = new_pos.0 - cur_pos.0; - //i = antal steps, 1 eller 2 + //i = size of step, 1 or 2. let i = dy.abs().max(dx.abs()); + //If thhe move is invalid, return false. if !Tile::is_valid(b.get_state(), cur_pos, new_pos, &i, false, (&dy, &dx)) { return false; } + //If we move 0 steps the move is false. if dx == 0 && dy == 0 { return false; } @@ -156,6 +158,7 @@ impl Tile { let mut boardstate = *b.get_state(); + //Direction let dir = ( (dy as f32 / 2.0).round() as i8, (dx as f32 / 2.0).round() as i8, @@ -179,6 +182,7 @@ impl Tile { let mut stepping: bool = true; let mut on_board: bool = true; + if step_x == end_x && step_y == end_y { stepping = false; } @@ -188,12 +192,14 @@ impl Tile { //If the pushed rock is still on the board. if on_board{ + //If we move one step and a rock is there. Move the rock. if boardstate[end_y][end_x] != Tile::Empty && !stepping{ boardstate[rock_y][rock_x] = boardstate[end_y][end_x]; } + //Leapfrog else if boardstate[step_y][step_x] != Tile::Empty && stepping{ boardstate[rock_y][rock_x] = boardstate[step_y][step_x]; - //Rensa platsen 1 steg bakom oss. (D'Lcrantz metoden) + //Clear the spot behind us. (The D'Lcrantz method) boardstate[step_y][step_x] = Tile::Empty; } //Edge case; diagonal 2 step pushes that are still on the board. @@ -221,9 +227,9 @@ impl Tile { [start][end]- Case 4 */ - //Flytta stenen. + //Move the rock. boardstate[end_y][end_x] = boardstate[start_y][start_x]; - //Rensa förra platsen. + //Clear the previous Tile. boardstate[start_y][start_x] = Tile::Empty; //Uppdatera boardstate. b.set_state(&boardstate); diff --git a/src/rules/tests.rs b/src/rules/tests.rs index 3d0a333..076fe2c 100644 --- a/src/rules/tests.rs +++ b/src/rules/tests.rs @@ -1192,4 +1192,21 @@ fn diagonal_push_1_step(){ assert!(Tile::aggressive_move(&mut board, (3, 3), (2, 2))); assert_eq!(board.get_state(), &target_state); +} + +#[test] +fn is_valid_bug_test() +{ + let state: [[Tile; 4]; 4] = [ + [Tile::Empty, Tile::Empty, Tile::Empty, Tile::Empty], + [Tile::Empty, Tile::Empty, Tile::Empty, Tile::Empty], + [Tile::Empty, Tile::White, Tile::Black, Tile::Empty], + [Tile::Empty, Tile::Empty, Tile::Empty, Tile::White], + ]; + + let mut board = Board::new_board(Tile::Black, Tile::Black); + board.set_state(&state); + + //Not supposed to do that. + assert!(!Tile::is_valid(board.get_state(), (2, 1), (2, 3), &2, false, (&0, &1))); } \ No newline at end of file