labag 2.5.0 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -24,61 +24,51 @@ export class RecordChecker {
24
24
  * @returns 計算出的分數。
25
25
  */
26
26
  calculateScore(record: GameRecord): number {
27
- // 重置遊戲狀態
27
+ // 警告:此操作會重置並覆蓋當前傳入的遊戲實例狀態
28
28
  this.game.init();
29
29
  this.game.times = record.times;
30
30
 
31
- // 使用 any 類型來存取私有方法
32
- const gameAny = this.game as any;
33
-
34
31
  for (const round of record.rounds) {
35
- if (!this.game.isRunning()) {
36
- throw new Error("遊戲次數已達上限,無法繼續遊玩。");
32
+ if (!this.game.isRunning) {
33
+ break;
37
34
  }
38
35
 
39
36
  // 1. 回合開始
40
- gameAny.roundStart();
37
+ this.game.roundStart();
38
+
39
+ // 2. 觸發 rollSlots 事件,這會執行所有模式的隨機邏輯
40
+ this.game.rollSlots();
41
41
 
42
- // 2. 設定隨機數字與圖案 (模擬 rollSlots)
42
+ // 3. 覆蓋隨機數字與圖案 (確保使用紀錄中的數值)
43
43
  const { ranges } = this.game.getCurrentConfig();
44
-
45
- this.game.randNums = [
46
- round.randNums["0"],
47
- round.randNums["1"],
48
- round.randNums["2"],
49
- ];
50
44
 
51
- this.game.randNums.forEach((num, index) => {
52
- const match = ranges.find((r) => num <= r.threshold);
53
- if (match) {
54
- this.game.patterns[index] = match.pattern;
55
- } else {
56
- this.game.patterns[index] = null;
57
- }
58
- });
45
+ for (let i = 0; i < 3; i++) {
46
+ const num = round.randNums?.[i.toString()] ?? 0;
47
+ this.game.randNums[i] = num;
59
48
 
60
- // 觸發 rollSlots 事件,讓模式執行其邏輯 (例如 greenwei 產生隨機數)
61
- gameAny.emit("rollSlots");
49
+ const match = ranges.find((r) => num <= r.threshold);
50
+ this.game.patterns[i] = match ? match.pattern : null;
51
+ }
62
52
 
63
- // 3. 覆蓋模式的隨機變數 (確保使用紀錄中的數值)
53
+ // 4. 覆蓋模式的隨機變數 (確保使用紀錄中的數值)
64
54
  this.game.modes.forEach((mode) => {
65
- if (round.randNums[mode.name] !== undefined) {
66
- mode.variable.randNum = round.randNums[mode.name];
55
+ const recordedNum = round.randNums?.[mode.name];
56
+ if (recordedNum !== undefined && mode.variable) {
57
+ mode.variable.randNum = recordedNum;
67
58
  }
68
59
  });
69
60
 
70
- // 4. 計算分數
71
- gameAny.calculateScore();
61
+ // 5. 計算分數
62
+ this.game.calculateScore();
72
63
 
73
- // 5. 回合結束
74
- gameAny.roundEnd();
64
+ // 6. 回合結束
65
+ this.game.roundEnd();
75
66
  }
76
67
 
77
- if (!this.game.isRunning()) {
78
- gameAny.gameOver();
68
+ if (!this.game.isRunning) {
69
+ this.game.gameOver();
79
70
  }
80
71
 
81
72
  return this.game.score;
82
73
  }
83
74
  }
84
-
package/src/recorder.ts CHANGED
@@ -1,13 +1,13 @@
1
1
  import { LaBaG } from "./labag";
2
2
 
3
3
  export type RoundRecord = {
4
- randNums: Record<string, number>;
4
+ readonly randNums: Readonly<Record<string, number>>;
5
5
  };
6
6
 
7
7
  export type GameRecord = {
8
8
  times: number;
9
9
  score: number;
10
- rounds: RoundRecord[];
10
+ readonly rounds: ReadonlyArray<RoundRecord>;
11
11
  };
12
12
 
13
13
  export type RecorderOptions = {
@@ -17,25 +17,23 @@ export class Recorder {
17
17
  private game: LaBaG;
18
18
  #rounds: RoundRecord[] = [];
19
19
  private score: number = 0;
20
- private onRoundEndBound: (e: LaBaG) => void;
21
20
  private started = false;
22
21
  private debug = false;
23
22
 
24
23
  constructor(gameInstance: LaBaG, options?: RecorderOptions) {
25
24
  this.game = gameInstance;
26
- this.onRoundEndBound = this.onRoundEnd.bind(this);
27
- this.debug = !!options?.debug;
25
+ this.debug = options?.debug ?? false;
28
26
  }
29
27
 
30
- get rounds() {
31
- return this.#rounds.map((r) => ({ ...r }));
28
+ get rounds(): ReadonlyArray<RoundRecord> {
29
+ return this.#rounds;
32
30
  }
33
31
 
34
- private onRoundEnd(g: LaBaG) {
32
+ private onRoundEnd = (g: LaBaG) => {
35
33
  const randNums: Record<string, number> = {};
36
34
 
37
35
  g.randNums.forEach((value, key) => {
38
- if (!isNaN(value)) {
36
+ if (typeof value === "number" && !Number.isNaN(value)) {
39
37
  randNums[key] = value;
40
38
  }
41
39
  });
@@ -43,7 +41,7 @@ export class Recorder {
43
41
  // 收集各模式的 randNum(若為數值且有效)
44
42
  g.modes.forEach((mode) => {
45
43
  const rn = mode?.variable?.randNum;
46
- if (!isNaN(rn)) {
44
+ if (typeof rn === "number" && !Number.isNaN(rn)) {
47
45
  randNums[mode.name] = rn;
48
46
  }
49
47
  });
@@ -60,7 +58,7 @@ export class Recorder {
60
58
 
61
59
  this.#rounds.push(round);
62
60
  this.score = g.score;
63
- }
61
+ };
64
62
 
65
63
  init(clearExisting = true) {
66
64
  if (this.started) return;
@@ -68,14 +66,14 @@ export class Recorder {
68
66
  this.clear();
69
67
  }
70
68
  if (typeof this.game.addEventListener === "function") {
71
- this.game.addEventListener("roundEnd", this.onRoundEndBound);
69
+ this.game.addEventListener("roundEnd", this.onRoundEnd);
72
70
  this.started = true;
73
71
  }
74
72
  }
75
73
 
76
74
  dispose() {
77
75
  if (!this.started) return;
78
- this.game.removeEventListener("roundEnd", this.onRoundEndBound);
76
+ this.game.removeEventListener("roundEnd", this.onRoundEnd);
79
77
  this.started = false;
80
78
  }
81
79
  clear() {
package/src/test.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { labag } from "./index";
1
+ import { checker, labag } from "./index";
2
+ import { recorder } from "./index";
2
3
  labag.addEventListener("gameStart", (game) => {
3
4
  console.log("Game Started!");
4
5
  console.log(`Total Rounds: ${game.times}\n`);
@@ -12,7 +13,7 @@ labag.addEventListener("rollSlots", (game) => {
12
13
  console.log(
13
14
  `Probability Ranges: ${ranges
14
15
  .map((r) => `${r.pattern.name}<=${r.threshold}`)
15
- .join(", ")}`
16
+ .join(", ")}`,
16
17
  );
17
18
  });
18
19
  labag.addEventListener("roundEnd", (game) => {
@@ -22,7 +23,9 @@ labag.addEventListener("roundEnd", (game) => {
22
23
  });
23
24
 
24
25
  labag.init();
25
- while (labag.isRunning()) {
26
+ recorder.init();
27
+
28
+ while (labag.isRunning) {
26
29
  labag.play();
27
30
  }
28
31
 
@@ -32,5 +35,11 @@ console.log(
32
35
  `Active Modes at end: ${labag
33
36
  .getCurrentConfig()
34
37
  .modes.map((m) => m.name)
35
- .join(", ")}`
38
+ .join(", ")}`,
39
+ );
40
+ console.log(`record: ${JSON.stringify(recorder.getRecord(), null, 2)}`);
41
+ console.log(
42
+ checker.check(recorder.getRecord())
43
+ ? "Record is valid!"
44
+ : "Record is invalid!",
36
45
  );
@@ -1,3 +1,5 @@
1
+ import { LaBaG } from "src/labag";
2
+ import { modes } from "src/modes";
1
3
  import { patterns } from "src/pattern";
2
4
 
3
5
  /**
@@ -26,3 +28,4 @@ export type Pattern = {
26
28
  */
27
29
  export type PatternName = (typeof patterns)[number]["name"];
28
30
 
31
+ export type ModeName = (typeof modes)[number]["name"] | "normal";
@@ -1,10 +0,0 @@
1
- import { Mode } from "../mode";
2
-
3
- export default new Mode(true, "normal", {
4
- gss: 36,
5
- hhh: 24,
6
- hentai: 17,
7
- handson: 12,
8
- kachu: 8,
9
- rrr: 3,
10
- });