@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.
- package/dist/index.d.ts +1 -0
- package/dist/index.js +21 -12
- package/dist/modules/board.d.ts +9 -0
- package/dist/modules/board.js +16 -0
- package/dist/modules/bridge.d.ts +8 -0
- package/dist/modules/bridge.js +10 -0
- package/dist/modules/click.d.ts +8 -0
- package/dist/modules/click.js +14 -0
- package/dist/modules/controller.accept.d.ts +7 -25
- package/dist/modules/controller.accept.js +12 -159
- package/dist/modules/controller.d.ts +4 -6
- package/dist/modules/controller.grid.d.ts +11 -11
- package/dist/modules/controller.grid.js +21 -25
- package/dist/modules/controller.js +8 -26
- package/dist/modules/player.interact.d.ts +9 -0
- package/dist/modules/player.interact.js +33 -0
- package/dist/modules/player.select.d.ts +9 -0
- package/dist/modules/player.select.js +29 -0
- package/dist/modules/view.d.ts +5 -5
- package/dist/modules/view.js +4 -4
- package/dist/types.d.ts +7 -5
- package/dist/utils/checkers.d.ts +19 -9
- package/dist/utils/checkers.js +30 -16
- package/dist/view/index.d.ts +2 -2
- package/dist/view/index.js +12 -12
- package/package.json +8 -2
- package/src/index.ts +21 -12
- package/src/modules/board.ts +29 -0
- package/src/modules/bridge.ts +20 -0
- package/src/modules/click.ts +28 -0
- package/src/modules/controller.accept.ts +20 -189
- package/src/modules/controller.grid.ts +23 -26
- package/src/modules/controller.ts +16 -36
- package/src/modules/player.interact.ts +48 -0
- package/src/modules/player.select.ts +42 -0
- package/src/modules/view.ts +12 -6
- package/src/tests/player.interact.test.ts +56 -0
- package/src/tests/setup.ts +21 -10
- package/src/types.ts +19 -6
- package/src/utils/checkers.ts +51 -25
- package/src/view/index.tsx +22 -23
- package/dist/modules/checkers.d.ts +0 -9
- package/dist/modules/checkers.js +0 -37
- package/dist/utils/ai.d.ts +0 -4
- package/dist/utils/ai.js +0 -27
- package/dist/utils/board.d.ts +0 -32
- package/dist/utils/board.js +0 -199
- package/src/modules/checkers.ts +0 -52
- package/src/tests/ai.test.ts +0 -61
- package/src/tests/board.test.ts +0 -43
- package/src/tests/checkers.test.ts +0 -58
- package/src/utils/ai.ts +0 -31
- package/src/utils/board.ts +0 -252
package/dist/index.d.ts
CHANGED
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 {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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 {
|
|
3
|
-
import type {
|
|
4
|
-
|
|
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:
|
|
9
|
-
EVENT_HIDE: "vne:
|
|
10
|
-
EVENT_ACCEPT: "vne:
|
|
11
|
-
EVENT_STATE_UPDATE: "vne:
|
|
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
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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.
|
|
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
|
|
67
|
-
if (gridRow == null || gridColumn == null
|
|
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
|
-
|
|
151
|
-
|
|
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 {
|
|
3
|
-
import {
|
|
4
|
-
export declare class
|
|
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:
|
|
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 {
|
|
3
|
-
import { type
|
|
4
|
-
export declare class
|
|
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:
|
|
7
|
-
EVENT_HIDE: "vne:
|
|
8
|
-
EVENT_STATE_UPDATE: "vne:
|
|
9
|
-
EVENT_UPDATE_FAST: "vne:
|
|
10
|
-
EVENT_GRID_NEXT: "vne:
|
|
11
|
-
EVENT_GRID_PREV: "vne:
|
|
12
|
-
EVENT_GRID_CLEAR: "vne:
|
|
13
|
-
EVENT_GRID_UPDATE_ITEMS: "vne:
|
|
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
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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.
|
|
18
|
-
getMaxColumns = () => this.PARAMS.
|
|
19
|
-
getGridItems = async () => {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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
|
-
|
|
3
|
-
|
|
4
|
-
|
|
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.
|
|
6
|
+
CONTROLS_INDEX = this.PARAMS.CHECKERS_VIEW.ZINDEX;
|
|
8
7
|
subscribe = () => {
|
|
9
|
-
this.on(this.EVENTS.
|
|
10
|
-
this.on(this.EVENTS.
|
|
11
|
-
this.on(this.EVENTS.
|
|
12
|
-
this.on(this.EVENTS.
|
|
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
|
+
}
|
package/dist/modules/view.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { ModuleView } from "@vnejs/module.components";
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
4
|
-
export declare class
|
|
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:
|
|
6
|
+
EVENT_UPDATE_VIEW: "vne:checkers_view:update";
|
|
7
7
|
LOC_LABEL: null;
|
|
8
8
|
TRANSITION: number;
|
|
9
|
-
renderFunc: import("@vnejs/module.components").ViewRenderFunc<
|
|
9
|
+
renderFunc: import("@vnejs/module.components").ViewRenderFunc<CheckersViewState>;
|
|
10
10
|
}
|
package/dist/modules/view.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { ModuleView } from "@vnejs/module.components";
|
|
2
2
|
import { render } from "../view/index.js";
|
|
3
|
-
export class
|
|
4
|
-
name = "
|
|
5
|
-
EVENT_UPDATE_VIEW = this.EVENTS.
|
|
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.
|
|
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.
|
|
6
|
-
|
|
7
|
-
export type
|
|
8
|
-
export type
|
|
9
|
-
export type
|
|
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>;
|