71 lines
1.9 KiB
TypeScript
71 lines
1.9 KiB
TypeScript
import { MutableSignal, mutableSignal, computed, ReadonlySignal } from 'boardgame-core';
|
|
import {getAvailableMoves, OnitamaState} from "boardgame-core/samples/onitama";
|
|
|
|
export interface ValidMove {
|
|
card: string;
|
|
fromX: number;
|
|
fromY: number;
|
|
toX: number;
|
|
toY: number;
|
|
}
|
|
|
|
// 先选择牌,然后选择棋子,最后选择移动
|
|
export interface OnitamaUIState {
|
|
selectedPiece: { x: number; y: number } | null;
|
|
selectedCard: string | null;
|
|
}
|
|
|
|
export function createUIState(): MutableSignal<OnitamaUIState> {
|
|
return mutableSignal<OnitamaUIState>({
|
|
selectedPiece: null,
|
|
selectedCard: null,
|
|
});
|
|
}
|
|
|
|
export function createValidMoves(state: ReadonlySignal<OnitamaState>, ui: ReadonlySignal<OnitamaUIState>){
|
|
return computed(() => {
|
|
return getAvailableMoves(state.value, state.value.currentPlayer)
|
|
.filter(move => {
|
|
const {selectedCard, selectedPiece} = ui.value;
|
|
return selectedPiece?.x === move.fromX && selectedPiece?.y === move.fromY && selectedCard === move.card;
|
|
})
|
|
});
|
|
}
|
|
|
|
export function clearSelection(uiState: MutableSignal<OnitamaUIState>): void {
|
|
uiState.produce(state => {
|
|
state.selectedPiece = null;
|
|
state.selectedCard = null;
|
|
});
|
|
}
|
|
|
|
export function selectPiece(
|
|
uiState: MutableSignal<OnitamaUIState>,
|
|
x: number,
|
|
y: number
|
|
): void {
|
|
uiState.produce(state => {
|
|
// 如果点击已选中的棋子,取消选择
|
|
if(state.selectedPiece?.x === x && state.selectedPiece?.y === y){
|
|
state.selectedPiece = null;
|
|
}else{
|
|
state.selectedPiece = { x, y };
|
|
}
|
|
});
|
|
}
|
|
|
|
export function selectCard(
|
|
uiState: MutableSignal<OnitamaUIState>,
|
|
card: string
|
|
): void {
|
|
uiState.produce(state => {
|
|
// 如果点击已选中的卡牌,取消选择
|
|
if (state.selectedCard === card) {
|
|
state.selectedCard = null;
|
|
} else {
|
|
// 选择新卡牌,清除棋子选择
|
|
state.selectedCard = card;
|
|
}
|
|
});
|
|
}
|