Skip to content

Instantly share code, notes, and snippets.

@flofehrenbacher
Created January 24, 2021 15:39
Show Gist options
  • Save flofehrenbacher/87d8c15891b31d6ba83c822fd2e028d8 to your computer and use it in GitHub Desktop.
Save flofehrenbacher/87d8c15891b31d6ba83c822fd2e028d8 to your computer and use it in GitHub Desktop.
Generated by XState Viz: https://xstate.js.org/viz
const gameMachine = Machine(
{
strict: true,
id: 'game',
context: {
currentPlayerId: '',
players: [],
stack: [],
order: [],
gamePlayed: null,
},
initial: 'lobby',
on: {
RESET_GAME: 'lobby',
},
states: {
lobby: {
on: {
UPDATE_PLAYERS: {
target: 'lobby',
actions: ['updatePlayers'],
},
START_BIDDING: {
target: 'bidding',
cond: fourPlayersInGame,
actions: ['initializeGame'],
},
},
},
bidding: {
on: {
START_PLAYING: { target: 'playing', actions: ['startPlaying'] },
CHOOSE_GAME: { target: 'bidding', actions: ['chooseGame'] },
},
},
playing: {
on: {
PLAY_CARD: {
target: 'playing',
actions: ['playCard'],
},
FINISH_GAME: 'evaluation',
},
},
evaluation: {
on: { START_AGAIN: 'bidding' },
},
},
},
{
actions: {
initializeGame: assign((c, e) =>
e.type === 'START_BIDDING'
? {
currentPlayerId: e.currentPlayerId,
order: e.order,
players: e.players,
}
: c,
),
updatePlayers: assign((c, e) =>
e.type === 'UPDATE_PLAYERS'
? {
players: e.players,
}
: c,
),
playCard: assign((c, e) =>
e.type === 'PLAY_CARD'
? {
stack: [e.card, ...c.stack],
currentPlayerId: c.order[findNextPlayerIndex(c.order, c.currentPlayerId)],
players: removeCardFromHand(c.players, e.card, c.currentPlayerId),
}
: c,
),
chooseGame: assign((c, e) =>
e.type === 'CHOOSE_GAME'
? {
gamePlayed: e.gamePlayed,
currentPlayerId: c.order[findNextPlayerIndex(c.order, c.currentPlayerId)],
}
: c,
),
startPlaying: assign({
order: (c) => c.players.map((p) => p.id),
currentPlayerId: (c) => c.players[0].id,
}),
},
guards: {
fourPlayersInGame,
},
},
)
function fourPlayersInGame(context) {
return context.players.length === 4
}
function findNextPlayerIndex(order, currentPlayerId) {
const currentPlayerIndex = order.findIndex((id) => currentPlayerId === id)
return currentPlayerIndex < order.length - 1 ? currentPlayerIndex + 1 : 0
}
function removeCardFromHand(players, card, currentPlayerId) {
const currentPlayer = players.find((p) => p.id === currentPlayerId)
if (!currentPlayer) return players
const updatedCards = currentPlayer?.cards?.filter((c) => c !== card)
return [
...players.filter((p) => p.id !== currentPlayerId),
{ ...currentPlayer, cards: updatedCards },
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment