refactor: update api
This commit is contained in:
@@ -24,7 +24,7 @@ export const registry = createGameCommandRegistry<BoopState>();
|
||||
/**
|
||||
* 放置棋子到棋盘
|
||||
*/
|
||||
async function place(game: BoopGame, row: number, col: number, player: PlayerType, type: PieceType) {
|
||||
async function handlePlace(game: BoopGame, row: number, col: number, player: PlayerType, type: PieceType) {
|
||||
const value = game.value;
|
||||
// 从玩家supply中找到对应类型的棋子
|
||||
const part = findPartInRegion(game, player, type);
|
||||
@@ -43,12 +43,12 @@ async function place(game: BoopGame, row: number, col: number, player: PlayerTyp
|
||||
|
||||
return { row, col, player, type, partId };
|
||||
}
|
||||
const placeCommand = registry.register( 'place <row:number> <col:number> <player> <type>', place);
|
||||
const place = registry.register( 'place <row:number> <col:number> <player> <type>', handlePlace);
|
||||
|
||||
/**
|
||||
* 执行boop - 推动周围棋子
|
||||
*/
|
||||
async function boop(game: BoopGame, row: number, col: number, type: PieceType) {
|
||||
async function handleBoop(game: BoopGame, row: number, col: number, type: PieceType) {
|
||||
const booped: string[] = [];
|
||||
|
||||
const toRemove = new Set<string>();
|
||||
@@ -95,12 +95,12 @@ async function boop(game: BoopGame, row: number, col: number, type: PieceType) {
|
||||
|
||||
return { booped };
|
||||
}
|
||||
const boopCommand = registry.register('boop <row:number> <col:number> <type>', boop);
|
||||
const boop = registry.register('boop <row:number> <col:number> <type>', handleBoop);
|
||||
|
||||
/**
|
||||
* 检查是否有玩家获胜(三个猫连线)
|
||||
*/
|
||||
async function checkWin(game: BoopGame) {
|
||||
async function handleCheckWin(game: BoopGame) {
|
||||
for(const line of getLineCandidates()){
|
||||
let whites = 0;
|
||||
let blacks = 0;
|
||||
@@ -119,12 +119,12 @@ async function checkWin(game: BoopGame) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
const checkWinCommand = registry.register('check-win', checkWin);
|
||||
const checkWin = registry.register('check-win', handleCheckWin);
|
||||
|
||||
/**
|
||||
* 检查并执行小猫升级(三个小猫连线变成猫)
|
||||
*/
|
||||
async function checkGraduates(game: BoopGame){
|
||||
async function handleCheckGraduates(game: BoopGame){
|
||||
const toUpgrade = new Set<string>();
|
||||
for(const line of getLineCandidates()){
|
||||
let whites = 0;
|
||||
@@ -155,12 +155,12 @@ async function checkGraduates(game: BoopGame){
|
||||
}
|
||||
});
|
||||
}
|
||||
const checkGraduatesCommand = registry.register('check-graduates', checkGraduates);
|
||||
const checkGraduates = registry.register('check-graduates', handleCheckGraduates);
|
||||
|
||||
async function setup(game: BoopGame) {
|
||||
export async function start(game: BoopGame) {
|
||||
while (true) {
|
||||
const currentPlayer = game.value.currentPlayer;
|
||||
const { winner } = await turnCommand(game, currentPlayer);
|
||||
const { winner } = await turn(game, currentPlayer);
|
||||
|
||||
await game.produceAsync((state: BoopState) => {
|
||||
state.winner = winner;
|
||||
@@ -173,9 +173,8 @@ async function setup(game: BoopGame) {
|
||||
|
||||
return game.value;
|
||||
}
|
||||
registry.register('setup', setup);
|
||||
|
||||
async function checkFullBoard(game: BoopGame, turnPlayer: PlayerType){
|
||||
async function handleCheckFullBoard(game: BoopGame, turnPlayer: PlayerType){
|
||||
// 检查8-piece规则: 如果玩家所有8个棋子都在棋盘上且没有获胜,强制升级一个小猫
|
||||
const playerPieces = Object.values(game.value.pieces).filter(
|
||||
(p: BoopPart) => p.player === turnPlayer && p.regionId === 'board'
|
||||
@@ -186,8 +185,7 @@ async function checkFullBoard(game: BoopGame, turnPlayer: PlayerType){
|
||||
|
||||
const partId = await game.prompt(
|
||||
'play <player> <row:number> <col:number> [type:string]',
|
||||
(command: Command) => {
|
||||
const [player, row, col] = command.params as [PlayerType, number, number];
|
||||
(player: PlayerType, row: number, col: number, type?: PieceType) => {
|
||||
if (player !== turnPlayer) {
|
||||
throw `无效的玩家: ${player},期望的是 ${turnPlayer}。`;
|
||||
}
|
||||
@@ -211,12 +209,12 @@ async function checkFullBoard(game: BoopGame, turnPlayer: PlayerType){
|
||||
moveToRegion(cat || part, null, state.regions[turnPlayer]);
|
||||
});
|
||||
}
|
||||
const checkFullBoard = registry.register('check-full-board', handleCheckFullBoard);
|
||||
|
||||
async function turn(game: BoopGame, turnPlayer: PlayerType) {
|
||||
async function handleTurn(game: BoopGame, turnPlayer: PlayerType) {
|
||||
const {row, col, type} = await game.prompt(
|
||||
'play <player> <row:number> <col:number> [type:string]',
|
||||
(command: Command) => {
|
||||
const [player, row, col, type] = command.params as [PlayerType, number, number, PieceType?];
|
||||
(player: PlayerType, row: number, col: number, type?: PieceType) => {
|
||||
const pieceType = type === 'cat' ? 'cat' : 'kitten';
|
||||
|
||||
if (player !== turnPlayer) {
|
||||
@@ -239,17 +237,18 @@ async function turn(game: BoopGame, turnPlayer: PlayerType) {
|
||||
);
|
||||
const pieceType = type === 'cat' ? 'cat' : 'kitten';
|
||||
|
||||
await placeCommand(game, row, col, turnPlayer, pieceType);
|
||||
await boopCommand(game, row, col, pieceType);
|
||||
const winner = await checkWinCommand(game);
|
||||
await place(game, row, col, turnPlayer, pieceType);
|
||||
await boop(game, row, col, pieceType);
|
||||
const winner = await checkWin(game);
|
||||
if(winner) return { winner: winner as WinnerType };
|
||||
|
||||
await checkGraduatesCommand(game);
|
||||
await checkFullBoard(game, turnPlayer);
|
||||
await checkGraduates(game);
|
||||
await handleCheckFullBoard(game, turnPlayer);
|
||||
return { winner: null };
|
||||
}
|
||||
const turnCommand = registry.register('turn <player>', turn);
|
||||
export const commands = {
|
||||
const turn = registry.register('turn <player>', handleTurn);
|
||||
|
||||
export const prompts = {
|
||||
play: (player: PlayerType, row: number, col: number, type?: PieceType) => {
|
||||
if (type) {
|
||||
return `play ${player} ${row} ${col} ${type}`;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { BoopState } from '@/game';
|
||||
import { GameHostScene } from 'boardgame-phaser';
|
||||
import { commands } from '@/game';
|
||||
import { prompts } from '@/game';
|
||||
import { BoardRenderer } from './BoardRenderer';
|
||||
import { createPieceSpawner } from './PieceSpawner';
|
||||
import { SupplyUI } from './SupplyUI';
|
||||
@@ -73,7 +73,7 @@ export class GameScene extends GameHostScene<BoopState> {
|
||||
|
||||
private handleCellClick(row: number, col: number): void {
|
||||
const selectedType = this.pieceTypeSelector.getSelectedType();
|
||||
const cmd = commands.play(this.state.currentPlayer, row, col, selectedType);
|
||||
const cmd = prompts.play(this.state.currentPlayer, row, col, selectedType);
|
||||
const error = this.gameHost.onInput(cmd);
|
||||
if (error) {
|
||||
this.errorOverlay.show(error);
|
||||
@@ -82,7 +82,7 @@ export class GameScene extends GameHostScene<BoopState> {
|
||||
|
||||
private handlePieceClick(row: number, col: number): void {
|
||||
// 棋盘满时,点击棋子触发升级
|
||||
const cmd = commands.play(this.state.currentPlayer, row, col);
|
||||
const cmd = prompts.play(this.state.currentPlayer, row, col);
|
||||
const error = this.gameHost.onInput(cmd);
|
||||
if (error) {
|
||||
this.errorOverlay.show(error);
|
||||
@@ -90,10 +90,10 @@ export class GameScene extends GameHostScene<BoopState> {
|
||||
}
|
||||
|
||||
private startGame(): void {
|
||||
this.gameHost.setup('setup');
|
||||
this.gameHost.start();
|
||||
}
|
||||
|
||||
private restartGame(): void {
|
||||
this.gameHost.setup('setup');
|
||||
this.gameHost.start();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,19 +14,13 @@ export default function App<TState extends Record<string, unknown>>(props: { gam
|
||||
const scene = useComputed(() => new props.gameScene());
|
||||
|
||||
const handleReset = async () => {
|
||||
gameHost.value.gameHost.setup('setup').then(result => {
|
||||
if(!result.success) {
|
||||
console.error(result.error);
|
||||
}else{
|
||||
console.log('Game finished!', result.result);
|
||||
}
|
||||
});
|
||||
gameHost.value.gameHost.start();
|
||||
};
|
||||
const label = useComputed(() => gameHost.value.gameHost.status.value === 'running' ? 'Restart' : 'Start');
|
||||
|
||||
return (
|
||||
<div className="flex flex-col h-screen">
|
||||
<div className="flex-1 relative">
|
||||
<div className="flex-1 flex relative justify-center items-center">
|
||||
<PhaserGame config={{ width: 640, height: 750 }}>
|
||||
<PhaserScene sceneKey="GameScene" scene={scene.value} autoStart data={gameHost.value} />
|
||||
</PhaserGame>
|
||||
|
||||
Reference in New Issue
Block a user