Page MenuHomedesp's stash

Main.java
No OneTemporary

Main.java

package me.despawningbone.arithtrain;
import java.awt.GraphicsEnvironment;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Map.Entry;
import javafx.animation.FadeTransition;
import javafx.animation.PauseTransition;
import javafx.application.Application;
import javafx.scene.image.Image;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.util.Duration;
/**
* The initializing class for the arithmetic trainer.
* @author despawningbone
*
*/
public class Main extends Application {
/**
* Global precision value for answers accepted for the trainer mode.
*/
public static int precision = 2;
public static void main(String[] args) { //no need to document this function in javadoc as it is the universal entry point of java programs
System.setProperty("prism.lcdtext", "false"); //fix anti aliasing
initConfig();
File pfile = new File(System.getProperty("user.dir") + File.separator + "users.data");
try {
if (pfile.createNewFile()) {
System.out.println("Cannot find user database, created a new one.");
}
} catch (IOException e) {
e.printStackTrace();
}
launch(args);
}
/**
* Initializes the welcome menu and the UIHelper for subsequent GUI pages.<br>
* See the parent method for more information.
* @param main the main window stage to operate on
*/
@Override
public void start(Stage main) throws Exception {
Font.loadFont(Main.class.getClassLoader().getResourceAsStream("resources/GothamBook.ttf"), 10);
Font.loadFont(Main.class.getClassLoader().getResourceAsStream("resources/GothamBold.ttf"), 10);
GraphicsEnvironment g = GraphicsEnvironment.getLocalGraphicsEnvironment(); //resize according to screen
int height = g.getDefaultScreenDevice().getDisplayMode().getHeight() / 2;
int width = g.getDefaultScreenDevice().getDisplayMode().getWidth() / 2;
if(height <= width) width = height / 9 * 16; //bind width to height with 16:9 so that 4:3 and 21:9 wont break the program
else height = width / 16 * 9; //bind to height if height is longer than width to avoid going out of bounds
UIHelper helper = new UIHelper(main, width, height);
main.setTitle("Arithmetic Trainer");
main.setResizable(false); //to avoid issues with resizing; since the window is already proportional
main.getIcons().add(new Image("resources/globe.png"));
main.setHeight(height);
main.setWidth(width);
//welcome
BorderPane welcome = new BorderPane();
Text t = new Text("Welcome to the Arithmetic Trainer");
t.setStyle("-fx-font-size: 3em; -fx-font-weight: bold;");
t.setFill(Color.WHITE);
welcome.setStyle("-fx-background-image: url(\"resources/bg-darken.png\"); -fx-background-size: cover;");
welcome.setCenter(t);
helper.display(welcome, true);
main.show();
//main menu
//transition from welcome to main menu
PauseTransition pause = new PauseTransition(Duration.millis(800));
pause.setOnFinished(p -> {
FadeTransition ft = new FadeTransition(Duration.millis(1200), t);
ft.setFromValue(1.0);
ft.setToValue(0.0);
ft.play();
ft.setOnFinished(f -> helper.showMainMenu());
});
pause.play();
}
/**
* Initializes the configuration, parsing the values into respective variables and generating one if one is not present.
*/
public static void initConfig() {
try {
File pfile = new File(System.getProperty("user.dir") + File.separator + "trainer.conf");
if (pfile.createNewFile()) { //create config
BufferedWriter writer = new BufferedWriter(new FileWriter(pfile));
writer.append("######################\n");
writer.append("# Arithmetic Trainer \n");
writer.append("# By despawningbone \n");
writer.append("# v1.0 \n");
writer.append("######################\n");
writer.append("\n");
writer.append("# At least how many decimal places should the precision be\n");
writer.append("# for the answers inputted to be accepted? (Integer only)\n");
writer.append("# This excludes answers that doesnt need to be rounded,\n");
writer.append("# And does not alter the results in evaluation mode.\n");
writer.append("Precision=2\n");
writer.append("\n");
writer.append("# What percentage will each operator appear?\n");
writer.append("# They should add up to 100.\n");
writer.append("# [+, -, *, /, %]\n");
writer.append("OperatorWeight=35, 25, 17, 13, 10\n");
writer.append("\n");
writer.append("# How many levels should there be?\n");
writer.append("# Each new line represent a level, with the top one being the first.\n");
writer.append("# [requirement, bracketChance, operatorCount, lowerRange, upperRange]\n");
writer.append("# where requirement = score * accuracy,\n");
writer.append("# bracketChance = chance for brackets to appear (0-100),\n");
writer.append("# operatorCount = how many operators the generated expression will have,\n");
writer.append("# lowerRange & upperRange = how large the operand range will be (lower - upper inclusive).\n");
writer.append("# only when the next level is harder and contains only Integer values (except for requirement) will it be valid.\n");
writer.append("# The first level must start from 0.\n");
writer.append("Levels:\n");
writer.append("0, 0, 3, 0, 9\n");
writer.append("50, 10, 4, -10, 20\n");
writer.append("150, 20, 5, -20, 50\n");
writer.close();
System.out.println("Cannot find configuration, created a new one."); //use debug?
initLevels();
initOperators();
} else { //parse config
boolean levelsConfig = false;
for(String line : Files.readAllLines(Paths.get(pfile.getPath()))) {
if(line.isEmpty() || line.startsWith("#")) { //either comments or new line
continue;
} else {
if(line.contains("=")) { //the 2 options
String[] split = line.split("=");
switch(split[0].toLowerCase()) {
case "precision":
try {
precision = Integer.parseInt(split[1].trim());
if(precision < 0) {
precision = 2;
throw new NumberFormatException(); //pass to exception handler
}
} catch (NumberFormatException e) {
System.out.println("Invalid precision value! Using default... (2 d.p.)");
}
break;
case "operatorweight":
try {
int total = 0;
String[] vals = split[1].split(", ?");
String[] ops = {"+", "-", "*", "/", "%"};
for(int i = 0; i < 5; i++) {
int weight = Integer.parseInt(vals[i]);
ExpressionGenerator.operators.put(total, ops[i]);
total += weight;
}
if(total != 100) {
throw new NumberFormatException();
}
} catch (NumberFormatException e) {
System.out.println("Invalid operator weights! Using default... (35, 25, 17, 13, 10)");
initOperators();
}
break;
}
} else if(line.equalsIgnoreCase("Levels:")) { //start of levels config section
levelsConfig = true;
} else if(levelsConfig) { //levels config section
try {
String[] vals = line.split(", ?");
double req = Double.parseDouble(vals[0]);
ExpressionGenerator newGen = new ExpressionGenerator(Integer.parseInt(vals[1]), Integer.parseInt(vals[2]), Integer.parseInt(vals[3]), Integer.parseInt(vals[4]));
Entry<Double, ExpressionGenerator> lowerGen = User.levels.floorEntry(req);
Entry<Double, ExpressionGenerator> higherGen = User.levels.ceilingEntry(req);
if((lowerGen == null || newGen.isHarder(lowerGen.getValue())) && (higherGen == null || higherGen.getValue().isHarder(newGen))) { //verify if the level makes sense with the requirement
User.levels.put(req, newGen);
} else {
throw new NumberFormatException();
}
} catch (NumberFormatException e) {
System.out.println("Invalid levels! Using default...");
initLevels();
}
}
}
}
if(User.levels.isEmpty() || User.levels.firstKey() != 0) {
System.out.println("Invalid levels! Using default...");
User.levels.clear();
initLevels();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Initializes the operator weights with default value.
*/
static void initOperators() {
int[] vals = {0, 35, 60, 77, 90};
String[] ops = {"+", "-", "*", "/", "%"};
for(int i = 0; i < 5; i++) {
ExpressionGenerator.operators.put(vals[i], ops[i]);
}
}
/**
* Initializes the levels with default value.
*/
static void initLevels() {
User.levels.put((double) 0, new ExpressionGenerator(0, 3, 0 ,9)); //initialize levels
User.levels.put((double) 50, new ExpressionGenerator(10, 4, -10, 20));
User.levels.put((double) 150, new ExpressionGenerator(20, 5, -20, 50));
}
}

File Metadata

Mime Type
text/x-c
Expires
Sat, Sep 21, 2:19 AM (19 h, 47 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
b1/e2/1d52e26aa1c9331724642d0ad3d7

Event Timeline