In this program you have to solve 20 exercises. The time you need will be measured. If you break a record, you'll get an entry in the highscore list.
The program can be downloaded here. You can only start it via command line, not by double-click.
If I can improve my code to make it more readable, please tell me how.
Main.java
import java.time.Duration;
import java.time.Instant;
import java.util.Scanner;
import java.io.File;
import java.io.ObjectOutputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.FileInputStream;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
new Main().mainLoop();
}
private static String saveName = ".mathematicianSave";
private static Scanner scanner = new Scanner(System.in);
private RecordList recordList;
public Main() {
if (new File(saveName).exists()) {
try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(saveName))) {
recordList = (RecordList)ois.readObject();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
} else {
recordList = new RecordList(5);
}
}
private void mainLoop() {
System.out.println("[0] Leave\n");
while(true) {
System.out.println("[1] Play");
System.out.println("[2] Highscore");
System.out.print("Input: ");
String decision = scanner.nextLine();
System.out.println();
if (decision.equals("1")) {
calculate();
} else if (decision.equals("2")) {
showHighscore();
} else if (decision.equals("0")) {
save();
break;
}
}
}
private void calculate() {
System.out.println("Division exercises have to be solved without rest.");
System.out.println("You have to solve twenty exercises.");
System.out.println("Be as fast as you can!\n");
Instant startTime = Instant.now();
for (int i = 0; i < 20; i++) {
Exercise exercise = Exercise.getRandomExercise();
System.out.print(exercise);
int guess = Integer.parseInt(scanner.nextLine());
exercise.solve(guess);
if (!exercise.solve(guess)) {
System.out.println("\nYou have made a mistake.");
System.out.println("More luck next time.\n");
return;
}
}
System.out.println();
Instant endTime = Instant.now();
Duration timeElapsed = Duration.between(startTime, endTime);
double seconds = timeElapsed.toMillis() / 1000.0;
Record record = new Record(seconds);
System.out.println("You have needed " + seconds + " seconds.");
if (recordList.add(record)) {
System.out.println("You have set a new record!");
System.out.print("Your name: ");
record.setName(scanner.nextLine());
}
System.out.println();
}
private void showHighscore() {
System.out.println(recordList);
}
private void save() {
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(saveName))) {
oos.writeObject(recordList);
} catch (IOException e) {
e.printStackTrace();
}
}
}
Exercise.java
import java.util.Random;
public class Exercise {
private int number1;
private int number2;
private int solution;
private String operationSymbol;
private Exercise(int number1, int number2, int solution, String operationSymbol) {
this.number1 = number1;
this.number2 = number2;
this.solution = solution;
this.operationSymbol = operationSymbol;
}
public static Exercise getRandomExercise() {
Random random = new Random();
int choice = random.nextInt(4);
int number1;
int number2;
int solution;
String operationSymbol;
if (choice == 0) {
number1 = random.nextInt(26);
number2 = random.nextInt(26);
solution = number1 + number2;
operationSymbol = "+";
} else if (choice == 1) {
number1 = random.nextInt(16) + 10;
number2 = random.nextInt(26);
solution = number1 - number2;
operationSymbol = "-";
} else if (choice == 2) {
number1 = random.nextInt(15) + 1;
number2 = random.nextInt(15) + 1;
solution = number1 * number2;
operationSymbol = "*";
} else {
number1 = random.nextInt(151);
number2 = random.nextInt(15) + 1;
solution = number1 / number2;
operationSymbol = "/";
}
return new Exercise(number1, number2, solution, operationSymbol);
}
public boolean solve(int guess) {
return solution == guess;
}
@Override
public String toString() {
return number1 + " " + operationSymbol + " " + number2 + " = ";
}
}
Record.java
import java.io.Serializable;
public class Record implements Serializable {
private String name;
private double seconds;
public Record(double seconds) {
name = null;
this.seconds = seconds;
}
public Record(String name, double seconds) {
this.name = name;
this.seconds = seconds;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public double getSeconds() {
return seconds;
}
}
RecordList.java
import java.util.Comparator;
import java.util.List;
import java.util.ArrayList;
import java.io.Serializable;
public class RecordList implements Serializable {
private List<Record> records;
private int limit;
public RecordList(int limit) {
records = new ArrayList<>();
this.limit = limit;
}
private void sort() {
records.sort(new Comparator<Record>() {
@Override
public int compare(Record record1, Record record2) {
Double double1 = record1.getSeconds();
Double double2 = record2.getSeconds();
return double1.compareTo(double2);
}
});
}
public boolean add(Record record) {
if (records.size() < limit) {
records.add(record);
sort();
return true;
}
Record lowestRecord = records.get(records.size() - 1);
if (record.getSeconds() < lowestRecord.getSeconds()) {
records.remove(lowestRecord);
records.add(record);
sort();
return true;
}
return false;
}
@Override
public String toString() {
if (records.isEmpty()) {
return "No records.\n";
}
StringBuilder returnValue = new StringBuilder("--- Records ---\n\n");
for (int i = 0; i < records.size(); i++) {
returnValue.append(i+1);
returnValue.append(". ");
returnValue.append(records.get(i).getName());
returnValue.append(" - ");
returnValue.append(records.get(i).getSeconds());
returnValue.append("\n");
}
return returnValue.toString();
}
}