Spaced Repetition System
Due: March 27
Objective
To get more experience working on complex Java programs combining multiple
classes, files, exceptions and the use of the Java API.
Task
For this project, you will create a flash-card like program that will allow
users to study things they wish to memorize. The program will represent a flash
card containing a question, such as "What is the capital of Morocco?"; and an
answer, such as "Rabat".
The program will not ask the user to type the answer in, or check if they got it
right. Instead, it will display the question and then just wait for the user to
show they're ready by pressing enter. It will then show the user the answer and ask
them if they got it right. Since the program is intended for self-study, there's no
reason for the user to lie!
The cards will be organized into multiple decks. For instance, we might have one
deck for world capitals, another for German verbs, and a third for the names of human
bones. Each deck will be stored in a file. The program will let us study the cards in
a deck, add new cards to a deck, and create new decks.
Spaced Repetition
This program will also keep track of when each card is due to be studied
again. The more somebody gets a question wrong, the more often they will need
to review it. Rather than just asking if someone got the question right or
wrong, we will actually provide them with four options:
- Easy
- Correct
- Difficult
- Wrong
Questions that are easy will not be due again for longer than questions that were difficult,
with "correct" ones somewhere in between. Questions the user gets wrong will be repeated again
in this same study session until they get them right.
This idea is called Spaced repetition
and has been shown to be an effective way to memorize information. The program Anki
is an example of a spaced repetition program.
To implement this, each card will store the number of days between reviews. As the user gets the
card correct, this number will increase. It will start at 1, then perhaps go to 2, then 4, then 7,
then 13, and so on. In addition to storing this number, each Card will store a due date. I
recommend using Java's
LocalDate class for this purpose.
Each time a user answers a question, the days between study will be updated. There are many
ways we can do this, but the following scheme will work pretty well:
- If they report that the question is easy, then:
numDays = round((numDays + 1) * 1.5)
- If they report that they got the question correct, then:
numDays = round((numDays + 1) * 1.25)
- If they report that the question is difficult, then:
numDays = round((numDays + 1) * 1.1)
- If they get the question wrong, then:
numDays = 0
Deck File Format
The decks will be stored in a directory called "decks", with a separate
file for each deck. The files will have the ".deck" extension. You can
look at my decks directory which has three decks.
One has some random Spanish words in it, one has all of the capital cities
of the world, and one has all of the elements in the periodic table.
Here are the first few lines of decks/spanish.deck:
manzana
apple
4
2025-03-14
false
pasa
raisin
3
2025-03-12
false
The information for each card takes 5 lines:
- The "question" shown to the user. In the first case this is the Spanish word manzana.
- The answer to the question, which the user is supposed to remember. In the first case,
it's apple, which is the meaning of manzana.
- The number of days the next review is passed the previous one. In this case, the manzana
card is at 4 days between reviews.
- The due date for the card to be studied again. The format is YYYY-MM-DD. The first card
is due on March 14, 2025. Combined with the last detail, we can surmise it was last studied
on the 10th of March.
- Whether or not the card is new or not. A card is new if it has never been studied before.
As soon as it is reviewed, it is marked as no longer being new. The purpose of this is to
prevent a user from being overwhelmed with new cards. When the user studies a deck, only 10
new cards are given, in addition to the old ones that are due for review.
There is one blank line after every card in the file. This just makes the file easier to read
should you open it with a text editor.
Program Operation
Your program provides three main features, which will interact with these deck files:
- Studying a deck. To do this, you will list which deck
files are available, and let the user select one. You will load the deck, and
shuffle it. Then go through each card. If it is due, show it to the user, get
their response and update the Card's day and due date fields. You'll need to
keep track of how many new cards you showed them, limiting it to 10. All
non-new cards that are due should be reviewed. When the review is done, you
will write all of the cards back into the file. That way, the user's progress
is saved.
- Adding cards. For this action, you will list which decks are
available, again letting the user choose one. You will then ask the user for
questions and answers, make them into new cards (with 0 for the days between
study and a due date of today), and add them to the deck. Users should be able
to add multiple cards to a deck in one go (without having to re-choose the
deck). After the user is done adding cards, the deck should be written to the
file.
- Creating a deck. To add a deck, ask the user for the name,
and create a file for it in the "decks" directory, with the ".deck" file extension.
If there is no decks directory, you should create it. Write the empty file when
this is done so that it can be later pulled up for adding cards.
Design
Here is a design you can use as a starting place for this project.

You may add other methods to the classes as well.
A Few Other Points
- It's a little nicer to use if you insert pauses after showing lines of output. You can see the pause method in
our Pig program to review how to do this.
- Another nice thing is to clear the screen between questions. Frustratingly, there is no reliable way to do this in
Java that will work in every terminal. As a work-around, you can just printed out a hundred new lines.
- You will need to look over the LocalDate documentation page
to see how to use it. Learning to read these pages and find what methods you need and how they work is an important skill.
- You will also need to find how to list all of the .deck files in the decks directory, and create the decks directory
if it does not exist. You can research how to do each of these tasks.
You can download example deck files and place them in your project
directory so that you can use them for testing.
General Requirements
When writing your program, also be sure to:
- Put each class/enum in its own file.
- Always use capital letters to begin a class or enum name, and lower-case
letters to begin method and variable names.
- Your code should include comments — at least one for each class
explaining its purpose, and one for each method explaining what its job
is.
- All instance variables should be private.
- Your code should be consistently indented.
- Your program should not crash with an exception under any scenario.
Submitting
You should submit your program by uploading all of the .java files to
Canvas.
Copyright ©
2025
Ian Finlayson | Licensed under a Creative Commons BY-NC-SA 4.0 License.