I learned something about threads and I tried to use them in an programming exercise. The user of the program has to solve as many exercises as he can within twenty seconds. After that time the program stops and and prints some statistical values.
Is my implementation a good implementation? Are there any blemishes or rookie mistakes that can be eliminated? I would be very thankful for a code review!
An executable can be downloaded here
Package game
Game.java
package game;
import game.TimeCounter;
import game.exercise.Examiner;
public class Game {
public static void main(String[] args) {
System.out.println("You have to solve as many exercises as you can " +
"within 20 seconds");
Examiner examiner = new Examiner();
examiner.start();
TimeCounter timeCounter = new TimeCounter(examiner, 20);
timeCounter.countTimeAndInterrupt();
examiner.printStats();
}
}
TimeCounter.java
package game;
import game.exercise.Examiner;
public class TimeCounter {
private Examiner examiner;
private int seconds;
public TimeCounter(Examiner examiner, int seconds) {
this.examiner = examiner;
this.seconds = seconds;
}
public void countTimeAndInterrupt() {
for(int i = 0; i < seconds; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
examiner.stop();
}
}
Package game.exercise
Examiner.java
package game.exercise;
import java.util.Scanner;
public class Examiner extends Thread {
private int right; // number of exercises solved right
private int wrong;
@Override
public void run() {
Scanner scanner = new Scanner(System.in);
while (true) {
int input;
Exercise exercise;
exercise = Exercise.getRandomExercise();
System.out.print(exercise);
input = scanner.nextInt();
if (exercise.check(input)) {
right++;
System.out.println("Right!");
} else {
wrong++;
System.out.println("Wrong!");
}
}
}
public void printStats() {
System.out.println();
System.out.println("Number of all exercises: " +
getNumberOfExercises());
System.out.println("Exercises solved right: " + right);
System.out.println("Exercises solved wrong: " + wrong);
int percentage = (int)((float)(right) / getNumberOfExercises() * 100);
System.out.println("Rate: " + percentage + " % ");
}
public int getNumberOfExercises() {
return right + wrong;
}
}
Exercise.java
package game.exercise;
import java.util.Random;
public class Exercise {
private static Random random = new Random();
private int number1;
private int number2;
private Type type;
public Exercise(Type type, int number1, int number2) {
this.type = type;
this.number1 = number1;
this.number2 = number2;
}
public static Exercise getRandomExercise() {
return getRandomExercise(Type.random());
}
public static Exercise getRandomExercise(Type type) {
switch(type) {
case ADDITION:
case SUBTRACTION:
return new Exercise(type, random.nextInt(40) + 1,
random.nextInt(40) + 1);
case MULTIPLICATION:
return new Exercise(type, random.nextInt(20) + 1,
random.nextInt(20) + 1);
case DIVISION:
return new Exercise(type, random.nextInt(100) + 1,
random.nextInt(15) + 1);
default: throw new IllegalArgumentException("not a valid type");
}
}
@Override
public String toString() {
return number1 + " " + getOperator() + " " + number2 + " = ";
}
private String getOperator() {
switch(type) {
case ADDITION: return "+";
case SUBTRACTION: return "-";
case MULTIPLICATION: return "*";
case DIVISION: return "/";
default: throw new IllegalArgumentException("not a valid type");
}
}
private int getSolution() {
switch(type) {
case ADDITION: return number1 + number2;
case SUBTRACTION: return number1 - number2;
case MULTIPLICATION: return number1 * number2;
case DIVISION: return (int)(number1 / number2);
default: throw new IllegalArgumentException("not a valid type");
}
}
public boolean check(int guess) {
return getSolution() == guess;
}
}
Type.java
package game.exercise;
import java.util.Random;
public enum Type {
ADDITION, SUBTRACTION, MULTIPLICATION, DIVISION;
public static Type random() {
Random random = new Random();
int choice = random.nextInt(4);
if(choice == 0) return ADDITION;
else if(choice == 1) return SUBTRACTION;
else if(choice == 2) return MULTIPLICATION;
else if(choice == 3) return DIVISION;
else throw new IllegalArgumentException();
}
}