calculate method
- required FsrsState state,
- required FsrsRating rating,
- required double elapsedDays,
- double targetRetention = 0.9,
Schedule a card given its current state, the user's rating, and the
number of elapsedDays since last review. targetRetention controls the
desired recall probability (default 0.9).
Implementation
FsrsResult calculate({
required FsrsState state,
required FsrsRating rating,
required double elapsedDays,
double targetRetention = 0.9,
}) {
final ratingIdx = rating.index; // 0=again, 1=hard, 2=good, 3=easy
double newStability;
double newDifficulty;
FsrsCardState newState;
if (state.cardState == FsrsCardState.newCard) {
// First review — use initial stability from parameters.
newStability = w[ratingIdx];
newDifficulty = _initDifficulty(ratingIdx);
newState = rating == FsrsRating.again
? FsrsCardState.learning
: FsrsCardState.review;
} else if (rating == FsrsRating.again) {
// Lapse: stability collapses.
newDifficulty = _nextDifficulty(state.difficulty, ratingIdx);
newStability = _stabilityAfterLapse(
state.stability,
newDifficulty,
elapsedDays,
);
newState = FsrsCardState.relearning;
} else {
// Successful recall.
final retrievability = _retrievability(elapsedDays, state.stability);
newDifficulty = _nextDifficulty(state.difficulty, ratingIdx);
newStability = _stabilityAfterRecall(
state.stability,
newDifficulty,
retrievability,
ratingIdx,
);
newState = FsrsCardState.review;
}
final interval = _nextInterval(newStability, targetRetention);
return FsrsResult(
stability: newStability,
difficulty: newDifficulty,
cardState: newState,
intervalDays: interval,
elapsedDays: elapsedDays,
nextReviewAt: DateTime.now().add(Duration(days: interval)),
);
}