Check boats layout before accepting it
This commit is contained in:
parent
d3d5feda4f
commit
8fac31e97b
@ -9,7 +9,7 @@ use crate::human_player_ws::{ClientMessage, ServerMessage};
|
|||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub enum ClientEndResult {
|
pub enum ClientEndResult {
|
||||||
Finished,
|
Finished,
|
||||||
InvalidLayout,
|
InvalidBoatsLayout,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn run_client(
|
pub async fn run_client(
|
||||||
@ -117,7 +117,7 @@ pub async fn run_client(
|
|||||||
}
|
}
|
||||||
ServerMessage::RejectedBoatsLayout { errors } => {
|
ServerMessage::RejectedBoatsLayout { errors } => {
|
||||||
log::warn!("Rejected boat layout: {:?}", errors);
|
log::warn!("Rejected boat layout: {:?}", errors);
|
||||||
return Ok(ClientEndResult::InvalidLayout);
|
return Ok(ClientEndResult::InvalidBoatsLayout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -216,7 +216,8 @@ impl BoatsLayout {
|
|||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn errors(&self, rules: &GameRules) -> Vec<&str> {
|
/// Check if this boats layout is valid or not
|
||||||
|
pub fn errors(&self, rules: &GameRules) -> Vec<&'static str> {
|
||||||
let mut errors = vec![];
|
let mut errors = vec![];
|
||||||
|
|
||||||
// Check the number of boats
|
// Check the number of boats
|
||||||
@ -272,12 +273,6 @@ impl BoatsLayout {
|
|||||||
pub fn number_of_boats(&self) -> usize {
|
pub fn number_of_boats(&self) -> usize {
|
||||||
self.0.len()
|
self.0.len()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check for layout invalid configuration
|
|
||||||
pub fn layouts_errors(&self, _rules: &GameRules) -> Vec<&'static str> {
|
|
||||||
//TODO : implement
|
|
||||||
vec![]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -44,6 +44,21 @@ impl GameRules {
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Remove last boat
|
||||||
|
pub fn pop_boat(&mut self) -> usize {
|
||||||
|
let list = self.boats_list();
|
||||||
|
self.set_boats_list(&list[0..list.len() - 1]);
|
||||||
|
*list.last().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add a boat to the list of boats
|
||||||
|
pub fn add_boat(&mut self, len: usize) {
|
||||||
|
let mut list = self.boats_list();
|
||||||
|
list.push(len);
|
||||||
|
self.set_boats_list(&list[0..list.len() - 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Check game rules errors
|
||||||
pub fn get_errors(&self) -> Vec<&str> {
|
pub fn get_errors(&self) -> Vec<&str> {
|
||||||
let config = PlayConfiguration::default();
|
let config = PlayConfiguration::default();
|
||||||
|
|
||||||
|
@ -208,9 +208,9 @@ impl Handler<SetBoatsLayout> for Game {
|
|||||||
|
|
||||||
let player_index = self.player_id_by_uuid(msg.0);
|
let player_index = self.player_id_by_uuid(msg.0);
|
||||||
|
|
||||||
let errors = msg.1.layouts_errors(&self.rules);
|
let errors = msg.1.errors(&self.rules);
|
||||||
if !errors.is_empty() {
|
if !errors.is_empty() {
|
||||||
log::error!("Got invalid boats layou!");
|
log::error!("Got invalid boats layout!");
|
||||||
self.players[player_index].rejected_boats_layout(errors);
|
self.players[player_index].rejected_boats_layout(errors);
|
||||||
self.players[player_index].query_boats_layout(&self.rules);
|
self.players[player_index].query_boats_layout(&self.rules);
|
||||||
return;
|
return;
|
||||||
|
@ -95,3 +95,60 @@ async fn full_game_no_touching_boats() {
|
|||||||
})
|
})
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn invalid_boats_layout_number_of_boats() {
|
||||||
|
let _ = env_logger::builder().is_test(true).try_init();
|
||||||
|
|
||||||
|
let local_set = task::LocalSet::new();
|
||||||
|
local_set
|
||||||
|
.run_until(async move {
|
||||||
|
let mut rules = GameRules::random_players_rules();
|
||||||
|
rules.boats_can_touch = false;
|
||||||
|
task::spawn_local(start_server(Args::for_test(
|
||||||
|
TestPort::FullGameTouchingBoats,
|
||||||
|
)));
|
||||||
|
wait_for_port(TestPort::FullGameTouchingBoats.port()).await;
|
||||||
|
|
||||||
|
let mut rules_modified = rules.clone();
|
||||||
|
rules_modified.pop_boat();
|
||||||
|
let layout = BoatsLayout::gen_random_for_rules(&rules_modified).unwrap();
|
||||||
|
|
||||||
|
let res =
|
||||||
|
bot_client::run_client(&TestPort::FullGameTouchingBoats.as_url(), &rules, layout)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
assert_eq!(res, ClientEndResult::InvalidBoatsLayout);
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn invalid_boats_layout_len_of_a_boat() {
|
||||||
|
let _ = env_logger::builder().is_test(true).try_init();
|
||||||
|
|
||||||
|
let local_set = task::LocalSet::new();
|
||||||
|
local_set
|
||||||
|
.run_until(async move {
|
||||||
|
let mut rules = GameRules::random_players_rules();
|
||||||
|
rules.boats_can_touch = false;
|
||||||
|
task::spawn_local(start_server(Args::for_test(
|
||||||
|
TestPort::FullGameTouchingBoats,
|
||||||
|
)));
|
||||||
|
wait_for_port(TestPort::FullGameTouchingBoats.port()).await;
|
||||||
|
|
||||||
|
let mut rules_modified = rules.clone();
|
||||||
|
let previous = rules_modified.pop_boat();
|
||||||
|
rules_modified.add_boat(previous - 1);
|
||||||
|
let layout = BoatsLayout::gen_random_for_rules(&rules_modified).unwrap();
|
||||||
|
|
||||||
|
let res =
|
||||||
|
bot_client::run_client(&TestPort::FullGameTouchingBoats.as_url(), &rules, layout)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
assert_eq!(res, ClientEndResult::InvalidBoatsLayout);
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user