Cursor teaching me how to re-write my big-two game with xstate which is awesome. Its not so scary when applied to a real life context. the API sort of reminds of vue.js options API
export const createBigTwoGameMachine = createMachine(
{
id: "bigTwoGame",
initial: "WAITING_FOR_PLAYERS",
types: {
// Types for context, states, actions etc all go here
},
context: {
players: [],
currentPlayerIndex: 0,
roundMode: null,
cardPile: [],
consecutivePasses: 0,
winner: undefined,
},
states: {
// Define all possible state here and also what those state can transition to. we can also place guards and other things in thes states too. e.g
WAITING_FOR_PLAYERS: {
on: {
JOIN_GAME: {
actions: ["addPlayer"],
},
START_GAME: {
target: "GAME_STARTING",
guard: "hasEnoughPlayers",
},
},
}
},
},
{
guards: {
// small functions to guard against impossible states
hasEnoughPlayers: ({ context }) => context.players.length >= 2,
},
actions: {
// actions like dispatchers, the actual buisness logic to update the state context. this where mutations live.
addPlayer: ({
context,
event,
}: {
context: GameContext;
event: GameEvent;
}) => {
context.players.push({
id: event.playerId,
name: event.playerName,
hand: [],
});
},
},
}
);
…and it has also taught me the slightly new setup
version of the this API too.
export const createBigTwoGameMachine = setup({
types: {
context: {} as GameContext,
events: {} as GameEvent,
},
actions: {
dealCards: ({ context }) => {
// Implementation here
},
playCards: ({ context, event }) => {
// Implementation here
},
setRoundMode: ({ context, event }) => {
// Implementation here
},
},
guards: {
hasMaxPlayers: ({ context }) => context.players.length !== 4,
},
}).createMachine({
id: "bigTwoGame",
initial: "WAITING_FOR_PLAYERS",
context: {
players: [],
currentPlayerIndex: 0,
roundMode: null,
cardPile: [],
consecutivePasses: 0,
winner: undefined,
},
states: {
WAITING_FOR_PLAYERS: {
on: {
JOIN_GAME: {
actions: ["addPlayer"],
guard: "hasMaxPlayers",
},
START_GAME: {
target: "GAME_STARTING",
},
},
},S
},
});