From 403d377c9e728c2cd23698736ffbdc4571baf213 Mon Sep 17 00:00:00 2001 From: Liam Bigelow <40188355+bglw@users.noreply.github.com> Date: Fri, 15 Nov 2024 23:31:13 +1300 Subject: [PATCH] Update classic board gen for new rules --- truncate_client/src/lib.rs | 2 +- truncate_core/benches/core_bench.rs | 2 +- truncate_core/src/board.rs | 142 ++++++++++++++++++---------- truncate_core/src/game.rs | 32 +++++++ truncate_core/src/moves/mod.rs | 32 +++---- truncate_core/src/npc/mod.rs | 2 +- truncate_server/src/game_state.rs | 4 +- 7 files changed, 143 insertions(+), 73 deletions(-) diff --git a/truncate_client/src/lib.rs b/truncate_client/src/lib.rs index 3bc831ac..facc29a5 100644 --- a/truncate_client/src/lib.rs +++ b/truncate_client/src/lib.rs @@ -146,7 +146,7 @@ pub fn backchannel(msg: String) -> String { next_player, npc_params, } => { - let mut game = truncate_core::game::Game::new(3, 3, None, rules); + let mut game = truncate_core::game::Game::new(9, 9, None, rules); game.board = board; game.player_turn_count = vec![0; players.len()]; game.players = players; diff --git a/truncate_core/benches/core_bench.rs b/truncate_core/benches/core_bench.rs index 044b6f25..8c1055f8 100644 --- a/truncate_core/benches/core_bench.rs +++ b/truncate_core/benches/core_bench.rs @@ -53,7 +53,7 @@ fn test_game(board: &str, hand: &str) -> Game { bag, players, next_player: Some(next_player), - ..Game::new(3, 1, None, GameRules::generation(0)) + ..Game::new_legacy(3, 1, None, GameRules::generation(0)) }; game.players[next_player].hand = Hand(hand.chars().collect()); game.start(); diff --git a/truncate_core/src/board.rs b/truncate_core/src/board.rs index be0b1adb..e96154c0 100644 --- a/truncate_core/src/board.rs +++ b/truncate_core/src/board.rs @@ -77,19 +77,62 @@ pub struct Board { impl Board { pub fn new(land_width: usize, land_height: usize) -> Self { - // TODO: resolve discrepancy between width parameter, and the actual width of the board (which is returned by self.width()) where `actual == width + 2` because of the extra home rows. - // let roots = vec![ - // Coordinate { - // x: land_width / 2 + land_width % 2 - 1, - // y: 0, - // }, - // Coordinate { - // x: land_width / 2, - // y: land_height + 1, - // }, - // ]; - - // Final board should have a ring of water around the land, in which to place the artifacts + // Final board should have a ring of water around the land + let board_width = land_width + 2; + let board_height = land_height + 2; + + // Create a slice of land with water on the edges + let mut land_row = vec![Square::land(); land_width]; + land_row.insert(0, Square::water()); + land_row.push(Square::water()); + + let mut squares = vec![vec![Square::water(); board_width]]; // Start with our north row of water + squares.extend(vec![land_row.clone(); land_height]); // Build out the centre land of the board + squares.extend(vec![vec![Square::water(); board_width]]); // Finish with a south row of water + + let mut board = Board { + squares, + artifacts: vec![], + towns: vec![], + obelisks: vec![], + orientations: vec![Direction::North, Direction::South], + }; + + let north_towns = [ + Coordinate::new(board_width - 4, 1), + Coordinate::new(board_width - 2, 3), + ]; + for town in north_towns { + board + .set_square(town, Square::town(0)) + .expect("Town square should exist"); + } + // North artifact + board + .set_square(Coordinate::new(board_width - 2, 1), Square::artifact(0)) + .expect("Artifact square should exist"); + + let south_towns = [ + Coordinate::new(1, board_height - 4), + Coordinate::new(3, board_height - 2), + ]; + for town in south_towns { + board + .set_square(town, Square::town(1)) + .expect("Town square should exist"); + } + // South artifact + board + .set_square(Coordinate::new(1, board_height - 2), Square::artifact(1)) + .expect("Artifact square should exist"); + + board.cache_special_squares(); + + board + } + + pub fn new_legacy(land_width: usize, land_height: usize) -> Self { + // Final board should have a ring of water around the land let board_width = land_width + 2; let board_height = land_height + 2; @@ -2026,40 +2069,34 @@ pub mod tests { #[test] fn makes_default_boards() { assert_eq!( - Board::new(3, 3).to_string(), - "~~ ~~ |0 ~~ ~~\n\ - ~~ #0 __ #0 ~~\n\ - ~~ __ __ __ ~~\n\ - ~~ #1 __ #1 ~~\n\ - ~~ ~~ |1 ~~ ~~" + Board::new(4, 4).to_string(), + "~~ ~~ ~~ ~~ ~~ ~~\n\ + ~~ __ #0 __ |0 ~~\n\ + ~~ #1 __ __ __ ~~\n\ + ~~ __ __ __ #0 ~~\n\ + ~~ |1 __ #1 __ ~~\n\ + ~~ ~~ ~~ ~~ ~~ ~~" ); assert_eq!( - Board::new(3, 2).to_string(), - "~~ ~~ |0 ~~ ~~\n\ - ~~ #0 __ #0 ~~\n\ - ~~ #1 __ #1 ~~\n\ - ~~ ~~ |1 ~~ ~~" - ); - - // TODO: Balance uneven boards - assert_eq!( - Board::new(2, 2).to_string(), - "~~ ~~ |0 ~~\n\ - ~~ #0 __ ~~\n\ - ~~ #1 __ ~~\n\ - ~~ ~~ |1 ~~" + Board::new(3, 4).to_string(), + "~~ ~~ ~~ ~~ ~~\n\ + ~~ #0 __ |0 ~~\n\ + ~~ #1 __ __ ~~\n\ + ~~ __ __ #0 ~~\n\ + ~~ |1 __ #1 ~~\n\ + ~~ ~~ ~~ ~~ ~~" ); assert_eq!( Board::new(5, 5).to_string(), - "~~ ~~ ~~ |0 ~~ ~~ ~~\n\ - ~~ #0 #0 __ #0 #0 ~~\n\ - ~~ __ __ __ __ __ ~~\n\ + "~~ ~~ ~~ ~~ ~~ ~~ ~~\n\ + ~~ __ __ #0 __ |0 ~~\n\ ~~ __ __ __ __ __ ~~\n\ + ~~ #1 __ __ __ #0 ~~\n\ ~~ __ __ __ __ __ ~~\n\ - ~~ #1 #1 __ #1 #1 ~~\n\ - ~~ ~~ ~~ |1 ~~ ~~ ~~" + ~~ |1 __ #1 __ __ ~~\n\ + ~~ ~~ ~~ ~~ ~~ ~~ ~~" ); } @@ -2165,9 +2202,9 @@ pub mod tests { #[test] fn width_height() { - let b = Board::new(6, 1); + let b = Board::new(6, 3); assert_eq!(b.width(), 8); - assert_eq!(b.height(), 3); + assert_eq!(b.height(), 5); } #[test] @@ -2573,12 +2610,13 @@ pub mod tests { #[test] fn get_neighbours() { - // (0,0) (1,0) (2,0) (3,0) (4,0) - // (0,1) (1,1) (2,1) (3,1) (4,1) - // (0,2) (1,2) (2,2) (3,2) (4,2) - // (0,3) (1,3) (2,3) (3,3) (4,3) - // (0,4) (1,4) (2,4) (3,4) (4,4) - let b = Board::new(3, 3); + // (0,0) (1,0) (2,0) (3,0) (4,0) (5,0) + // (0,1) (1,1) (2,1) (3,1) (4,1) (5,1) + // (0,2) (1,2) (2,2) (3,2) (4,2) (5,2) + // (0,3) (1,3) (2,3) (3,3) (4,3) (5,3) + // (0,4) (1,4) (2,4) (3,4) (4,4) (5,4) + // (0,5) (1,5) (2,5) (3,5) (4,5) (5,5) + let b = Board::new(4, 4); assert_eq!( // TODO: should we allow you to find neighbours of an invalid square? @@ -2590,21 +2628,21 @@ pub mod tests { ); assert_eq!( - b.neighbouring_squares(Coordinate { x: 1, y: 0 }), + b.neighbouring_squares(Coordinate { x: 0, y: 4 }), [ - (Coordinate { x: 2, y: 0 }, Square::artifact(0)), - (Coordinate { x: 1, y: 1 }, Square::town(0)), - (Coordinate { x: 0, y: 0 }, Square::water()), + (Coordinate { x: 0, y: 3 }, Square::water()), + (Coordinate { x: 1, y: 4 }, Square::artifact(1)), + (Coordinate { x: 0, y: 5 }, Square::water()), ] ); assert_eq!( b.neighbouring_squares(Coordinate { x: 2, y: 2 }), [ - (Coordinate { x: 2, y: 1 }, Square::land()), + (Coordinate { x: 2, y: 1 }, Square::town(0)), (Coordinate { x: 3, y: 2 }, Square::land()), (Coordinate { x: 2, y: 3 }, Square::land()), - (Coordinate { x: 1, y: 2 }, Square::land()), + (Coordinate { x: 1, y: 2 }, Square::town(1)), ] ); } diff --git a/truncate_core/src/game.rs b/truncate_core/src/game.rs index e5f63a62..5a26e746 100644 --- a/truncate_core/src/game.rs +++ b/truncate_core/src/game.rs @@ -85,6 +85,38 @@ impl Game { } } + pub fn new_legacy( + width: usize, + height: usize, + tile_seed: Option, + rules: GameRules, + ) -> Self { + let mut board = Board::new_legacy(width, height); + board.grow(); + + let next_player = match &rules.timing { + rules::Timing::Periodic { .. } => None, + _ => Some(0), + }; + + Self { + players: Vec::with_capacity(2), + board, + bag: TileBag::generation(rules.tile_generation, tile_seed), + judge: Judge::default(), + battle_count: 0, + turn_count: 0, + player_turn_count: Vec::with_capacity(2), + recent_changes: vec![], + started_at: None, + game_ends_at: None, + next_player, + paused: false, + winner: None, + rules, + } + } + pub fn add_player(&mut self, name: String) { let time_allowance = match self.rules.timing { rules::Timing::PerPlayer { diff --git a/truncate_core/src/moves/mod.rs b/truncate_core/src/moves/mod.rs index 2c402d4f..b01c2138 100644 --- a/truncate_core/src/moves/mod.rs +++ b/truncate_core/src/moves/mod.rs @@ -100,7 +100,7 @@ mod tests { players, player_turn_count: vec![0, 0], judge: short_dict(), - ..Game::new(3, 3, None, GameRules::generation(0)) + ..Game::new_legacy(3, 3, None, GameRules::generation(0)) }; assert_eq!( game.make_move(out_of_bounds, None, None, None), @@ -140,7 +140,7 @@ mod tests { players, player_turn_count: vec![0, 0], judge: short_dict(), - ..Game::new(3, 3, None, GameRules::generation(0)) + ..Game::new_legacy(3, 3, None, GameRules::generation(0)) }; // Places beside artifact @@ -318,7 +318,7 @@ mod tests { players, player_turn_count: vec![0, 0], judge: short_dict(), - ..Game::new(3, 3, None, GameRules::generation(0)) + ..Game::new_legacy(3, 3, None, GameRules::generation(0)) }; assert_eq!( @@ -499,7 +499,7 @@ mod tests { players, player_turn_count: vec![0, 0], judge: short_dict(), - ..Game::new(1, 1, None, GameRules::generation(0)) + ..Game::new_legacy(1, 1, None, GameRules::generation(0)) }; game.make_move( @@ -545,7 +545,7 @@ mod tests { players, player_turn_count: vec![0, 0], judge: short_dict(), - ..Game::new(3, 1, None, GameRules::generation(0)) + ..Game::new_legacy(3, 1, None, GameRules::generation(0)) }; game.make_move( @@ -601,7 +601,7 @@ mod tests { players, player_turn_count: vec![0, 0], judge: short_dict(), - ..Game::new(3, 1, None, GameRules::generation(0)) + ..Game::new_legacy(3, 1, None, GameRules::generation(0)) }; game.make_move( @@ -655,7 +655,7 @@ mod tests { players, player_turn_count: vec![0, 0], judge: short_dict(), - ..Game::new(3, 1, None, GameRules::generation(0)) + ..Game::new_legacy(3, 1, None, GameRules::generation(0)) }; game.make_move( @@ -705,7 +705,7 @@ mod tests { players, player_turn_count: vec![0, 0], judge: short_dict(), - ..Game::new(3, 1, None, GameRules::generation(0)) + ..Game::new_legacy(3, 1, None, GameRules::generation(0)) }; game.start(); @@ -764,7 +764,7 @@ mod tests { players, player_turn_count: vec![0, 0], judge: short_dict(), - ..Game::new(3, 1, None, GameRules::generation(0)) + ..Game::new_legacy(3, 1, None, GameRules::generation(0)) }; game.start(); @@ -823,7 +823,7 @@ mod tests { players, player_turn_count: vec![0, 0], judge: short_dict(), - ..Game::new(3, 1, None, GameRules::generation(0)) + ..Game::new_legacy(3, 1, None, GameRules::generation(0)) }; game.start(); @@ -882,7 +882,7 @@ mod tests { players, player_turn_count: vec![0, 0], judge: short_dict(), - ..Game::new(3, 1, None, GameRules::generation(0)) + ..Game::new_legacy(3, 1, None, GameRules::generation(0)) }; game.start(); @@ -941,7 +941,7 @@ mod tests { players, player_turn_count: vec![0, 0], judge: short_dict(), - ..Game::new(3, 1, None, GameRules::generation(0)) + ..Game::new_legacy(3, 1, None, GameRules::generation(0)) }; game.start(); @@ -999,7 +999,7 @@ mod tests { players, player_turn_count: vec![0, 0], judge: short_dict(), - ..Game::new(3, 1, None, GameRules::generation(0)) + ..Game::new_legacy(3, 1, None, GameRules::generation(0)) }; game.start(); @@ -1055,7 +1055,7 @@ mod tests { players, player_turn_count: vec![0, 0], judge: short_dict(), - ..Game::new(3, 1, None, GameRules::generation(0)) + ..Game::new_legacy(3, 1, None, GameRules::generation(0)) }; game.make_move( @@ -1103,7 +1103,7 @@ mod tests { players, player_turn_count: vec![0, 0], judge: short_dict(), - ..Game::new(1, 1, None, GameRules::generation(0)) + ..Game::new_legacy(1, 1, None, GameRules::generation(0)) }; game.make_move( @@ -1153,7 +1153,7 @@ mod tests { players, player_turn_count: vec![0, 0], judge: short_dict(), - ..Game::new(1, 1, None, GameRules::generation(0)) + ..Game::new_legacy(1, 1, None, GameRules::generation(0)) }; game.make_move( diff --git a/truncate_core/src/npc/mod.rs b/truncate_core/src/npc/mod.rs index 3d5fb0e6..1a9c6355 100644 --- a/truncate_core/src/npc/mod.rs +++ b/truncate_core/src/npc/mod.rs @@ -665,7 +665,7 @@ mod tests { players, player_turn_count: vec![0, 0], next_player: Some(next_player), - ..Game::new(3, 1, None, GameRules::generation(0)) // TODO: update snapshots to rules v1 + ..Game::new_legacy(3, 1, None, GameRules::generation(0)) // TODO: update snapshots to rules v1 }; game.players[next_player].hand = Hand(hand.chars().collect()); game.start(); diff --git a/truncate_server/src/game_state.rs b/truncate_server/src/game_state.rs index 675b749d..6c3e1ed0 100644 --- a/truncate_server/src/game_state.rs +++ b/truncate_server/src/game_state.rs @@ -34,8 +34,8 @@ pub struct GameManager { impl GameManager { pub fn new(game_id: String, effective_day: u32) -> Self { - let game = Game::new(9, 11, None, GameRules::latest(Some(effective_day)).1); - // let game = Game::new(9, 11, None, GameRules::tuesday()); + let game = Game::new(9, 9, None, GameRules::latest(Some(effective_day)).1); + // let game = Game::new(9, 9, None, GameRules::tuesday()); Self { game_id,