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::*;
|
use crate::consts::*;
|
||||||
|
use crate::data::{BotType, PlayConfiguration};
|
||||||
/// 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(),
|
|
||||||
}],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
|
||||||
pub struct GameRules {
|
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)]
|
#[derive(serde::Serialize, Debug)]
|
||||||
#[serde(tag = "type")]
|
#[serde(tag = "type")]
|
||||||
pub enum ServerMessage {
|
pub enum ServerMessage {
|
||||||
WaitingForOtherPlayer,
|
WaitingForAnotherPlayer,
|
||||||
QueryBoatsLayout { rules: GameRules },
|
QueryBoatsLayout { rules: GameRules },
|
||||||
|
WaitingForOtherPlayerConfiguration,
|
||||||
|
OtherPlayerReady,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
@ -51,7 +53,7 @@ impl Actor for HumanPlayerWS {
|
|||||||
type Context = WebsocketContext<Self>;
|
type Context = WebsocketContext<Self>;
|
||||||
|
|
||||||
fn started(&mut self, ctx: &mut Self::Context) {
|
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
|
// Start game, according to appropriate start mode
|
||||||
match &self.start_mode {
|
match &self.start_mode {
|
||||||
|
Loading…
Reference in New Issue
Block a user