aboutsummaryrefslogtreecommitdiffstats
path: root/src/app/game/game.stat.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/app/game/game.stat.ts')
-rw-r--r--src/app/game/game.stat.ts82
1 files changed, 82 insertions, 0 deletions
diff --git a/src/app/game/game.stat.ts b/src/app/game/game.stat.ts
new file mode 100644
index 0000000..43136e6
--- /dev/null
+++ b/src/app/game/game.stat.ts
@@ -0,0 +1,82 @@
+export interface GState {
+ displayedLineIdx: number;
+ typedCount: number;
+ lineCompleted: boolean;
+ combo: number;
+ maxCombo: number;
+ score: number;
+ totalCorrect: number;
+ totalMiss: number;
+ linesCleared: number;
+ wpm: number;
+}
+
+export type GAction =
+ | { type: "ADVANCE"; newIdx: number; prevCompleted: boolean }
+ | { type: "CORRECT"; willComplete: boolean }
+ | { type: "WRONG" }
+ | { type: "RESET" };
+
+export const initialGState: GState = {
+ displayedLineIdx: -1,
+ typedCount: 0,
+ lineCompleted: false,
+ combo: 0,
+ maxCombo: 0,
+ score: 0,
+ totalCorrect: 0,
+ totalMiss: 0,
+ linesCleared: 0,
+ wpm: 0,
+};
+
+export function gReducer(state: GState, action: GAction): GState {
+ switch (action.type) {
+ case "ADVANCE": {
+ const prevIdx = state.displayedLineIdx;
+ const comboReset = !action.prevCompleted && prevIdx >= 0;
+ return {
+ ...state,
+ displayedLineIdx: action.newIdx,
+ typedCount: 0,
+ lineCompleted: false,
+ combo: comboReset ? 0 : state.combo,
+ };
+ }
+
+ case "CORRECT": {
+ const newTypedCount = state.typedCount + 1;
+ const newCombo = state.combo + 1;
+ const newMaxCombo = Math.max(state.maxCombo, newCombo);
+ const comboBonus = Math.min(50, Math.floor(newCombo / 10) * 5);
+ const newScore = state.score + 10 + comboBonus;
+ const newTotalCorrect = state.totalCorrect + 1;
+ if (action.willComplete) {
+ return {
+ ...state,
+ typedCount: newTypedCount,
+ lineCompleted: true,
+ combo: newCombo,
+ maxCombo: newMaxCombo,
+ score: newScore,
+ totalCorrect: newTotalCorrect,
+ linesCleared: state.linesCleared + 1,
+ };
+ }
+ return {
+ ...state,
+ typedCount: newTypedCount,
+ combo: newCombo,
+ maxCombo: newMaxCombo,
+ score: newScore,
+ totalCorrect: newTotalCorrect,
+ };
+ }
+ case "WRONG":
+ return { ...state, totalMiss: state.totalMiss + 1, combo: 0 };
+ case "RESET":
+ return { ...initialGState };
+ default:
+ return state;
+ }
+} \ No newline at end of file
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage