From 3c97c9f2c5b3a9dc13032a169a2a03db779ef7b2 Mon Sep 17 00:00:00 2001 From: Joel Therrien Date: Mon, 31 Jul 2023 19:31:22 -0700 Subject: [PATCH] Add total board scoring --- src/lib.rs | 76 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 60 insertions(+), 16 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 187255a..21f6771 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -93,8 +93,9 @@ trait Dictionary { fn substring_set(&self) -> HashSet<&str>; fn is_word_valid(&self, word: &Word) -> bool; } +type DictionaryImpl = HashMap; -impl Dictionary for HashMap { +impl Dictionary for DictionaryImpl{ fn create(path: &str) -> Self { let mut reader = csv::Reader::from_path(path).unwrap(); @@ -154,7 +155,7 @@ pub struct Board { cells: Vec, } -struct Word<'a> { +pub struct Word<'a> { cells: Vec<&'a Cell>, coords: Coordinates, } @@ -296,23 +297,30 @@ impl Board { } } - /* - fn calculate_scores(&self, dictionary: &Dictionary) -> Result<(Vec<(Word, u32)>, u32), &str> { - let words = self.find_played_words()?; + + pub fn calculate_scores(&self, dictionary: &DictionaryImpl) -> Result<(Vec<(Word, u32)>, u32), String> { + let (words, tiles_played) = self.find_played_words()?; let mut words_and_scores = Vec::new(); let mut total_score = 0; for word in words { - let mut word_score = 0; - let mut word_multiplier = 1; - + if !dictionary.contains_key(&word.to_string()) { + return Err(format!("{} is not a valid word", word.to_string())); + } + let score = word.calculate_score(); + total_score += score; + words_and_scores.push((word, score)); } - todo!() - }*/ + if tiles_played == TRAY_LENGTH { + total_score += ALL_LETTERS_BONUS; + } - fn find_played_words(&self) -> Result, &str> { + Ok((words_and_scores, total_score)) + } + + pub fn find_played_words(&self) -> Result<(Vec, u8), &str> { // We don't assume that the move is valid, so let's first establish that @@ -406,7 +414,7 @@ impl Board { } if anchored { - Ok(words) + Ok((words, tiles_played)) } else { return Err("Played tiles must be anchored to something") } @@ -679,7 +687,8 @@ mod tests { is_blank: false, }); - let words = board.find_played_words().unwrap(); + let (words, tiles_played) = board.find_played_words().unwrap(); + assert_eq!(tiles_played, 1); assert_eq!(words.len(), 1); let word = words.first().unwrap(); assert_eq!(word.calculate_score(), 2); @@ -700,7 +709,8 @@ mod tests { is_blank: false, }); - let words = board.find_played_words().unwrap(); + let (words, tiles_played) = board.find_played_words().unwrap(); + assert_eq!(tiles_played, 1); assert_eq!(words.len(), 1); let word = words.first().unwrap(); assert_eq!(word.calculate_score(), 2); @@ -816,7 +826,8 @@ mod tests { println!("{}", board); let words = board.find_played_words(); match words { - Ok(x) => { + Ok((x, tiles_played)) => { + assert_eq!(tiles_played, 2); assert_eq!(x.len(), 1); let word = x.get(0).unwrap(); assert_eq!(word.to_string(), "JOEL"); @@ -860,7 +871,8 @@ mod tests { let words = board.find_played_words(); match words { - Ok(x) => { + Ok((x, tiled_played)) => { + assert_eq!(tiled_played, 2); assert_eq!(x.len(), 2); let word = x.get(0).unwrap(); assert_eq!(word.to_string(), "EGG"); @@ -874,6 +886,38 @@ mod tests { } Err(e) => { panic!("Expected to find a word to play; found error {}", e) } } + + let scores = board.calculate_scores(&dictionary); + match scores { + Ok(_) => {panic!("Expected an error")} + Err(e) => {assert_eq!(e, "JOEL is not a valid word")} + } + + let mut alt_dictionary = DictionaryImpl::new(); + alt_dictionary.insert("JOEL".to_string(), 0.5); + alt_dictionary.insert("EGG".to_string(), 0.5); + + + let scores = board.calculate_scores(&alt_dictionary); + match scores { + Ok((words, total_score)) => { + assert_eq!(words.len(), 2); + let (word, score) = words.get(0).unwrap(); + assert_eq!(word.to_string(), "EGG"); + assert_eq!(word.calculate_score(), 2 + 2 + 2); + assert_eq!(*score, 2 + 2 + 2); + + let (word, score) = words.get(1).unwrap(); + assert_eq!(word.to_string(), "JOEL"); + assert_eq!(word.calculate_score(), 8 + 1 + 2 + 1); + assert_eq!(*score, 8 + 1 + 2 + 1); + + assert_eq!(total_score, 18); + } + Err(e) => {panic!("Wasn't expecting to encounter error {e}")} + } + + // replace one of the 'G' in EGG with an ephemeral to trigger an error board.get_cell_mut(maybe_invert(Coordinates(9, 8))).unwrap().value = Some(make_letter('G', true, 2));