Skip to content

Commit 9b649be

Browse files
committed
Per column judge count
1 parent 3cffd58 commit 9b649be

File tree

5 files changed

+177
-0
lines changed

5 files changed

+177
-0
lines changed
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
package bms.player.beatoraja.modmenu;
2+
3+
import bms.model.Mode;
4+
import bms.player.beatoraja.play.JudgeResult;
5+
import org.apache.commons.lang3.tuple.Pair;
6+
7+
import java.util.Map;
8+
import java.util.concurrent.ConcurrentHashMap;
9+
import java.util.concurrent.atomic.AtomicInteger;
10+
11+
/**
12+
* Track the current judge count
13+
*/
14+
public class JudgeCountTracker {
15+
// column count
16+
private final int columnCount;
17+
private final int[] scratchKeys;
18+
// (column, judge) -> count
19+
private final Map<Pair<Integer, JudgeResult>, AtomicInteger> counts = new ConcurrentHashMap<>();
20+
// column -> (fast, slow)
21+
private final Map<Integer, Pair<AtomicInteger, AtomicInteger>> fsCounts = new ConcurrentHashMap<>();
22+
23+
public JudgeCountTracker(Mode playMode) {
24+
this.columnCount = playMode.key;
25+
this.scratchKeys = playMode.scratchKey;
26+
for (int i = 0; i < columnCount; i++) {
27+
for (JudgeResult judge : JudgeResult.values()) {
28+
counts.put(Pair.of(i, judge), new AtomicInteger());
29+
}
30+
fsCounts.put(i, Pair.of(new AtomicInteger(), new AtomicInteger()));
31+
}
32+
}
33+
34+
public void track(int lane, int judge, boolean fast, int count) {
35+
JudgeResult judgeResult = JudgeResult.valueOf(judge);
36+
counts.get(Pair.of(lane, judgeResult)).addAndGet(count);
37+
// TODO: Allow user define their own interval?
38+
if (judgeResult != JudgeResult.PGREAT) {
39+
Pair<AtomicInteger, AtomicInteger> fs = fsCounts.get(lane);
40+
if (fast) {
41+
fs.getLeft().incrementAndGet();
42+
} else {
43+
fs.getRight().incrementAndGet();
44+
}
45+
}
46+
}
47+
48+
public int getCount(int lane, JudgeResult judge) {
49+
return counts.get(Pair.of(lane, judge)).get();
50+
}
51+
52+
public int getFastCount(int lane) {
53+
return fsCounts.get(lane).getLeft().get();
54+
}
55+
56+
public int getSlowCount(int lane) {
57+
return fsCounts.get(lane).getRight().get();
58+
}
59+
60+
public int getColumnCount() {
61+
return columnCount;
62+
}
63+
64+
public int[] getScratchKeys() {
65+
return scratchKeys;
66+
}
67+
}

core/src/bms/player/beatoraja/modmenu/JudgeTrainer.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,19 @@
22

33
import bms.model.Mode;
44
import bms.player.beatoraja.play.BMSPlayerRule;
5+
import org.apache.commons.lang3.tuple.Pair;
6+
7+
import java.util.HashMap;
8+
import java.util.Map;
59

610
public class JudgeTrainer {
711
public static final String[] JUDGE_OPTIONS = new String[]{
812
"EASY", "NORMAL", "HARD", "VERY_HARD"
913
};
1014
private static boolean active;
1115
private static int judgeRank = 0;
16+
// NOTE: judgeCountTracker must have an initialized value to allow mod menu draw the table
17+
private static volatile JudgeCountTracker judgeCountTracker = new JudgeCountTracker(Mode.BEAT_7K);
1218

1319
public static boolean isActive() {
1420
return active;
@@ -37,5 +43,13 @@ public static int getJudgeWindowRate(Mode mode) {
3743
BMSPlayerRule rule = BMSPlayerRule.getBMSPlayerRule(mode);
3844
return rule.judge.windowrule.judgerank[3 - judgeRank];
3945
}
46+
47+
public static void setJudgeCountTracker(JudgeCountTracker judgeCountTracker) {
48+
JudgeTrainer.judgeCountTracker = judgeCountTracker;
49+
}
50+
51+
public static JudgeCountTracker getJudgeCountTracker() {
52+
return judgeCountTracker;
53+
}
4054
}
4155

core/src/bms/player/beatoraja/modmenu/JudgeTrainerMenu.java

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
package bms.player.beatoraja.modmenu;
22

3+
import bms.player.beatoraja.play.JudgeResult;
34
import imgui.ImGui;
45
import imgui.flag.ImGuiCond;
6+
import imgui.flag.ImGuiTableFlags;
57
import imgui.flag.ImGuiWindowFlags;
68
import imgui.type.ImBoolean;
79
import imgui.type.ImInt;
10+
import javafx.util.Pair;
11+
12+
import java.util.Arrays;
13+
import java.util.HashMap;
814

915
import static bms.player.beatoraja.modmenu.ImGuiRenderer.windowHeight;
1016
import static bms.player.beatoraja.modmenu.ImGuiRenderer.windowWidth;
@@ -25,7 +31,53 @@ public static void show(ImBoolean showJudgeTrainer) {
2531
if (ImGui.combo("judge", OVERRIDE_JUDGE_RANK, JudgeTrainer.JUDGE_OPTIONS)) {
2632
JudgeTrainer.setJudgeRank(OVERRIDE_JUDGE_RANK.get());
2733
}
34+
renderJudgeCountTable();
2835
ImGui.end();
2936
}
3037
}
38+
39+
private static void renderJudgeCountTable() {
40+
JudgeCountTracker tracker = JudgeTrainer.getJudgeCountTracker();
41+
int columnCount = tracker.getColumnCount();
42+
int[] scratchKeys = tracker.getScratchKeys();
43+
if (ImGui.beginTable("Judge Count", columnCount + 1, ImGuiTableFlags.Borders | ImGuiTableFlags.ScrollY, 0, ImGui.getTextLineHeight() * 20)) {
44+
ImGui.tableSetupColumn("/");
45+
for (int i = 0; i < columnCount; i++) {
46+
int finalI = i;
47+
boolean isScratchKey = Arrays.stream(scratchKeys).anyMatch(lane -> lane == finalI);
48+
if (isScratchKey) {
49+
ImGui.tableSetupColumn(String.format("%d(SC)", i));
50+
} else {
51+
ImGui.tableSetupColumn(String.valueOf(i));
52+
}
53+
}
54+
ImGui.tableHeadersRow();
55+
// Judgements
56+
for (JudgeResult judgeResult : JudgeResult.values()) {
57+
ImGui.tableNextRow();
58+
ImGui.tableNextColumn();
59+
ImGui.text(judgeResult.getName());
60+
for (int i = 0;i < columnCount; ++i) {
61+
ImGui.tableNextColumn();
62+
ImGui.text(String.valueOf(tracker.getCount(i, judgeResult)));
63+
}
64+
}
65+
// Fast/Slow
66+
ImGui.tableNextRow();
67+
ImGui.tableNextColumn();
68+
ImGui.text("Fast");
69+
for (int i = 0;i < columnCount; ++i) {
70+
ImGui.tableNextColumn();
71+
ImGui.text(String.valueOf(tracker.getFastCount(i)));
72+
}
73+
ImGui.tableNextRow();
74+
ImGui.tableNextColumn();
75+
ImGui.text("Slow");
76+
for (int i = 0;i < columnCount; ++i) {
77+
ImGui.tableNextColumn();
78+
ImGui.text(String.valueOf(tracker.getSlowCount(i)));
79+
}
80+
ImGui.endTable();
81+
}
82+
}
3183
}

core/src/bms/player/beatoraja/play/JudgeManager.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import java.util.Arrays;
66
import java.util.stream.IntStream;
77

8+
import bms.player.beatoraja.modmenu.JudgeCountTracker;
9+
import bms.player.beatoraja.modmenu.JudgeTrainer;
810
import com.badlogic.gdx.utils.FloatArray;
911

1012
import bms.model.*;
@@ -35,6 +37,7 @@ public class JudgeManager {
3537
* 現在の判定カウント内訳
3638
*/
3739
private ScoreData score = new ScoreData();
40+
private JudgeCountTracker judgeCountTracker;
3841

3942
/**
4043
* 現在のコンボ数
@@ -146,6 +149,8 @@ public void init(BMSModel model, PlayerResource resource) {
146149
score = new ScoreData(orgmode);
147150
score.setNotes(model.getTotalNotes());
148151
score.setSha256(model.getSHA256());
152+
judgeCountTracker = new JudgeCountTracker(orgmode);
153+
JudgeTrainer.setJudgeCountTracker(judgeCountTracker);
149154
ghost = new int[model.getTotalNotes()];
150155
for (int i=0; i<ghost.length; i++) {
151156
ghost[i] = 4;
@@ -706,6 +711,7 @@ private void updateMicro(LaneState state, Note n, long mtime, int judge, long mf
706711
}
707712
n.setMicroPlayTime(mfast);
708713
score.addJudgeCount(judge, mfast >= 0, 1);
714+
judgeCountTracker.track(state.lane, judge, mfast >= 0, 1);
709715

710716
if (judge < 4) {
711717
recentJudgesIndex = (recentJudgesIndex + 1) % recentJudges.length;
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package bms.player.beatoraja.play;
2+
3+
public enum JudgeResult {
4+
PGREAT("PGREAT", 0),
5+
GREAT("GREAT", 1),
6+
GOOD("GOOD", 2),
7+
BAD("BAD", 3),
8+
POOR("POOR", 4),
9+
MISS("MISS", 5);
10+
11+
private String name;
12+
private int value;
13+
14+
JudgeResult(String name, int value) {
15+
this.name = name;
16+
this.value = value;
17+
}
18+
19+
public static JudgeResult valueOf(int value) {
20+
return switch (value) {
21+
case 0 -> PGREAT;
22+
case 1 -> GREAT;
23+
case 2 -> GOOD;
24+
case 3 -> BAD;
25+
case 4 -> POOR;
26+
case 5 -> MISS;
27+
default -> null;
28+
};
29+
}
30+
31+
public String getName() {
32+
return name;
33+
}
34+
35+
public int getValue() {
36+
return value;
37+
}
38+
}

0 commit comments

Comments
 (0)