Start to work on game structures
This commit is contained in:
parent
c0b6067d34
commit
5a19763d73
92
src/data/boats_layout.rs
Normal file
92
src/data/boats_layout.rs
Normal file
@ -0,0 +1,92 @@
|
||||
use crate::data::GameRules;
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Copy)]
|
||||
pub enum BoatDirection {
|
||||
Left,
|
||||
Right,
|
||||
Top,
|
||||
Bottom,
|
||||
}
|
||||
|
||||
impl BoatDirection {
|
||||
pub fn shift_coordinates(&self, coordinates: Coordinates, nth: usize) -> Coordinates {
|
||||
let shift = match self {
|
||||
BoatDirection::Left => (1, 0),
|
||||
BoatDirection::Right => (-1, 0),
|
||||
BoatDirection::Top => (0, -1),
|
||||
BoatDirection::Bottom => (0, 1),
|
||||
};
|
||||
|
||||
Coordinates::new(
|
||||
coordinates.x + shift.0 * nth as i32,
|
||||
coordinates.y + shift.1 * nth as i32,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Copy, Eq, PartialEq)]
|
||||
pub struct Coordinates {
|
||||
x: i32,
|
||||
y: i32,
|
||||
}
|
||||
|
||||
impl Coordinates {
|
||||
pub fn new<E>(x: E, y: E) -> Self
|
||||
where
|
||||
E: Into<i32>,
|
||||
{
|
||||
Self {
|
||||
x: x.into(),
|
||||
y: y.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone, Copy)]
|
||||
pub struct BoatPosition {
|
||||
start: Coordinates,
|
||||
len: usize,
|
||||
direction: BoatDirection,
|
||||
}
|
||||
|
||||
impl BoatPosition {
|
||||
pub fn all_coordinates(&self) -> Vec<Coordinates> {
|
||||
let mut positions = Vec::with_capacity(self.len);
|
||||
for i in 0..self.len {
|
||||
positions.push(self.direction.shift_coordinates(self.start, i));
|
||||
}
|
||||
positions
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
||||
pub struct BoatsLayout(Vec<BoatPosition>);
|
||||
|
||||
impl BoatsLayout {
|
||||
pub fn gen_random_for_rules(rules: &GameRules) -> Self {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::data::boats_layout::{BoatDirection, BoatPosition, Coordinates};
|
||||
|
||||
#[test]
|
||||
fn get_boat_coordinates() {
|
||||
let position = BoatPosition {
|
||||
start: Coordinates { x: 1, y: 1 },
|
||||
len: 3,
|
||||
direction: BoatDirection::Bottom,
|
||||
};
|
||||
let coordinates = position.all_coordinates();
|
||||
assert_eq!(
|
||||
coordinates,
|
||||
vec![
|
||||
Coordinates::new(1, 1),
|
||||
Coordinates::new(1, 2),
|
||||
Coordinates::new(1, 3),
|
||||
]
|
||||
)
|
||||
}
|
||||
}
|
50
src/data/game_map.rs
Normal file
50
src/data/game_map.rs
Normal file
@ -0,0 +1,50 @@
|
||||
use crate::data::boats_layout::BoatsLayout;
|
||||
use crate::data::GameRules;
|
||||
|
||||
enum MapCellContent {
|
||||
Invalid,
|
||||
Nothing,
|
||||
TouchedBoat,
|
||||
Boat,
|
||||
FailedStrike,
|
||||
}
|
||||
|
||||
impl MapCellContent {
|
||||
fn letter(&self) -> &'static str {
|
||||
match self {
|
||||
MapCellContent::Invalid => "!",
|
||||
MapCellContent::Nothing => " ",
|
||||
MapCellContent::TouchedBoat => "T",
|
||||
MapCellContent::Boat => "B",
|
||||
MapCellContent::FailedStrike => "X",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct GameMap {
|
||||
rules: GameRules,
|
||||
boats_config: BoatsLayout,
|
||||
}
|
||||
|
||||
impl GameMap {
|
||||
pub fn new(rules: GameRules, boats_config: BoatsLayout) -> Self {
|
||||
Self {
|
||||
rules,
|
||||
boats_config,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_cell_content(&self, x: usize, y: usize) -> MapCellContent {
|
||||
// TODO : improve this
|
||||
return MapCellContent::Nothing;
|
||||
}
|
||||
|
||||
pub fn print_map(&self) {
|
||||
for y in 0..self.rules.map_height {
|
||||
for x in 0..self.rules.map_width {
|
||||
print!("{} ", self.get_cell_content(x, y).letter());
|
||||
}
|
||||
println!();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,48 +1,5 @@
|
||||
use crate::consts::*;
|
||||
|
||||
/// Specifies the kind of boat to use
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Copy, Clone)]
|
||||
pub enum BotType {
|
||||
Random,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize)]
|
||||
struct BotDescription {
|
||||
r#type: BotType,
|
||||
description: String,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize)]
|
||||
pub struct PlayConfiguration {
|
||||
min_boat_len: usize,
|
||||
max_boat_len: usize,
|
||||
min_map_width: usize,
|
||||
max_map_width: usize,
|
||||
min_map_height: usize,
|
||||
max_map_height: usize,
|
||||
min_boats_number: usize,
|
||||
max_boats_number: usize,
|
||||
bot_types: Vec<BotDescription>,
|
||||
}
|
||||
|
||||
impl Default for PlayConfiguration {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
min_boat_len: MIN_BOATS_LENGTH,
|
||||
max_boat_len: MAX_BOATS_LENGTH,
|
||||
min_map_width: MIN_MAP_WIDTH,
|
||||
max_map_width: MAX_MAP_WIDTH,
|
||||
min_map_height: MIN_MAP_HEIGHT,
|
||||
max_map_height: MAX_MAP_HEIGHT,
|
||||
min_boats_number: MIN_BOATS_NUMBER,
|
||||
max_boats_number: MAX_BOATS_NUMBER,
|
||||
bot_types: vec![BotDescription {
|
||||
r#type: BotType::Random,
|
||||
description: "Random strike. All the time.".to_string(),
|
||||
}],
|
||||
}
|
||||
}
|
||||
}
|
||||
use crate::data::{BotType, PlayConfiguration};
|
||||
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
||||
pub struct GameRules {
|
7
src/data/mod.rs
Normal file
7
src/data/mod.rs
Normal file
@ -0,0 +1,7 @@
|
||||
pub use game_rules::*;
|
||||
pub use play_config::*;
|
||||
|
||||
mod boats_layout;
|
||||
mod game_map;
|
||||
mod game_rules;
|
||||
mod play_config;
|
45
src/data/play_config.rs
Normal file
45
src/data/play_config.rs
Normal file
@ -0,0 +1,45 @@
|
||||
use crate::consts::*;
|
||||
|
||||
/// Specifies the kind of boat to use
|
||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Copy, Clone)]
|
||||
pub enum BotType {
|
||||
Random,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize)]
|
||||
pub struct BotDescription {
|
||||
r#type: BotType,
|
||||
description: String,
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize)]
|
||||
pub struct PlayConfiguration {
|
||||
pub min_boat_len: usize,
|
||||
pub max_boat_len: usize,
|
||||
pub min_map_width: usize,
|
||||
pub max_map_width: usize,
|
||||
pub min_map_height: usize,
|
||||
pub max_map_height: usize,
|
||||
pub min_boats_number: usize,
|
||||
pub max_boats_number: usize,
|
||||
pub bot_types: Vec<BotDescription>,
|
||||
}
|
||||
|
||||
impl Default for PlayConfiguration {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
min_boat_len: MIN_BOATS_LENGTH,
|
||||
max_boat_len: MAX_BOATS_LENGTH,
|
||||
min_map_width: MIN_MAP_WIDTH,
|
||||
max_map_width: MAX_MAP_WIDTH,
|
||||
min_map_height: MIN_MAP_HEIGHT,
|
||||
max_map_height: MAX_MAP_HEIGHT,
|
||||
min_boats_number: MIN_BOATS_NUMBER,
|
||||
max_boats_number: MAX_BOATS_NUMBER,
|
||||
bot_types: vec![BotDescription {
|
||||
r#type: BotType::Random,
|
||||
description: "Random strike. All the time.".to_string(),
|
||||
}],
|
||||
}
|
||||
}
|
||||
}
|
@ -30,8 +30,10 @@ pub enum ClientMessage {
|
||||
#[derive(serde::Serialize, Debug)]
|
||||
#[serde(tag = "type")]
|
||||
pub enum ServerMessage {
|
||||
WaitingForOtherPlayer,
|
||||
WaitingForAnotherPlayer,
|
||||
QueryBoatsLayout { rules: GameRules },
|
||||
WaitingForOtherPlayerConfiguration,
|
||||
OtherPlayerReady,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
@ -51,7 +53,7 @@ impl Actor for HumanPlayerWS {
|
||||
type Context = WebsocketContext<Self>;
|
||||
|
||||
fn started(&mut self, ctx: &mut Self::Context) {
|
||||
self.send_message(ServerMessage::WaitingForOtherPlayer, ctx);
|
||||
self.send_message(ServerMessage::WaitingForAnotherPlayer, ctx);
|
||||
|
||||
// Start game, according to appropriate start mode
|
||||
match &self.start_mode {
|
||||
|
Loading…
Reference in New Issue
Block a user