diff --git a/src/core/srs.rs b/src/core/srs.rs index 4691e3b..9d34d7c 100644 --- a/src/core/srs.rs +++ b/src/core/srs.rs @@ -1,7 +1,6 @@ use crate::data::entities::CardState; use chrono::{Local, TimeDelta}; use fsrs::FSRS; -use log::{debug, info}; use rand::distr::weighted::WeightedIndex; use rand::prelude::ThreadRng; use rand::prelude::{Distribution, SliceRandom}; @@ -67,6 +66,18 @@ pub struct SemiRandomSRSModule { generator: ThreadRng, } impl SRSModule for SemiRandomSRSModule { + fn new(set: &[&CardState]) -> Self { + let weights = set + .iter() + .map(|s| (100.0 / s.calculated_score()).powf(2.0) * 2.0) + .collect::>(); + + Self { + generator: rng(), + last_weights: WeightedIndex::new(weights).expect("Incorrect weights update"), + history: vec![], + } + } fn next(&mut self, set: &[&CardState]) -> usize { let index = self.last_weights.sample(&mut self.generator); @@ -87,18 +98,6 @@ impl SRSModule for SemiRandomSRSModule { .update_weights(&[(index, &new_weight)]) .expect("update weights error"); } - fn new(set: &[&CardState]) -> Self { - let weights = set - .iter() - .map(|s| (100.0 / s.calculated_score()).powf(2.0) * 2.0) - .collect::>(); - - Self { - generator: rng(), - last_weights: WeightedIndex::new(weights).expect("Incorrect weights update"), - history: vec![], - } - } } impl SemiRandomSRSModule { fn history_len(&self, set: &[&CardState]) -> usize { @@ -114,6 +113,16 @@ pub struct WorstWordsSRSModule { rounds_count: u8, } impl SRSModule for WorstWordsSRSModule { + fn new(_: &[&CardState]) -> Self { + WorstWordsSRSModule { + pool_size: PARTIAL_POOL_SIZE, + rounds_count: 2, + rounds_remaining: 0, + pool: vec![], + queue: vec![], + } + } + fn next(&mut self, set: &[&CardState]) -> usize { if self.rounds_remaining == 0 { self.fill_pool(set); @@ -131,16 +140,6 @@ impl SRSModule for WorstWordsSRSModule { } fn open(&mut self, _: WordOpenMode, _: usize, _: &mut CardState) {} - - fn new(_: &[&CardState]) -> Self { - WorstWordsSRSModule { - pool_size: PARTIAL_POOL_SIZE, - rounds_count: 2, - rounds_remaining: 0, - pool: vec![], - queue: vec![], - } - } } impl WorstWordsSRSModule { fn fill_pool(&mut self, set: &[&CardState]) { @@ -157,9 +156,7 @@ impl WorstWordsSRSModule { #[derive(Clone)] pub struct FsrsModule { - today_set: Vec, - solved: Vec, - current_group: Vec, + next_round: Vec, queue: Vec, rng: ThreadRng, fsrs: FSRS, @@ -170,29 +167,22 @@ impl SRSModule for FsrsModule { let today = Local::now().date_naive(); let mut new = Self { - today_set: set + queue: set .iter() .enumerate() .filter(|(_, c)| c.fsrs_open_day <= today) .map(|(index, _)| index) .collect(), - current_group: vec![], - queue: vec![], - solved: vec![], + next_round: vec![], rng: rng(), fsrs: FSRS::default(), }; - new.today_set.shuffle(&mut new.rng); - new.fill_partial_pool(); + new.queue.shuffle(&mut new.rng); new } fn next(&mut self, _: &[&CardState]) -> usize { - if self.current_group.is_empty() { - self.fill_partial_pool(); - } - if self.queue.is_empty() { self.fill_queue(); self.queue.shuffle(&mut self.rng); @@ -230,37 +220,21 @@ impl SRSModule for FsrsModule { updated_word.fsrs_open_day = next_day; updated_word.fsrs_opened = updated_word.last_open.date_naive(); - if (updated_word.fsrs_open_day != today && !first_time) - || (first_time && status == WordOpenMode::Easy) + if (updated_word.fsrs_open_day == today && !first_time) + || (first_time && status != WordOpenMode::Easy) { - info!("For today word on index {} solved", index); - self.solved.push(index); - let index = self.current_group.iter().position(|x| *x == index).unwrap(); - self.current_group.remove(index); + self.next_round.push(index); } } } impl FsrsModule { - fn fill_partial_pool(&mut self) { - debug!("Filling partial pool"); - self.current_group.extend( - self.today_set - .iter() - .filter(|x| !self.solved.contains(*x)) - .take(PARTIAL_POOL_SIZE), - ); - - self.queue.clear(); - self.queue.extend(self.current_group.clone()); - } - fn fill_queue(&mut self) { - self.queue.extend(self.current_group.clone()); + self.queue.append(&mut self.next_round); } pub fn finished(&self) -> bool { - self.today_set.len() == self.solved.len() + self.queue.is_empty() && self.next_round.is_empty() } }