@vnejs/plugins.views.screens.checkers 0.2.2 → 0.2.3

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.
Files changed (53) hide show
  1. package/dist/index.d.ts +1 -0
  2. package/dist/index.js +21 -12
  3. package/dist/modules/board.d.ts +9 -0
  4. package/dist/modules/board.js +16 -0
  5. package/dist/modules/bridge.d.ts +8 -0
  6. package/dist/modules/bridge.js +10 -0
  7. package/dist/modules/click.d.ts +8 -0
  8. package/dist/modules/click.js +14 -0
  9. package/dist/modules/controller.accept.d.ts +7 -25
  10. package/dist/modules/controller.accept.js +12 -159
  11. package/dist/modules/controller.d.ts +4 -6
  12. package/dist/modules/controller.grid.d.ts +11 -11
  13. package/dist/modules/controller.grid.js +21 -25
  14. package/dist/modules/controller.js +8 -26
  15. package/dist/modules/player.interact.d.ts +9 -0
  16. package/dist/modules/player.interact.js +33 -0
  17. package/dist/modules/player.select.d.ts +9 -0
  18. package/dist/modules/player.select.js +29 -0
  19. package/dist/modules/view.d.ts +5 -5
  20. package/dist/modules/view.js +4 -4
  21. package/dist/types.d.ts +7 -5
  22. package/dist/utils/checkers.d.ts +19 -9
  23. package/dist/utils/checkers.js +30 -16
  24. package/dist/view/index.d.ts +2 -2
  25. package/dist/view/index.js +12 -12
  26. package/package.json +8 -2
  27. package/src/index.ts +21 -12
  28. package/src/modules/board.ts +29 -0
  29. package/src/modules/bridge.ts +20 -0
  30. package/src/modules/click.ts +28 -0
  31. package/src/modules/controller.accept.ts +20 -189
  32. package/src/modules/controller.grid.ts +23 -26
  33. package/src/modules/controller.ts +16 -36
  34. package/src/modules/player.interact.ts +48 -0
  35. package/src/modules/player.select.ts +42 -0
  36. package/src/modules/view.ts +12 -6
  37. package/src/tests/player.interact.test.ts +56 -0
  38. package/src/tests/setup.ts +21 -10
  39. package/src/types.ts +19 -6
  40. package/src/utils/checkers.ts +51 -25
  41. package/src/view/index.tsx +22 -23
  42. package/dist/modules/checkers.d.ts +0 -9
  43. package/dist/modules/checkers.js +0 -37
  44. package/dist/utils/ai.d.ts +0 -4
  45. package/dist/utils/ai.js +0 -27
  46. package/dist/utils/board.d.ts +0 -32
  47. package/dist/utils/board.js +0 -199
  48. package/src/modules/checkers.ts +0 -52
  49. package/src/tests/ai.test.ts +0 -61
  50. package/src/tests/board.test.ts +0 -43
  51. package/src/tests/checkers.test.ts +0 -58
  52. package/src/utils/ai.ts +0 -31
  53. package/src/utils/board.ts +0 -252
package/dist/index.d.ts CHANGED
@@ -1 +1,2 @@
1
+ import "@vnejs/contracts.game.checkers";
1
2
  import "@vnejs/contracts.views.screens.checkers";
package/dist/index.js CHANGED
@@ -1,15 +1,24 @@
1
+ import "@vnejs/contracts.game.checkers";
1
2
  import "@vnejs/contracts.views.screens.checkers";
2
3
  import { regPlugin } from "@vnejs/shared";
3
- import { CONSTANTS, PARAMS, PLUGIN_NAME, SUBSCRIBE_EVENTS } from "@vnejs/contracts.views.screens.checkers";
4
- import { CheckersController } from "./modules/controller.js";
5
- import { CheckersControllerAccept } from "./modules/controller.accept.js";
6
- import { CheckersControllerGrid } from "./modules/controller.grid.js";
7
- import { Checkers } from "./modules/checkers.js";
8
- import { CheckersView } from "./modules/view.js";
9
- regPlugin(PLUGIN_NAME, { constants: CONSTANTS, events: SUBSCRIBE_EVENTS, params: PARAMS }, [
10
- CheckersController,
11
- CheckersControllerGrid,
12
- CheckersControllerAccept,
13
- Checkers,
14
- CheckersView,
4
+ import { PARAMS, PLUGIN_NAME, SUBSCRIBE_EVENTS } from "@vnejs/contracts.views.screens.checkers";
5
+ import { CheckersViewBoard } from "./modules/board.js";
6
+ import { CheckersViewBridge } from "./modules/bridge.js";
7
+ import { CheckersViewClick } from "./modules/click.js";
8
+ import { CheckersViewController } from "./modules/controller.js";
9
+ import { CheckersViewControllerAccept } from "./modules/controller.accept.js";
10
+ import { CheckersViewControllerGrid } from "./modules/controller.grid.js";
11
+ import { CheckersViewPlayerInteract } from "./modules/player.interact.js";
12
+ import { CheckersViewPlayerSelect } from "./modules/player.select.js";
13
+ import { CheckersViewView } from "./modules/view.js";
14
+ regPlugin(PLUGIN_NAME, { events: SUBSCRIBE_EVENTS, params: PARAMS }, [
15
+ CheckersViewBridge,
16
+ CheckersViewController,
17
+ CheckersViewControllerGrid,
18
+ CheckersViewControllerAccept,
19
+ CheckersViewPlayerInteract,
20
+ CheckersViewPlayerSelect,
21
+ CheckersViewClick,
22
+ CheckersViewBoard,
23
+ CheckersViewView,
15
24
  ]);
@@ -0,0 +1,9 @@
1
+ import { ModuleCore } from "@vnejs/module.core";
2
+ import type { CheckersBoardChangedPayload } from "@vnejs/contracts.game.checkers";
3
+ import type { CheckersViewPluginConstants, CheckersViewPluginEvents, CheckersViewPluginParams, CheckersViewPluginSettings } from "../types.js";
4
+ import { type CheckersViewState } from "../utils/checkers.js";
5
+ export declare class CheckersViewBoard extends ModuleCore<CheckersViewPluginEvents, CheckersViewPluginConstants, CheckersViewPluginSettings, CheckersViewPluginParams, CheckersViewState> {
6
+ name: string;
7
+ subscribe: () => void;
8
+ onBoardChanged: (payload?: CheckersBoardChangedPayload) => Promise<void>;
9
+ }
@@ -0,0 +1,16 @@
1
+ import { ModuleCore } from "@vnejs/module.core";
2
+ import { buildGridItems, emptyBoard, fromBoardChanged } from "../utils/checkers.js";
3
+ export class CheckersViewBoard extends ModuleCore {
4
+ name = "checkers_view.board";
5
+ subscribe = () => {
6
+ this.on(this.EVENTS.CHECKERS.BOARD_CHANGED, this.onBoardChanged);
7
+ this.on(this.EVENTS.CHECKERS_VIEW.STATE_UPDATE, this.updateState);
8
+ };
9
+ onBoardChanged = async (payload = {}) => {
10
+ const mirror = fromBoardChanged(payload);
11
+ const board = mirror.board ?? this.state.board ?? emptyBoard();
12
+ const gridItems = buildGridItems({ board, gridRow: this.state.gridRow ?? null, gridColumn: this.state.gridColumn ?? null });
13
+ await this.emit(this.EVENTS.CHECKERS_VIEW.STATE_UPDATE, { ...mirror, board, gridItems });
14
+ await this.emit(this.EVENTS.CHECKERS_VIEW.UPDATE_FAST);
15
+ };
16
+ }
@@ -0,0 +1,8 @@
1
+ import { ModuleCore } from "@vnejs/module.core";
2
+ import type { CheckersViewPluginConstants, CheckersViewPluginEvents, CheckersViewPluginParams, CheckersViewPluginSettings } from "../types.js";
3
+ export declare class CheckersViewBridge extends ModuleCore<CheckersViewPluginEvents, CheckersViewPluginConstants, CheckersViewPluginSettings, CheckersViewPluginParams> {
4
+ name: string;
5
+ subscribe: () => void;
6
+ onCheckersShow: () => Promise<unknown[]> | undefined;
7
+ onCheckersHide: () => Promise<unknown[]> | undefined;
8
+ }
@@ -0,0 +1,10 @@
1
+ import { ModuleCore } from "@vnejs/module.core";
2
+ export class CheckersViewBridge extends ModuleCore {
3
+ name = "checkers_view.bridge";
4
+ subscribe = () => {
5
+ this.on(this.EVENTS.CHECKERS.SHOW, this.onCheckersShow);
6
+ this.on(this.EVENTS.CHECKERS.HIDE, this.onCheckersHide);
7
+ };
8
+ onCheckersShow = () => this.emit(this.EVENTS.CHECKERS_VIEW.SHOW);
9
+ onCheckersHide = () => this.emit(this.EVENTS.CHECKERS_VIEW.HIDE);
10
+ }
@@ -0,0 +1,8 @@
1
+ import { ModuleCore } from "@vnejs/module.core";
2
+ import type { CheckersViewPluginConstants, CheckersViewPluginEvents, CheckersViewPluginParams, CheckersViewPluginSettings } from "../types.js";
3
+ import type { CheckersClickPayload, CheckersViewState } from "../utils/checkers.js";
4
+ export declare class CheckersViewClick extends ModuleCore<CheckersViewPluginEvents, CheckersViewPluginConstants, CheckersViewPluginSettings, CheckersViewPluginParams, CheckersViewState> {
5
+ name: string;
6
+ subscribe: () => void;
7
+ onClick: ({ row, column }?: CheckersClickPayload) => Promise<void>;
8
+ }
@@ -0,0 +1,14 @@
1
+ import { ModuleCore } from "@vnejs/module.core";
2
+ export class CheckersViewClick extends ModuleCore {
3
+ name = "checkers_view.click";
4
+ subscribe = () => {
5
+ this.on(this.EVENTS.CHECKERS_VIEW.CLICK, this.onClick);
6
+ this.on(this.EVENTS.CHECKERS_VIEW.STATE_UPDATE, this.updateState);
7
+ };
8
+ onClick = async ({ row, column } = {}) => {
9
+ if (this.shared.checkersInteractDisableSources.isNotEmpty() || row == null || column == null)
10
+ return;
11
+ await this.emit(this.EVENTS.CHECKERS_VIEW.GRID_CLEAR);
12
+ this.emit(this.EVENTS.CHECKERS_VIEW.PLAYER_INTERACT, { row, column });
13
+ };
14
+ }
@@ -1,30 +1,12 @@
1
1
  import { ModuleControllerAccept } from "@vnejs/module.controller.accept";
2
- import type { CheckersAiType } from "@vnejs/contracts.views.screens.checkers";
3
- import type { CheckersPluginConstants, CheckersPluginEvents, CheckersPluginParams, CheckersPluginSettings } from "../types.js";
4
- import { type CheckersPos } from "../utils/board.js";
5
- import { type CheckersCellClickPayload, type CheckersPluginState } from "../utils/checkers.js";
6
- export declare class CheckersControllerAccept extends ModuleControllerAccept<CheckersPluginEvents, CheckersPluginConstants, CheckersPluginSettings, CheckersPluginParams, CheckersPluginState> {
2
+ import type { CheckersViewPluginConstants, CheckersViewPluginEvents, CheckersViewPluginParams, CheckersViewPluginSettings } from "../types.js";
3
+ import type { CheckersViewState } from "../utils/checkers.js";
4
+ export declare class CheckersViewControllerAccept extends ModuleControllerAccept<CheckersViewPluginEvents, CheckersViewPluginConstants, CheckersViewPluginSettings, CheckersViewPluginParams, CheckersViewState> {
7
5
  name: string;
8
- EVENT_SHOW: "vne:checkers:show";
9
- EVENT_HIDE: "vne:checkers:hide";
10
- EVENT_ACCEPT: "vne:checkers:accept";
11
- EVENT_STATE_UPDATE: "vne:checkers:state_update";
6
+ EVENT_SHOW: "vne:checkers_view:show";
7
+ EVENT_HIDE: "vne:checkers_view:hide";
8
+ EVENT_ACCEPT: "vne:checkers_view:accept";
9
+ EVENT_STATE_UPDATE: "vne:checkers_view:state_update";
12
10
  CONTROLS_ZINDEX: number;
13
- subscribe: () => void;
14
- onShow: () => undefined;
15
- onShowAndMaybeAi: () => Promise<void>;
16
- onHide: () => Promise<unknown[]> | undefined;
17
- controllerFor: (turn: NonNullable<CheckersPluginState["turn"]>) => CheckersAiType;
18
- isHumanTurn: () => boolean;
19
- onCellClick: ({ row, column }?: CheckersCellClickPayload) => Promise<void>;
20
11
  onAccept: () => Promise<void>;
21
- onAiTurn: () => Promise<void>;
22
- playMove: (from: CheckersPos, to: CheckersPos, { scheduleAi }?: {
23
- scheduleAi?: boolean;
24
- }) => Promise<boolean>;
25
- emitBoardState: (patch: Partial<CheckersPluginState> & {
26
- board?: CheckersPluginState["board"];
27
- selected?: CheckersPluginState["selected"];
28
- legalMoves?: CheckersPluginState["legalMoves"];
29
- }) => Promise<void>;
30
12
  }
@@ -1,165 +1,18 @@
1
1
  import { ModuleControllerAccept } from "@vnejs/module.controller.accept";
2
- import { applyMove, findMove, getAllMoves, getWinner, oppositeColor, samePos } from "../utils/board.js";
3
- import { pickMove } from "../utils/ai.js";
4
- import { buildGridItems, statusForTurn } from "../utils/checkers.js";
5
- export class CheckersControllerAccept extends ModuleControllerAccept {
6
- name = "checkers.controller.accept";
7
- EVENT_SHOW = this.EVENTS.CHECKERS.SHOW;
8
- EVENT_HIDE = this.EVENTS.CHECKERS.HIDE;
9
- EVENT_ACCEPT = this.EVENTS.CHECKERS.ACCEPT;
10
- EVENT_STATE_UPDATE = this.EVENTS.CHECKERS.STATE_UPDATE;
11
- CONTROLS_ZINDEX = this.PARAMS.CHECKERS.ZINDEX;
12
- subscribe = () => {
13
- this.on(this.EVENT_SHOW, this.onShow);
14
- this.on(this.EVENT_HIDE, this.onHide);
15
- this.on(this.EVENT_ACCEPT, this.onAccept);
16
- if (this.EVENT_STATE_UPDATE)
17
- this.on(this.EVENT_STATE_UPDATE, this.updateState);
18
- this.on(this.EVENTS.CHECKERS.CELL_CLICK, this.onCellClick);
19
- this.on(this.EVENTS.CHECKERS.AI_TURN, this.onAiTurn);
20
- };
21
- onShow = () => void this.onShowAndMaybeAi();
22
- onShowAndMaybeAi = async () => {
23
- await this.emit(this.EVENTS.CONTROLS.PUSH, {
24
- key: this.name,
25
- controls: this.CONTROLS,
26
- index: this.CONTROLS_ZINDEX + 1,
27
- checkNext: true,
28
- });
29
- // SHOW handlers run in parallel with controller.beforeShow — wait for board.
30
- await this.waitCheck(() => Boolean(this.state.board && this.state.turn));
31
- await this.onAiTurn();
32
- };
33
- onHide = () => {
34
- this.shared.checkersAiBusy = false;
35
- this.setDefaultState();
36
- return this.emit(this.EVENTS.CONTROLS.POP, { key: this.name });
37
- };
38
- controllerFor = (turn) => (this.state.ai?.[turn] ?? this.shared.checkersAi?.[turn] ?? this.CONST.CHECKERS.AI_TYPES.PLAYER);
39
- isHumanTurn = () => {
40
- const turn = this.state.turn;
41
- if (!turn)
42
- return false;
43
- return this.controllerFor(turn) === this.CONST.CHECKERS.AI_TYPES.PLAYER;
44
- };
45
- onCellClick = async ({ row, column } = {}) => {
46
- if (this.shared.checkersAiBusy || !this.isHumanTurn())
47
- return;
48
- if (row == null || column == null)
49
- return;
50
- await this.emit(this.EVENTS.CHECKERS.STATE_UPDATE, {
51
- gridRow: row,
52
- gridColumn: column,
53
- });
54
- await this.emit(this.EVENTS.CHECKERS.UPDATE_FAST);
55
- await this.onAccept();
56
- };
2
+ export class CheckersViewControllerAccept extends ModuleControllerAccept {
3
+ name = "checkers_view.controller.accept";
4
+ EVENT_SHOW = this.EVENTS.CHECKERS_VIEW.SHOW;
5
+ EVENT_HIDE = this.EVENTS.CHECKERS_VIEW.HIDE;
6
+ EVENT_ACCEPT = this.EVENTS.CHECKERS_VIEW.ACCEPT;
7
+ EVENT_STATE_UPDATE = this.EVENTS.CHECKERS_VIEW.STATE_UPDATE;
8
+ CONTROLS_ZINDEX = this.PARAMS.CHECKERS_VIEW.ZINDEX;
57
9
  onAccept = async () => {
58
- if (this.shared.checkersAiBusy)
59
- return;
60
- if (this.state.winner) {
61
- await this.emit(this.EVENTS.CHECKERS.FINISH);
62
- return;
63
- }
64
- if (!this.isHumanTurn())
10
+ if (this.shared.checkersInteractDisableSources.isNotEmpty())
65
11
  return;
66
- const { gridRow, gridColumn, board, turn, selected } = this.state;
67
- if (gridRow == null || gridColumn == null || !board || !turn)
68
- return;
69
- const focus = { row: gridRow, column: gridColumn };
70
- const piece = board[focus.row]?.[focus.column] ?? null;
71
- if (selected && findMove(this.state.legalMoves ?? [], selected, focus)) {
72
- await this.playMove(selected, focus);
73
- return;
74
- }
75
- if (piece && piece.color === turn) {
76
- const all = getAllMoves(board, turn);
77
- const legalMoves = all.filter((move) => samePos(move.from, focus));
78
- if (legalMoves.length === 0)
79
- return;
80
- const nextSelected = selected && samePos(selected, focus) ? null : focus;
81
- const nextLegal = nextSelected ? legalMoves : [];
82
- await this.emitBoardState({
83
- selected: nextSelected,
84
- legalMoves: nextLegal,
85
- });
86
- return;
87
- }
88
- if (selected) {
89
- await this.emitBoardState({ selected: null, legalMoves: [] });
90
- }
91
- };
92
- onAiTurn = async () => {
93
- if (this.state.winner || !this.state.board || !this.state.turn)
94
- return;
95
- if (this.isHumanTurn())
96
- return;
97
- if (this.shared.checkersAiBusy)
98
- return;
99
- this.shared.checkersAiBusy = true;
100
- try {
101
- while (!this.state.winner && this.state.board && this.state.turn && !this.isHumanTurn()) {
102
- await this.waitTimeout(this.PARAMS.CHECKERS.AI_DELAY);
103
- const { board, turn } = this.state;
104
- if (!board || !turn || this.state.winner)
105
- break;
106
- const move = pickMove(board, turn, this.controllerFor(turn));
107
- if (!move)
108
- break;
109
- const played = await this.playMove(move.from, move.to, { scheduleAi: false });
110
- if (!played)
111
- break;
112
- }
113
- }
114
- finally {
115
- this.shared.checkersAiBusy = false;
116
- }
117
- };
118
- playMove = async (from, to, { scheduleAi = true } = {}) => {
119
- const { board, turn } = this.state;
120
- if (!board || !turn)
121
- return false;
122
- // Always resolve against current legal moves — `legalMoves: []` after a move is truthy and must not win over getAllMoves.
123
- const move = findMove(getAllMoves(board, turn), from, to);
124
- if (!move)
125
- return false;
126
- const nextBoard = applyMove(board, move);
127
- const nextTurn = oppositeColor(turn);
128
- const winner = getWinner(nextBoard, nextTurn);
129
- await this.emitBoardState({
130
- board: nextBoard,
131
- turn: nextTurn,
132
- selected: null,
133
- legalMoves: [],
134
- winner,
135
- statusText: statusForTurn(nextTurn, winner),
136
- });
137
- if (winner) {
138
- await this.waitTimeout(this.PARAMS.CHECKERS.TRANSITION);
139
- await this.emit(this.EVENTS.CHECKERS.FINISH);
140
- return true;
141
- }
142
- if (scheduleAi)
143
- await this.onAiTurn();
144
- return true;
145
- };
146
- emitBoardState = async (patch) => {
147
- const board = patch.board ?? this.state.board;
148
- if (!board)
12
+ const { gridRow, gridColumn } = this.state;
13
+ if (gridRow == null || gridColumn == null)
149
14
  return;
150
- const selected = patch.selected !== undefined ? patch.selected : this.state.selected;
151
- const legalMoves = patch.legalMoves !== undefined ? patch.legalMoves : this.state.legalMoves;
152
- const gridItems = buildGridItems({
153
- board,
154
- selected: selected ?? null,
155
- legalMoves: legalMoves ?? [],
156
- gridRow: this.state.gridRow ?? null,
157
- gridColumn: this.state.gridColumn ?? null,
158
- });
159
- await this.emit(this.EVENTS.CHECKERS.STATE_UPDATE, {
160
- ...patch,
161
- gridItems,
162
- });
163
- await this.emit(this.EVENTS.CHECKERS.UPDATE_FAST);
15
+ await this.emit(this.EVENTS.CHECKERS_VIEW.GRID_CLEAR);
16
+ this.emit(this.EVENTS.CHECKERS_VIEW.PLAYER_INTERACT, { row: gridRow, column: gridColumn });
164
17
  };
165
18
  }
@@ -1,13 +1,11 @@
1
1
  import { ModuleController } from "@vnejs/module.components";
2
- import type { CheckersPluginConstants, CheckersPluginEvents, CheckersPluginParams, CheckersPluginSettings } from "../types.js";
3
- import { type CheckersPluginState } from "../utils/checkers.js";
4
- export declare class CheckersController extends ModuleController<CheckersPluginEvents, CheckersPluginConstants, CheckersPluginSettings, CheckersPluginParams, CheckersPluginState> {
2
+ import type { CheckersViewPluginConstants, CheckersViewPluginEvents, CheckersViewPluginParams, CheckersViewPluginSettings } from "../types.js";
3
+ import type { CheckersViewState } from "../utils/checkers.js";
4
+ export declare class CheckersViewController extends ModuleController<CheckersViewPluginEvents, CheckersViewPluginConstants, CheckersViewPluginSettings, CheckersViewPluginParams, CheckersViewState> {
5
5
  name: string;
6
- EVENT_UPDATE_VIEW: "vne:checkers:update";
6
+ EVENT_UPDATE_VIEW: "vne:checkers_view:update";
7
7
  CONTROLS: {};
8
8
  CONTROLS_INDEX: number;
9
9
  subscribe: () => void;
10
- beforeShow: () => Promise<void>;
11
10
  afterHide: () => void;
12
- onFinish: () => Promise<void>;
13
11
  }
@@ -1,16 +1,16 @@
1
1
  import { ModuleControllerArrowsGrid } from "@vnejs/module.controller.arrows.grid";
2
- import type { CheckersPluginConstants, CheckersPluginEvents, CheckersPluginParams, CheckersPluginSettings } from "../types.js";
3
- import { type CheckersPluginState } from "../utils/checkers.js";
4
- export declare class CheckersControllerGrid extends ModuleControllerArrowsGrid<CheckersPluginEvents, CheckersPluginConstants, CheckersPluginSettings, CheckersPluginParams, CheckersPluginState> {
2
+ import type { CheckersViewPluginConstants, CheckersViewPluginEvents, CheckersViewPluginParams, CheckersViewPluginSettings } from "../types.js";
3
+ import { type CheckersViewState } from "../utils/checkers.js";
4
+ export declare class CheckersViewControllerGrid extends ModuleControllerArrowsGrid<CheckersViewPluginEvents, CheckersViewPluginConstants, CheckersViewPluginSettings, CheckersViewPluginParams, CheckersViewState> {
5
5
  name: string;
6
- EVENT_SHOW: "vne:checkers:show";
7
- EVENT_HIDE: "vne:checkers:hide";
8
- EVENT_STATE_UPDATE: "vne:checkers:state_update";
9
- EVENT_UPDATE_FAST: "vne:checkers:update_fast";
10
- EVENT_GRID_NEXT: "vne:checkers:grid_next";
11
- EVENT_GRID_PREV: "vne:checkers:grid_prev";
12
- EVENT_GRID_CLEAR: "vne:checkers:grid_clear";
13
- EVENT_GRID_UPDATE_ITEMS: "vne:checkers:grid_update_items";
6
+ EVENT_SHOW: "vne:checkers_view:show";
7
+ EVENT_HIDE: "vne:checkers_view:hide";
8
+ EVENT_STATE_UPDATE: "vne:checkers_view:state_update";
9
+ EVENT_UPDATE_FAST: "vne:checkers_view:update_fast";
10
+ EVENT_GRID_NEXT: "vne:checkers_view:grid_next";
11
+ EVENT_GRID_PREV: "vne:checkers_view:grid_prev";
12
+ EVENT_GRID_CLEAR: "vne:checkers_view:grid_clear";
13
+ EVENT_GRID_UPDATE_ITEMS: "vne:checkers_view:grid_update_items";
14
14
  CONTROLS_ZINDEX: number;
15
15
  isDisableGridChangeHorizontal: boolean;
16
16
  isDisableGridChangeVertical: boolean;
@@ -1,29 +1,25 @@
1
1
  import { ModuleControllerArrowsGrid } from "@vnejs/module.controller.arrows.grid";
2
- import { buildGridItems } from "../utils/checkers.js";
3
- import { createInitialBoard } from "../utils/board.js";
4
- export class CheckersControllerGrid extends ModuleControllerArrowsGrid {
5
- name = "checkers.controller.grid";
6
- EVENT_SHOW = this.EVENTS.CHECKERS.SHOW;
7
- EVENT_HIDE = this.EVENTS.CHECKERS.HIDE;
8
- EVENT_STATE_UPDATE = this.EVENTS.CHECKERS.STATE_UPDATE;
9
- EVENT_UPDATE_FAST = this.EVENTS.CHECKERS.UPDATE_FAST;
10
- EVENT_GRID_NEXT = this.EVENTS.CHECKERS.GRID_NEXT;
11
- EVENT_GRID_PREV = this.EVENTS.CHECKERS.GRID_PREV;
12
- EVENT_GRID_CLEAR = this.EVENTS.CHECKERS.GRID_CLEAR;
13
- EVENT_GRID_UPDATE_ITEMS = this.EVENTS.CHECKERS.GRID_UPDATE_ITEMS;
14
- CONTROLS_ZINDEX = this.PARAMS.CHECKERS.ZINDEX;
2
+ import { buildGridItems, emptyBoard } from "../utils/checkers.js";
3
+ export class CheckersViewControllerGrid extends ModuleControllerArrowsGrid {
4
+ name = "checkers_view.controller.grid";
5
+ EVENT_SHOW = this.EVENTS.CHECKERS_VIEW.SHOW;
6
+ EVENT_HIDE = this.EVENTS.CHECKERS_VIEW.HIDE;
7
+ EVENT_STATE_UPDATE = this.EVENTS.CHECKERS_VIEW.STATE_UPDATE;
8
+ EVENT_UPDATE_FAST = this.EVENTS.CHECKERS_VIEW.UPDATE_FAST;
9
+ EVENT_GRID_NEXT = this.EVENTS.CHECKERS_VIEW.GRID_NEXT;
10
+ EVENT_GRID_PREV = this.EVENTS.CHECKERS_VIEW.GRID_PREV;
11
+ EVENT_GRID_CLEAR = this.EVENTS.CHECKERS_VIEW.GRID_CLEAR;
12
+ EVENT_GRID_UPDATE_ITEMS = this.EVENTS.CHECKERS_VIEW.GRID_UPDATE_ITEMS;
13
+ CONTROLS_ZINDEX = this.PARAMS.CHECKERS_VIEW.ZINDEX;
15
14
  isDisableGridChangeHorizontal = true;
16
15
  isDisableGridChangeVertical = true;
17
- getMaxRows = () => this.PARAMS.CHECKERS.ROWS;
18
- getMaxColumns = () => this.PARAMS.CHECKERS.COLUMNS;
19
- getGridItems = async () => {
20
- const board = this.state.board ?? createInitialBoard();
21
- return buildGridItems({
22
- board,
23
- selected: this.state.selected ?? null,
24
- legalMoves: this.state.legalMoves ?? [],
25
- gridRow: this.state.gridRow ?? null,
26
- gridColumn: this.state.gridColumn ?? null,
27
- });
28
- };
16
+ getMaxRows = () => this.PARAMS.CHECKERS_VIEW.ROWS;
17
+ getMaxColumns = () => this.PARAMS.CHECKERS_VIEW.COLUMNS;
18
+ getGridItems = async () => buildGridItems({
19
+ board: this.state.board ?? emptyBoard(),
20
+ selected: this.state.selected ?? null,
21
+ legalMoves: this.state.legalMoves ?? [],
22
+ gridRow: this.state.gridRow ?? null,
23
+ gridColumn: this.state.gridColumn ?? null,
24
+ });
29
25
  }
@@ -1,34 +1,16 @@
1
1
  import { ModuleController } from "@vnejs/module.components";
2
- import { createInitialCheckersState } from "../utils/checkers.js";
3
- export class CheckersController extends ModuleController {
4
- name = "checkers.controller";
5
- EVENT_UPDATE_VIEW = this.EVENTS.CHECKERS.UPDATE;
2
+ export class CheckersViewController extends ModuleController {
3
+ name = "checkers_view.controller";
4
+ EVENT_UPDATE_VIEW = this.EVENTS.CHECKERS_VIEW.UPDATE;
6
5
  CONTROLS = {};
7
- CONTROLS_INDEX = this.PARAMS.CHECKERS.ZINDEX;
6
+ CONTROLS_INDEX = this.PARAMS.CHECKERS_VIEW.ZINDEX;
8
7
  subscribe = () => {
9
- this.on(this.EVENTS.CHECKERS.SHOW, this.onShow);
10
- this.on(this.EVENTS.CHECKERS.HIDE, this.onHide);
11
- this.on(this.EVENTS.CHECKERS.STATE_UPDATE, this.updateState);
12
- this.on(this.EVENTS.CHECKERS.UPDATE_FAST, this.updateViewFast);
13
- this.on(this.EVENTS.CHECKERS.FINISH, this.onFinish);
14
- };
15
- beforeShow = async () => {
16
- this.shared.checkersAiBusy = false;
17
- const initial = createInitialCheckersState();
18
- const ai = {
19
- white: this.shared.checkersAi?.white ?? this.CONST.CHECKERS.AI_TYPES.PLAYER,
20
- black: this.shared.checkersAi?.black ?? this.CONST.CHECKERS.AI_TYPES.PLAYER,
21
- };
22
- await this.emit(this.EVENTS.CHECKERS.STATE_UPDATE, { ...initial, ai });
23
- await this.emit(this.EVENTS.CHECKERS.GRID_UPDATE_ITEMS);
8
+ this.on(this.EVENTS.CHECKERS_VIEW.SHOW, this.onShow);
9
+ this.on(this.EVENTS.CHECKERS_VIEW.HIDE, this.onHide);
10
+ this.on(this.EVENTS.CHECKERS_VIEW.STATE_UPDATE, this.updateState);
11
+ this.on(this.EVENTS.CHECKERS_VIEW.UPDATE_FAST, this.updateViewFast);
24
12
  };
25
13
  afterHide = () => {
26
- this.shared.checkersAiBusy = false;
27
14
  this.setDefaultState();
28
15
  };
29
- onFinish = async () => {
30
- this.shared.checkersAiBusy = false;
31
- await this.emit(this.EVENTS.CHECKERS.HIDE);
32
- this.emitNext();
33
- };
34
16
  }
@@ -0,0 +1,9 @@
1
+ import { ModuleCore } from "@vnejs/module.core";
2
+ import type { CheckersPlayerInteractPayload } from "@vnejs/contracts.views.screens.checkers";
3
+ import type { CheckersViewPluginConstants, CheckersViewPluginEvents, CheckersViewPluginParams, CheckersViewPluginSettings } from "../types.js";
4
+ import { type CheckersViewState } from "../utils/checkers.js";
5
+ export declare class CheckersViewPlayerInteract extends ModuleCore<CheckersViewPluginEvents, CheckersViewPluginConstants, CheckersViewPluginSettings, CheckersViewPluginParams, CheckersViewState> {
6
+ name: string;
7
+ subscribe: () => void;
8
+ onPlayerInteract: ({ row, column }?: CheckersPlayerInteractPayload) => Promise<undefined>;
9
+ }
@@ -0,0 +1,33 @@
1
+ import { ModuleCore } from "@vnejs/module.core";
2
+ import { samePos } from "../utils/checkers.js";
3
+ export class CheckersViewPlayerInteract extends ModuleCore {
4
+ name = "checkers_view.player.interact";
5
+ subscribe = () => {
6
+ this.on(this.EVENTS.CHECKERS_VIEW.PLAYER_INTERACT, this.onPlayerInteract);
7
+ this.on(this.EVENTS.CHECKERS_VIEW.STATE_UPDATE, this.updateState);
8
+ };
9
+ onPlayerInteract = async ({ row, column } = {}) => {
10
+ const { board, turn, selected } = this.state;
11
+ if (row == null || column == null || !board || !turn)
12
+ return;
13
+ const focus = { row, column };
14
+ const piece = board[focus.row]?.[focus.column] ?? null;
15
+ const legalFromState = this.state.legalMoves ?? [];
16
+ const move = selected && legalFromState.find((m) => samePos(m.from, selected) && samePos(m.to, focus));
17
+ if (move)
18
+ return void this.emitOne(this.EVENTS.CHECKERS.MOVE_PLAY, { move, controllerType: this.CONST.AI.PLAYER_TYPE });
19
+ if (piece && piece.color === turn) {
20
+ const result = (await this.emitOne(this.EVENTS.CHECKERS.MOVES_GET, { board, turn }));
21
+ const legalMoves = (result?.moves ?? []).filter((m) => samePos(m.from, focus));
22
+ if (legalMoves.length === 0)
23
+ return;
24
+ const nextSelected = selected && samePos(selected, focus) ? null : focus;
25
+ return void this.emit(this.EVENTS.CHECKERS_VIEW.PLAYER_SELECT, {
26
+ selected: nextSelected,
27
+ legalMoves: nextSelected ? legalMoves : [],
28
+ });
29
+ }
30
+ if (selected)
31
+ return void this.emit(this.EVENTS.CHECKERS_VIEW.PLAYER_SELECT, { selected: null, legalMoves: [] });
32
+ };
33
+ }
@@ -0,0 +1,9 @@
1
+ import { ModuleCore } from "@vnejs/module.core";
2
+ import type { CheckersPlayerSelectPayload } from "@vnejs/contracts.views.screens.checkers";
3
+ import type { CheckersViewPluginConstants, CheckersViewPluginEvents, CheckersViewPluginParams, CheckersViewPluginSettings } from "../types.js";
4
+ import { type CheckersViewState } from "../utils/checkers.js";
5
+ export declare class CheckersViewPlayerSelect extends ModuleCore<CheckersViewPluginEvents, CheckersViewPluginConstants, CheckersViewPluginSettings, CheckersViewPluginParams, CheckersViewState> {
6
+ name: string;
7
+ subscribe: () => void;
8
+ onPlayerSelect: ({ selected, legalMoves }?: CheckersPlayerSelectPayload) => Promise<void>;
9
+ }
@@ -0,0 +1,29 @@
1
+ import { ModuleCore } from "@vnejs/module.core";
2
+ import { buildGridItems } from "../utils/checkers.js";
3
+ export class CheckersViewPlayerSelect extends ModuleCore {
4
+ name = "checkers_view.player.select";
5
+ subscribe = () => {
6
+ this.on(this.EVENTS.CHECKERS_VIEW.PLAYER_SELECT, this.onPlayerSelect);
7
+ this.on(this.EVENTS.CHECKERS_VIEW.STATE_UPDATE, this.updateState);
8
+ };
9
+ onPlayerSelect = async ({ selected = null, legalMoves = [] } = {}) => {
10
+ const board = this.state.board;
11
+ if (!board)
12
+ return;
13
+ const nextSelected = selected;
14
+ const nextLegalMoves = legalMoves;
15
+ const gridItems = buildGridItems({
16
+ board,
17
+ selected: nextSelected,
18
+ legalMoves: nextLegalMoves,
19
+ gridRow: this.state.gridRow ?? null,
20
+ gridColumn: this.state.gridColumn ?? null,
21
+ });
22
+ await this.emit(this.EVENTS.CHECKERS_VIEW.STATE_UPDATE, {
23
+ selected: nextSelected,
24
+ legalMoves: nextLegalMoves,
25
+ gridItems,
26
+ });
27
+ await this.emit(this.EVENTS.CHECKERS_VIEW.UPDATE_FAST);
28
+ };
29
+ }
@@ -1,10 +1,10 @@
1
1
  import { ModuleView } from "@vnejs/module.components";
2
- import type { CheckersPluginConstants, CheckersPluginEvents, CheckersPluginParams, CheckersPluginSettings } from "../types.js";
3
- import type { CheckersPluginState } from "../utils/checkers.js";
4
- export declare class CheckersView extends ModuleView<CheckersPluginEvents, CheckersPluginConstants, CheckersPluginSettings, CheckersPluginParams, CheckersPluginState> {
2
+ import type { CheckersViewPluginConstants, CheckersViewPluginEvents, CheckersViewPluginParams, CheckersViewPluginSettings } from "../types.js";
3
+ import type { CheckersViewState } from "../utils/checkers.js";
4
+ export declare class CheckersViewView extends ModuleView<CheckersViewPluginEvents, CheckersViewPluginConstants, CheckersViewPluginSettings, CheckersViewPluginParams, CheckersViewState> {
5
5
  name: string;
6
- EVENT_UPDATE_VIEW: "vne:checkers:update";
6
+ EVENT_UPDATE_VIEW: "vne:checkers_view:update";
7
7
  LOC_LABEL: null;
8
8
  TRANSITION: number;
9
- renderFunc: import("@vnejs/module.components").ViewRenderFunc<CheckersPluginState>;
9
+ renderFunc: import("@vnejs/module.components").ViewRenderFunc<CheckersViewState>;
10
10
  }
@@ -1,9 +1,9 @@
1
1
  import { ModuleView } from "@vnejs/module.components";
2
2
  import { render } from "../view/index.js";
3
- export class CheckersView extends ModuleView {
4
- name = "checkers.view";
5
- EVENT_UPDATE_VIEW = this.EVENTS.CHECKERS.UPDATE;
3
+ export class CheckersViewView extends ModuleView {
4
+ name = "checkers_view.view";
5
+ EVENT_UPDATE_VIEW = this.EVENTS.CHECKERS_VIEW.UPDATE;
6
6
  LOC_LABEL = null;
7
- TRANSITION = this.PARAMS.CHECKERS.TRANSITION;
7
+ TRANSITION = this.PARAMS.CHECKERS_VIEW.TRANSITION;
8
8
  renderFunc = render;
9
9
  }
package/dist/types.d.ts CHANGED
@@ -1,9 +1,11 @@
1
1
  import type { ModuleComponentsConstants, ModuleComponentsEvents, ModuleComponentsParams, ModuleComponentsSettings } from "@vnejs/module.components";
2
+ import type { Constants as AiConstants, Params as AiParams, PluginName as AiPluginName, SubscribeEvents as AiSubscribeEvents } from "@vnejs/contracts.ai";
2
3
  import type { Constants as ControlsConstants, PluginName as ControlsPluginName } from "@vnejs/contracts.controls";
3
4
  import type { Constants as ScenarioConstants, PluginName as ScenarioPluginName, SubscribeEvents as ScenarioSubscribeEvents } from "@vnejs/contracts.core.scenario";
4
5
  import type { PluginName as LogsPluginName, SubscribeEvents as LogsSubscribeEvents } from "@vnejs/contracts.core.logs";
5
- import type { Constants, Params, PluginName, SubscribeEvents } from "@vnejs/contracts.views.screens.checkers";
6
- export type CheckersPluginEvents = ModuleComponentsEvents & Record<PluginName, SubscribeEvents> & Record<ScenarioPluginName, ScenarioSubscribeEvents> & Record<LogsPluginName, LogsSubscribeEvents>;
7
- export type CheckersPluginConstants = ModuleComponentsConstants & Record<PluginName, Constants> & Record<ControlsPluginName, ControlsConstants> & Record<ScenarioPluginName, ScenarioConstants>;
8
- export type CheckersPluginSettings = ModuleComponentsSettings;
9
- export type CheckersPluginParams = ModuleComponentsParams & Record<PluginName, Params>;
6
+ import type { Constants as CheckersConstants, Params as CheckersParams, PluginName as CheckersPluginName, SubscribeEvents as CheckersSubscribeEvents } from "@vnejs/contracts.game.checkers";
7
+ import type { Params, PluginName, SubscribeEvents } from "@vnejs/contracts.views.screens.checkers";
8
+ export type CheckersViewPluginEvents = ModuleComponentsEvents & Record<PluginName, SubscribeEvents> & Record<CheckersPluginName, CheckersSubscribeEvents> & Record<AiPluginName, AiSubscribeEvents> & Record<ScenarioPluginName, ScenarioSubscribeEvents> & Record<LogsPluginName, LogsSubscribeEvents>;
9
+ export type CheckersViewPluginConstants = ModuleComponentsConstants & Record<CheckersPluginName, CheckersConstants> & Record<AiPluginName, AiConstants> & Record<ControlsPluginName, ControlsConstants> & Record<ScenarioPluginName, ScenarioConstants>;
10
+ export type CheckersViewPluginSettings = ModuleComponentsSettings;
11
+ export type CheckersViewPluginParams = ModuleComponentsParams & Record<PluginName, Params> & Record<CheckersPluginName, CheckersParams> & Record<AiPluginName, AiParams>;