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.