feat: make attempts dynamic
This commit is contained in:
parent
492d6b8920
commit
5e1c5b3f07
@ -1,24 +1,22 @@
|
|||||||
use super::charstatus::{compare_strings, CharStatus};
|
use super::charstatus::{compare_strings, CharStatus};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
type Tries = usize;
|
type Attempts = usize;
|
||||||
|
|
||||||
const MAX_TRIES: Tries = 5;
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
|
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
|
||||||
pub struct Game {
|
pub struct Game {
|
||||||
pub word: Option<String>,
|
word: Option<String>,
|
||||||
pub submitted_words: Vec<Vec<CharStatus<String>>>,
|
submitted_words: Vec<Vec<CharStatus<String>>>,
|
||||||
tries: Tries,
|
max_attempts: Attempts,
|
||||||
status: Status,
|
status: Status,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Game {
|
impl Game {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub const fn new() -> Self {
|
pub const fn new(max_attempts: Attempts) -> Self {
|
||||||
Self {
|
Self {
|
||||||
word: None,
|
word: None,
|
||||||
tries: 0,
|
max_attempts,
|
||||||
submitted_words: Vec::new(),
|
submitted_words: Vec::new(),
|
||||||
status: Status::New,
|
status: Status::New,
|
||||||
}
|
}
|
||||||
@ -35,7 +33,6 @@ impl Game {
|
|||||||
if let Some(ref word) = self.word {
|
if let Some(ref word) = self.word {
|
||||||
let res = compare_strings(word, &answer.to_uppercase());
|
let res = compare_strings(word, &answer.to_uppercase());
|
||||||
self.submitted_words.push(res);
|
self.submitted_words.push(res);
|
||||||
self.tries += 1;
|
|
||||||
self.status = self.current_status();
|
self.status = self.current_status();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -44,24 +41,16 @@ impl Game {
|
|||||||
pub fn current_status(&self) -> Status {
|
pub fn current_status(&self) -> Status {
|
||||||
self.word.as_ref().map_or(Status::New, |_| {
|
self.word.as_ref().map_or(Status::New, |_| {
|
||||||
let word_count = self.submitted_words.len();
|
let word_count = self.submitted_words.len();
|
||||||
match self.tries {
|
match word_count {
|
||||||
0 => Status::New,
|
0 => Status::New,
|
||||||
1..MAX_TRIES => self
|
i => self
|
||||||
.submitted_words
|
|
||||||
.last()
|
|
||||||
.map_or(Status::InProgress, |words| {
|
|
||||||
if words.iter().all(|v| matches!(v, CharStatus::Match(_))) {
|
|
||||||
Status::Win(word_count)
|
|
||||||
} else {
|
|
||||||
Status::InProgress
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
_ => self
|
|
||||||
.submitted_words
|
.submitted_words
|
||||||
.last()
|
.last()
|
||||||
.map_or(Status::Lose(word_count), |words| {
|
.map_or(Status::Lose(word_count), |words| {
|
||||||
if words.iter().all(|v| matches!(v, CharStatus::Match(_))) {
|
if words.iter().all(|v| matches!(v, CharStatus::Match(_))) {
|
||||||
Status::Win(word_count)
|
Status::Win(word_count)
|
||||||
|
} else if i < self.max_attempts {
|
||||||
|
Status::InProgress
|
||||||
} else {
|
} else {
|
||||||
Status::Lose(word_count)
|
Status::Lose(word_count)
|
||||||
}
|
}
|
||||||
@ -73,7 +62,7 @@ impl Game {
|
|||||||
|
|
||||||
impl Default for Game {
|
impl Default for Game {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::new()
|
Self::new(5)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,8 +70,8 @@ impl Default for Game {
|
|||||||
#[allow(clippy::module_name_repetitions)]
|
#[allow(clippy::module_name_repetitions)]
|
||||||
pub enum Status {
|
pub enum Status {
|
||||||
New,
|
New,
|
||||||
Win(Tries),
|
Win(Attempts),
|
||||||
Lose(Tries),
|
Lose(Attempts),
|
||||||
InProgress,
|
InProgress,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,29 +85,35 @@ mod test {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
Game {
|
Game {
|
||||||
word: None,
|
word: None,
|
||||||
tries: 0,
|
max_attempts: 5,
|
||||||
submitted_words: Vec::new(),
|
submitted_words: Vec::new(),
|
||||||
status: Status::New,
|
status: Status::New,
|
||||||
},
|
},
|
||||||
Game::new()
|
Game::default()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
#[allow(clippy::field_reassign_with_default)]
|
||||||
fn start() {
|
fn start() {
|
||||||
let word: String = random_word(5);
|
let word: String = random_word(5);
|
||||||
|
|
||||||
let want = Game {
|
let want = Game {
|
||||||
word: Some(word.to_uppercase()),
|
word: Some(word.to_uppercase()),
|
||||||
submitted_words: Vec::new(),
|
submitted_words: Vec::new(),
|
||||||
tries: 0,
|
max_attempts: 5,
|
||||||
status: Status::InProgress,
|
status: Status::InProgress,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut got = Game::new();
|
let mut got = Game::default();
|
||||||
got.start(&word);
|
got.start(&word);
|
||||||
|
|
||||||
assert_eq!(got, want);
|
assert_eq!(got, want);
|
||||||
|
|
||||||
|
let mut got = Game::default();
|
||||||
|
|
||||||
|
got.word = Some(word.to_uppercase());
|
||||||
|
assert_ne!(got, want);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -132,11 +127,11 @@ mod test {
|
|||||||
&word.to_uppercase(),
|
&word.to_uppercase(),
|
||||||
&answer.to_uppercase(),
|
&answer.to_uppercase(),
|
||||||
)],
|
)],
|
||||||
tries: 1,
|
max_attempts: 5,
|
||||||
status: Status::InProgress,
|
status: Status::InProgress,
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut got = Game::new();
|
let mut got = Game::default();
|
||||||
got.start(word);
|
got.start(word);
|
||||||
got.submit_answer(answer);
|
got.submit_answer(answer);
|
||||||
|
|
||||||
@ -145,7 +140,7 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn current_status() {
|
fn current_status() {
|
||||||
let mut got = Game::new();
|
let mut got = Game::default();
|
||||||
|
|
||||||
assert_eq!(got.current_status(), Status::New);
|
assert_eq!(got.current_status(), Status::New);
|
||||||
|
|
||||||
@ -154,7 +149,7 @@ mod test {
|
|||||||
let want = Game {
|
let want = Game {
|
||||||
word: Some(word.to_uppercase()),
|
word: Some(word.to_uppercase()),
|
||||||
submitted_words: Vec::new(),
|
submitted_words: Vec::new(),
|
||||||
tries: 0,
|
max_attempts: 5,
|
||||||
status: Status::InProgress,
|
status: Status::InProgress,
|
||||||
};
|
};
|
||||||
got.start(word);
|
got.start(word);
|
||||||
@ -168,7 +163,7 @@ mod test {
|
|||||||
&word.to_uppercase(),
|
&word.to_uppercase(),
|
||||||
&answer.to_uppercase(),
|
&answer.to_uppercase(),
|
||||||
)],
|
)],
|
||||||
tries: 1,
|
max_attempts: 5,
|
||||||
status: Status::InProgress,
|
status: Status::InProgress,
|
||||||
};
|
};
|
||||||
got.submit_answer(answer);
|
got.submit_answer(answer);
|
||||||
@ -180,12 +175,12 @@ mod test {
|
|||||||
got.submit_answer(answer);
|
got.submit_answer(answer);
|
||||||
assert_eq!(got.current_status(), Status::Lose(5));
|
assert_eq!(got.current_status(), Status::Lose(5));
|
||||||
|
|
||||||
let mut got = Game::new();
|
let mut got = Game::default();
|
||||||
got.start(word);
|
got.start(word);
|
||||||
got.submit_answer(word);
|
got.submit_answer(word);
|
||||||
assert_eq!(got.current_status(), Status::Win(1));
|
assert_eq!(got.current_status(), Status::Win(1));
|
||||||
|
|
||||||
let mut got = Game::new();
|
let mut got = Game::default();
|
||||||
got.start(word);
|
got.start(word);
|
||||||
got.submit_answer(answer);
|
got.submit_answer(answer);
|
||||||
got.submit_answer(answer);
|
got.submit_answer(answer);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user