feat: save highscores per difficulty

This commit is contained in:
Martin Prokoph
2025-09-09 15:03:24 +02:00
parent db537f84ae
commit f881427a67
7 changed files with 64 additions and 27 deletions

View File

@@ -1,13 +1,22 @@
package eu.midnightdust.yaytris;
import eu.midnightdust.yaytris.util.Difficulty;
import eu.midnightdust.yaytris.util.json.Comment;
import eu.midnightdust.yaytris.util.json.NightJson;
import java.util.HashMap;
import java.util.Map;
@SuppressWarnings("unused") // Comments are unused in code, but are added to the JSON file for readability
public class HighScores {
private static final NightJson json = new NightJson(HighScores.class, "tetris_scores.json5");
public static Map<String, Integer> scores = new HashMap<>();
public static Comment c1 = new Comment("Highscores for each difficulty");
public static Map<String, Integer> Noob = new HashMap<>();
public static Map<String, Integer> Easy = new HashMap<>();
public static Map<String, Integer> Normal = new HashMap<>();
public static Map<String, Integer> Hard = new HashMap<>();
public static Map<String, Integer> Extreme = new HashMap<>();
public static Map<String, Integer> WTF = new HashMap<>();
/**
* Saves a new high score for the specified player
@@ -16,10 +25,21 @@ public class HighScores {
* @param score the score to save
*/
public static void addScore(String playerName, int score) {
scores.put(playerName, score);
diffToMap(Settings.difficulty).put(playerName, score);
write();
}
public static Map<String, Integer> diffToMap(Difficulty difficulty) {
switch (difficulty) {
case EASY: return Easy;
case NORMAL: return Normal;
case HARD: return Hard;
case EXTREME: return Extreme;
case WTF: return WTF;
default: return Noob;
}
}
public static void load() {
json.readJson();
}

View File

@@ -97,7 +97,7 @@ public class Tetris {
timer.purge();
if (ui.getMenuPanel() instanceof ScoreMenu) ((ScoreMenu) ui.getMenuPanel()).gameOver();
ui.transferFocus();
if (HighScores.scores.values().stream().noneMatch(hs -> hs > space.getScore())) ui.showHighscoreDialog(space.getScore());
if (HighScores.diffToMap(Settings.difficulty).values().stream().noneMatch(hs -> hs > space.getScore())) ui.showHighscoreDialog(space.getScore());
}
/**

View File

@@ -1,6 +1,7 @@
package eu.midnightdust.yaytris.ui;
import eu.midnightdust.yaytris.HighScores;
import eu.midnightdust.yaytris.Settings;
import eu.midnightdust.yaytris.util.CatppuccinColor;
import javax.swing.*;
@@ -8,6 +9,7 @@ import javax.swing.border.LineBorder;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import static eu.midnightdust.yaytris.Translation.t;
import static eu.midnightdust.yaytris.ui.TetrisUI.scale;
@@ -20,11 +22,12 @@ public class HighScoreMenu extends JPanel {
this.setBounds(x, y, width, height);
this.setLayout(null);
this.add(new JLabel(t("highscores.title")));
this.add(new JLabel(t("highscores.title", Settings.difficulty)));
List<String> highscores = new ArrayList<>();
for (String key : HighScores.scores.keySet()) {
highscores.add(String.format("%s %s", HighScores.scores.get(key), key));
Map<String, Integer> scores = HighScores.diffToMap(Settings.difficulty);
for (String key : scores.keySet()) {
highscores.add(String.format("%s %s", scores.get(key), key));
}
highscores.sort((s1, s2) -> Integer.compare(Integer.parseInt(s2.split("")[0].replace(" ", "")), Integer.parseInt(s1.split("")[0].replace(" ", ""))));
JList<String> highscoreList = new JList<>(highscores.toArray(String[]::new));

View File

@@ -17,7 +17,7 @@ import java.util.regex.Pattern;
* Concept inspired by GSON
*/
public class NightJson {
private static final String KEY_PATTERN = "\"(-?[A-Za-z-_.]*)\":";
private static final String KEY_PATTERN = "\"(.*)\":";
Class<?> jsonClass;
Field jsonMap;
String fileLocation;
@@ -175,21 +175,8 @@ public class NightJson {
private Object getValue(String s, String key, Function<String, Class<?>> keyToType, Iterator<String> pairIterator) {
String val = s.split(KEY_PATTERN, 2)[1];
if (s.contains("{")) { // Handle maps recursively
StringBuilder submapString = new StringBuilder();
int level = charAmount(s, '{');
submapString.append(val);
if (pairIterator.hasNext()) submapString.append(",");
while (pairIterator.hasNext()) {
String next = pairIterator.next();
submapString.append(next);
level += charAmount(next, '{');
level -= charAmount(next, '}');
if (level <= 0) break;
if (pairIterator.hasNext()) submapString.append(",");
}
Optional<Field> field = getField(key);
return jsonToMap(String.valueOf(submapString), k -> field.isPresent() ? getTypeArgument(field.get(), 1) : String.class);
if (s.contains("{")) {
return readJsonMap(key, pairIterator, val);
}
else {
while (val.startsWith(" ")) val = val.substring(1);
@@ -200,6 +187,27 @@ public class NightJson {
}
}
/**
* Handle maps recursively
*/
private Map<String, Object> readJsonMap(String key, Iterator<String> pairIterator, String val) {
StringBuilder submapString = new StringBuilder();
String next = val;
int level = 0;
while (next != null) {
submapString.append(next);
level += charAmount(next, '{');
level -= charAmount(next, '}');
if (level <= 0) break;
if (!pairIterator.hasNext()) {
submapString.append(",");
next = pairIterator.next();
} else next = null;
}
Optional<Field> field = getField(key);
return jsonToMap(String.valueOf(submapString), k -> field.isPresent() ? getTypeArgument(field.get(), 1) : String.class);
}
/**
* Count the amount of appearances of a char in a string.
*

View File

@@ -5,7 +5,7 @@
"game.over": "Game over :(",
"game.score": "Score: %s",
"game.time": "Zeit: %s",
"highscores.title": "Highscores:",
"highscores.title": "Highscores (%s):",
"menu.exit": "Spiel verlassen",
"menu.highscores": "Highscores",
"menu.settings": "Einstellungen",

View File

@@ -5,7 +5,7 @@
"game.over": "Game over :(",
"game.score": "Score: %s",
"game.time": "Time: %s",
"highscores.title": "Highscores:",
"highscores.title": "Highscores (%s):",
"menu.exit": "Exit Game",
"menu.highscores": "Highscores",
"menu.settings": "Settings",

View File

@@ -1,5 +1,11 @@
{
"scores": {
"MartinProkoph": 8040
}
// Highscores for each difficulty
"Noob": {},
"Easy": {},
"Normal": {
"Martin": 10593
},
"Hard": {},
"Extreme": {},
"WTF": {}
}