Skip to content

Commit

Permalink
Handle players leaving in GameStart state
Browse files Browse the repository at this point in the history
- If a player leaves ensure the correct action takes place
- Change the state back to OnePlayer if the player count ever reaches 1

Add tests for changing state on player leaves

If we remove the cap on two players, we should add an additional test for the condition (which checks that there is only one player left before changing back to `OnePlayer` state.
We should also add tests for the number of players on action 'playerLeaves'.
  • Loading branch information
lookupdaily authored and rich committed Nov 29, 2023
1 parent 142b524 commit 1feb860
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 2 deletions.
38 changes: 37 additions & 1 deletion server/machines/lobby.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { describe, expect, it, beforeEach, afterEach } from "bun:test";
import { describe, expect, it } from "bun:test";
import { lobbyMachine, isNewPlayer, context } from "./lobby";
import { interpret } from "xstate";

Expand Down Expand Up @@ -83,6 +83,42 @@ describe("lobbyMachine", () => {
).toBe("GameStart");
});
});

describe("On playerLeaves", () => {
it("transitions from OnePlayer to Empty state", () => {
expect(lobbyMachine.transition("OnePlayer", "playerLeaves").value).toBe(
"Empty",
);
});

it("transitions from Multiple players to one player when player leaves", () => {
expect(
lobbyMachine.transition("MultiplePlayers", "playerLeaves").value,
).toBe("OnePlayer");
});

it("transitions from GameStart to OnePlayer if there is only one player left", () => {
const actor = interpret(lobbyMachine);
actor.start();
const player1 = { socketId: "id", name: "a name" };
const player2 = { socketId: "id-2", name: "a name 2" };

const players = [player1, player2];

players.forEach((player) => {
actor.send({
type: "playerJoins",
player: player,
});
});

actor.send({ type: "playerClicksStart" });
expect(actor.getSnapshot().value).toBe("GameStart");

actor.send({ type: "playerLeaves", socketId: "id" });
expect(actor.getSnapshot().value).toBe("OnePlayer");
});
});
});

describe("isNewPlayer", () => {
Expand Down
12 changes: 11 additions & 1 deletion server/machines/lobby.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,11 @@ export const isNewPlayer = (
{ player }: { player: Player },
) => players.map((player) => player.socketId).indexOf(player.socketId) === -1;

export const isOnlyPlayer = ({ players }: { players: Array<Player> }) =>
players.length === 1;

export const lobbyMachine = createMachine(
{
/** @xstate-layout N4IgpgJg5mDOIC5QBsD2AjdBPAdAUQFsAHAFywGIjkBDLMAJwClUBLAO1gG0AGAXUVBFUsFiRao2AkAA9EARgAsANhwAOBQGYA7AFYNSjYoBMSrQBoQWeVpVajcjZo2q53He40BfTxbSZcAPJsYAAKNHT0lOEMzOxcfFJCImISUrIImqo4JhrcDqpG6lpyFlYIcjoqmgqqqloaAJxydbrevhjYOEGh0ZFUtAwAMmDUAG5wPPxIIEmi4pLT6Yoq6tp6BsampYguOBpGRk21utxaqg1ePiB+nQCyAK7IYlQ9A-SwUW8AwsgsAMYAa1gAGUSNR6CRJolhHNUosdg5sgoGg0lNxTlozm5tuVFDglA1uA16nIGnpdEY2tcOrgHk8WC8wm8Pv0IsMxhMEtNZikFqB0sijDhUY4GvZ0R4FDjXCo0RctDUlAojJUyd4rmxUBA4FIbmVBDDeWlEABaJQ4k06YUohouByuJwGKl6-DEMjQ5LzY0ZIzSolqHTnRzKQO5YrOmldYJMiIe2F8mSIXJWwN2ZxGBRaMky6VyIUaQMXBQh1RhhQR-w4OnPZCvCLwbmGr3whBKho4ORKYxGYqGQklSzyPGqQvBpSh07lq4ugDi1AIYFB4JIcaNLZRWSzSgKOmahh0Ch0uYUAaDxfHpcn6s8QA */
tsTypes: {} as import("./lobby.typegen").Typegen0,
schema: {
context: {} as Context,
Expand Down Expand Up @@ -73,6 +75,13 @@ export const lobbyMachine = createMachine(
},
GameStart: {
entry: ["setQuestion"],
always: {
target: "OnePlayer",
cond: "isOnlyPlayer",
},
on: {
playerLeaves: { actions: "removePlayer" },
},
},
},
},
Expand All @@ -94,6 +103,7 @@ export const lobbyMachine = createMachine(
},
guards: {
isNewPlayer,
isOnlyPlayer,
},
},
);

0 comments on commit 1feb860

Please sign in to comment.