Re-do dictionary, fix bug in word-finding
This commit is contained in:
parent
6f14579f3a
commit
37fe5bac56
1 changed files with 125 additions and 64 deletions
189
src/lib.rs
189
src/lib.rs
|
@ -1,4 +1,4 @@
|
|||
use std::collections::HashSet;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::fmt;
|
||||
use std::fmt::{Formatter, Write};
|
||||
use std::str::FromStr;
|
||||
|
@ -87,50 +87,50 @@ pub struct Cell {
|
|||
coordinates: Coordinates,
|
||||
}
|
||||
|
||||
|
||||
pub struct Dictionary {
|
||||
words: Vec<String>,
|
||||
scores: Vec<f64>,
|
||||
trait Dictionary {
|
||||
fn create(path: &str) -> Self;
|
||||
fn filter_to_sub_dictionary(&self, proportion: f64) -> Self;
|
||||
fn substring_set(&self) -> HashSet<&str>;
|
||||
fn is_word_valid(&self, word: &Word) -> bool;
|
||||
}
|
||||
|
||||
impl Dictionary {
|
||||
fn new() -> Self {
|
||||
let mut reader = csv::Reader::from_path("resources/dictionary.csv").unwrap();
|
||||
let mut words: Vec<String> = Vec::new();
|
||||
let mut scores: Vec<f64> = Vec::new();
|
||||
impl Dictionary for HashMap<String, f64> {
|
||||
|
||||
fn create(path: &str) -> Self {
|
||||
let mut reader = csv::Reader::from_path(path).unwrap();
|
||||
let mut map = HashMap::new();
|
||||
|
||||
for result in reader.records() {
|
||||
let record = result.unwrap();
|
||||
words.push(record.get(0).unwrap().to_string());
|
||||
let word = record.get(0).unwrap().to_string();
|
||||
|
||||
let score = record.get(1).unwrap();
|
||||
scores.push(f64::from_str(score).unwrap());
|
||||
let score = f64::from_str(score).unwrap();
|
||||
|
||||
map.insert(word, score);
|
||||
|
||||
}
|
||||
|
||||
Dictionary {
|
||||
words,
|
||||
scores,
|
||||
}
|
||||
map
|
||||
}
|
||||
|
||||
fn filter_to_sub_dictionary(&self, proportion: f64) -> Self {
|
||||
let mut words: Vec<String> = Vec::new();
|
||||
let mut scores: Vec<f64> = Vec::new();
|
||||
let mut map = HashMap::new();
|
||||
|
||||
for (word, score) in self.words.iter().zip(self.scores.iter()) {
|
||||
for (word, score) in self.iter() {
|
||||
if *score >= proportion {
|
||||
words.push(word.clone());
|
||||
scores.push(*score);
|
||||
map.insert(word.clone(), *score);
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary {words, scores}
|
||||
map
|
||||
|
||||
}
|
||||
|
||||
fn substring_set(&self) -> HashSet<&str> {
|
||||
let mut set = HashSet::new();
|
||||
|
||||
for word in self.words.iter() {
|
||||
for (word, _score) in self.iter() {
|
||||
for j in 0..word.len() {
|
||||
for k in (j+1)..(word.len()+1) {
|
||||
set.insert(&word[j..k]);
|
||||
|
@ -142,7 +142,11 @@ impl Dictionary {
|
|||
set
|
||||
}
|
||||
|
||||
fn is_word_valid(&self, word: &Word) -> bool {
|
||||
|
||||
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -156,6 +160,18 @@ struct Word<'a> {
|
|||
coords: Coordinates,
|
||||
}
|
||||
|
||||
impl<'a> ToString for Word<'a> {
|
||||
fn to_string(&self) -> String {
|
||||
let mut text = String::with_capacity(self.cells.len());
|
||||
for cell in self.cells.as_slice() {
|
||||
text.push(cell.value.as_ref().unwrap().text);
|
||||
}
|
||||
|
||||
text
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
impl <'a> Word<'a> {
|
||||
|
||||
fn calculate_score(&self) -> u32{
|
||||
|
@ -368,8 +384,15 @@ impl Board {
|
|||
return Err("Played tiles cannot have empty gap");
|
||||
}
|
||||
|
||||
|
||||
// don't want the case of a single letter word
|
||||
if main_word.cells.len() > 1 {
|
||||
words.push(main_word);
|
||||
} else if words.is_empty() {
|
||||
return Err("All words must be at least one letter");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// need to verify that the play is 'anchored'
|
||||
let mut anchored = false;
|
||||
|
@ -552,15 +575,6 @@ mod tests {
|
|||
board.get_cell_mut(Coordinates(9, 8)).unwrap().value = Some(Letter::new_fixed( 'G', 0));
|
||||
board.get_cell_mut(Coordinates(10, 8)).unwrap().value = Some(Letter::new_fixed( 'G', 0));
|
||||
|
||||
fn word_to_text(word: Word) -> String {
|
||||
let mut text = String::with_capacity(word.cells.len());
|
||||
for cell in word.cells {
|
||||
text.push(cell.value.as_ref().unwrap().text);
|
||||
}
|
||||
|
||||
text
|
||||
}
|
||||
|
||||
for x in vec![6, 7, 8, 9] {
|
||||
println!("x is {}", x);
|
||||
let first_word = board.find_word_at_position(Coordinates(8, x), Direction::Column);
|
||||
|
@ -570,7 +584,7 @@ mod tests {
|
|||
assert_eq!(x.coords.0, 8);
|
||||
assert_eq!(x.coords.1, 6);
|
||||
|
||||
assert_eq!(word_to_text(x), "JOEL");
|
||||
assert_eq!(x.to_string(), "JOEL");
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -583,7 +597,7 @@ mod tests {
|
|||
assert_eq!(x.coords.0, 8);
|
||||
assert_eq!(x.coords.1, 9);
|
||||
|
||||
assert_eq!(word_to_text(x), "L");
|
||||
assert_eq!(x.to_string(), "L");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -596,7 +610,7 @@ mod tests {
|
|||
assert_eq!(x.coords.0, 0);
|
||||
assert_eq!(x.coords.1, 0);
|
||||
|
||||
assert_eq!(word_to_text(x), "IS");
|
||||
assert_eq!(x.to_string(), "IS");
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -611,7 +625,7 @@ mod tests {
|
|||
assert_eq!(x.coords.0, 3);
|
||||
assert_eq!(x.coords.1, 0);
|
||||
|
||||
assert_eq!(word_to_text(x), "COOL");
|
||||
assert_eq!(x.to_string(), "COOL");
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -627,7 +641,7 @@ mod tests {
|
|||
assert_eq!(x.coords.0, 8);
|
||||
assert_eq!(x.coords.1, 8);
|
||||
|
||||
assert_eq!(word_to_text(x), "EGG");
|
||||
assert_eq!(x.to_string(), "EGG");
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -636,6 +650,63 @@ mod tests {
|
|||
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_word_finding_one_letter() {
|
||||
let mut board = Board::new();
|
||||
|
||||
board.get_cell_mut(Coordinates(7, 7)).unwrap().value = Some(Letter {
|
||||
text: 'I',
|
||||
points: 1,
|
||||
ephemeral: true,
|
||||
is_blank: false,
|
||||
});
|
||||
|
||||
match board.find_played_words() {
|
||||
Ok(_) => {panic!("Expected error")}
|
||||
Err(e) => {assert_eq!(e, "All words must be at least one letter");}
|
||||
}
|
||||
|
||||
board.get_cell_mut(Coordinates(7, 7)).unwrap().value = Some(Letter {
|
||||
text: 'I',
|
||||
points: 1,
|
||||
ephemeral: false, // fixed now
|
||||
is_blank: false,
|
||||
});
|
||||
|
||||
board.get_cell_mut(Coordinates(7, 8)).unwrap().value = Some(Letter {
|
||||
text: 'S',
|
||||
points: 1,
|
||||
ephemeral: true,
|
||||
is_blank: false,
|
||||
});
|
||||
|
||||
let words = board.find_played_words().unwrap();
|
||||
assert_eq!(words.len(), 1);
|
||||
let word = words.first().unwrap();
|
||||
assert_eq!(word.calculate_score(), 2);
|
||||
|
||||
// making fixed
|
||||
board.get_cell_mut(Coordinates(7, 8)).unwrap().value = Some(Letter {
|
||||
text: 'S',
|
||||
points: 1,
|
||||
ephemeral: false,
|
||||
is_blank: false,
|
||||
});
|
||||
|
||||
// trying other orientation
|
||||
board.get_cell_mut(Coordinates(8, 7)).unwrap().value = Some(Letter {
|
||||
text: 'S',
|
||||
points: 1,
|
||||
ephemeral: true,
|
||||
is_blank: false,
|
||||
});
|
||||
|
||||
let words = board.find_played_words().unwrap();
|
||||
assert_eq!(words.len(), 1);
|
||||
let word = words.first().unwrap();
|
||||
assert_eq!(word.calculate_score(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_word_finding_anchor() {
|
||||
let mut board = Board::new();
|
||||
|
@ -741,15 +812,6 @@ mod tests {
|
|||
board.get_cell_mut(Coordinates(5, 0)).unwrap().value = Some(Letter::new_fixed('O', 1));
|
||||
board.get_cell_mut(Coordinates(6, 0)).unwrap().value = Some(Letter::new_fixed('L', 1));
|
||||
|
||||
fn word_to_text(word: &Word) -> String {
|
||||
let mut text = String::with_capacity(word.cells.len());
|
||||
for cell in word.cells.as_slice() {
|
||||
text.push(cell.value.as_ref().unwrap().text);
|
||||
}
|
||||
|
||||
text
|
||||
}
|
||||
|
||||
fn check_board(board: &mut Board, inverted: bool) {
|
||||
println!("{}", board);
|
||||
let words = board.find_played_words();
|
||||
|
@ -757,7 +819,7 @@ mod tests {
|
|||
Ok(x) => {
|
||||
assert_eq!(x.len(), 1);
|
||||
let word = x.get(0).unwrap();
|
||||
assert_eq!(word_to_text(word), "JOEL");
|
||||
assert_eq!(word.to_string(), "JOEL");
|
||||
|
||||
assert_eq!(word.calculate_score(), 8 + 1 + 2 + 1);
|
||||
}
|
||||
|
@ -788,7 +850,7 @@ mod tests {
|
|||
assert_eq!(x.coords.0, 8);
|
||||
assert_eq!(x.coords.1, 8);
|
||||
|
||||
assert_eq!(word_to_text(&x), "EGG");
|
||||
assert_eq!(x.to_string(), "EGG");
|
||||
assert_eq!(x.calculate_score(), 2 + 2 + 2);
|
||||
|
||||
}
|
||||
|
@ -799,11 +861,11 @@ mod tests {
|
|||
Ok(x) => {
|
||||
assert_eq!(x.len(), 2);
|
||||
let word = x.get(0).unwrap();
|
||||
assert_eq!(word_to_text(word), "EGG");
|
||||
assert_eq!(word.to_string(), "EGG");
|
||||
assert_eq!(word.calculate_score(), 2 + 2 + 2);
|
||||
|
||||
let word = x.get(1).unwrap();
|
||||
assert_eq!(word_to_text(word), "JOEL");
|
||||
assert_eq!(word.to_string(), "JOEL");
|
||||
assert_eq!(word.calculate_score(), 8 + 1 + 2 + 1);
|
||||
}
|
||||
Err(e) => { panic!("Expected to find a word to play; found error {}", e) }
|
||||
|
@ -847,29 +909,28 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_dictionary() {
|
||||
let dictionary = Dictionary::new();
|
||||
let dictionary = HashMap::create("resources/dictionary.csv");
|
||||
|
||||
assert_eq!(dictionary.words.len(), dictionary.scores.len());
|
||||
assert_eq!(dictionary.words.len(), 279429);
|
||||
assert_eq!(dictionary.len(), 279429);
|
||||
|
||||
assert_eq!(dictionary.words.get(0).unwrap(), "AA");
|
||||
assert_eq!(dictionary.words.get(9).unwrap(), "AARDVARK");
|
||||
assert!(dictionary.contains_key("AA"));
|
||||
assert!(dictionary.contains_key("AARDVARK"));
|
||||
|
||||
assert!((dictionary.scores.get(9).unwrap() - 0.5798372).abs() < 0.0001)
|
||||
assert!((dictionary.get("AARDVARK").unwrap() - 0.5798372).abs() < 0.0001)
|
||||
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_dictionary_sets() {
|
||||
let dictionary = Dictionary {
|
||||
words: vec!["JOEL".to_string(), "JOHN".to_string(), "XYZ".to_string()],
|
||||
scores: vec![0.7, 0.5, 0.1],
|
||||
};
|
||||
let mut dictionary = HashMap::new();
|
||||
dictionary.insert("JOEL".to_string(), 0.7);
|
||||
dictionary.insert("JOHN".to_string(), 0.5);
|
||||
dictionary.insert("XYZ".to_string(), 0.1);
|
||||
|
||||
let dictionary = dictionary.filter_to_sub_dictionary(0.3);
|
||||
assert_eq!(dictionary.words.len(), 2);
|
||||
assert_eq!(dictionary.words.get(0).unwrap(), "JOEL");
|
||||
assert_eq!(dictionary.words.get(1).unwrap(), "JOHN");
|
||||
assert_eq!(dictionary.len(), 2);
|
||||
assert!(dictionary.contains_key("JOEL"));
|
||||
assert!(dictionary.contains_key("JOHN"));
|
||||
|
||||
let set = dictionary.substring_set();
|
||||
|
||||
|
|
Loading…
Reference in a new issue