aboutsummaryrefslogtreecommitdiffstats
path: root/src/app/game/game.stat.ts
blob: 43136e6e5fe99a0f5c70d9e0a0e75eb2ba2affcb (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
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;
  }
}
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage