boggle_maker/
builder.rs

1use crate::genetic_boggle_maker;
2use crate::boggle_board::Board;
3use word_trie::TrieBuilder;
4
5///The boggle board builder struct
6#[derive(Default)]
7pub struct BoggleBuilder {
8    width : Option<usize>,
9    length : Option<usize>,
10    target_score: Option<isize>,
11    dictionary_path: Option<String>,
12}
13
14impl BoggleBuilder {
15    ///initiates a new instance of the boggle board builder
16    pub fn new() -> Self {
17        Self::default()
18    }
19
20    ///sets the trie dictionary text file path
21    pub fn with_dictionary_path<P: Into<String>>(mut self, path: P) -> Self {
22        self.dictionary_path = Some(path.into());
23        self
24    } 
25
26    ///sets the desired target score for the board to be generated
27    pub fn with_target_score(mut self, score: isize) -> Self {
28        self.target_score = Some(score);
29        self
30    } 
31
32    ///sets the board's width
33    pub fn with_width(mut self, width: usize) -> Self {
34        self.width = Some(width);
35        self
36    } 
37
38    ///sets the board's length
39    pub fn with_length(mut self, length: usize) -> Self {
40        self.length = Some(length);
41        self
42    } 
43
44    ///generates a boggle board instance
45    ///
46    /// # Examples
47    ///
48    /// ```
49    /// use boggle_maker::BoggleBuilder;
50    /// let builder = BoggleBuilder::new()
51    ///.with_dictionary_path("words.txt")
52    ///.with_target_score(2500)
53    ///.with_length(4)
54    ///.with_width(4);
55    ///
56    ///if let Some(board) = builder.build().expect("Failed to load trie from words.txt file"){
57    ///   assert!(board.score().unwrap()>=2500);
58    ///}
59    ///else{
60    ///assert!(false);
61    ///}
62    /// ```
63    pub fn build(self) -> Result<Option<Board>, std::io::Error> {
64        let width = match self.width {
65            Some(w) => w,
66            None => 4,
67        };
68
69        let length = match self.length {
70            Some(l) => l,
71            None => 4,
72        };
73
74        let target_score = match self.target_score {
75            Some(score) => score,
76            None => 0,
77        };
78
79        if let Some(path) = self.dictionary_path {
80            let trie = TrieBuilder::new()
81            .from_file(path)
82            .expect("Failed to load trie from file");
83
84            let board = genetic_boggle_maker::make(width,length,target_score,&trie);
85            return Ok(board);
86        }
87
88        Ok(None)
89    }
90}
91
92#[cfg(test)]
93mod tests{
94
95    use super::*;
96
97    #[test]
98    fn should_generate_a_board_with_3600_score(){
99        should_generate_a_board_with_deired_score(3200);
100    }
101
102    #[test]
103    fn should_generate_a_board_with_2500_score(){
104        should_generate_a_board_with_deired_score(2500);
105    }
106
107    fn should_generate_a_board_with_deired_score(score:isize){
108        let builder = BoggleBuilder::new()
109         .with_dictionary_path("words.txt")
110         .with_target_score(score)
111         .with_length(4)
112         .with_width(4);
113        
114         if let Some(board) = builder.build().expect("Failed to load trie from words.txt file"){
115            assert!(board.score().unwrap()>=score);
116         }
117         else{
118         assert!(false);
119        }
120    }
121}