Skip to content

Commit

Permalink
Allow player to submit answer
Browse files Browse the repository at this point in the history
This will allow a player to submit an answer and add it to the array
of answers in the round state machine

Co-authored-by: Liz Daly <50752284+lookupdaily@users.noreply.github.com>
Co-authored-by: Rich James <richpjames@users.noreply.github.com>
  • Loading branch information
3 people committed Feb 20, 2024
1 parent fea6f64 commit f21dc09
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 4 deletions.
24 changes: 23 additions & 1 deletion client/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { io } from "socket.io-client";
import { Player, Question } from "../server/@types/models";
import { Answer, Colour, Player, Question } from "../server/@types/models";
import { NameFormElement } from "../server/@types/ui";
import { getElementById } from "./utils/getElementById";

Expand Down Expand Up @@ -37,6 +37,12 @@ const renderColourCheckboxes = (): void => {
const template = getElementById<HTMLTemplateElement>("checkbox-template");
const clone = template.content.cloneNode(true) as DocumentFragment;
colourSection.appendChild(clone);

const colourForm = getElementById<HTMLFormElement>("checkbox-form");
colourForm.addEventListener("submit", (e) => {
e.preventDefault();
submitAnswers(colourForm);
});
};

const derenderNameForm = (): void => {
Expand All @@ -57,6 +63,22 @@ const derenderStartButton = (): void => {
startButton.remove();
};

const submitAnswers = async (form: HTMLFormElement): Promise<void> => {
const checked = form.querySelectorAll('input[type="checkbox"]:checked');
const colours: Answer["colours"] = Array.from(checked).map(
(checked) => checked.id as Colour,
);
socket.emit("answers:post", { colours });
derenderColorCheckboxes();
getElementById("colour-section").innerText = `You picked: ${colours.join(
", ",
)}`;
};

const derenderColorCheckboxes = (): void => {
getElementById("checkbox-form").remove();
};

const connectionStatusIconElement = getElementById("connection-status-icon");
const nameFormElement = getElementById("name-form") as NameFormElement;
const playerListElement = getElementById("player-list");
Expand Down
20 changes: 19 additions & 1 deletion server/@types/models/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
import type { Socket } from "socket.io";

type Answer = {
colours: Colour[];
socketId: Socket["id"];
};

type Colour =
| "black"
| "blue"
| "brown"
| "green"
| "grey"
| "orange"
| "pink"
| "purple"
| "red"
| "white"
| "yellow";

type Player = {
name: string;
socketId: Socket["id"];
Expand All @@ -11,4 +29,4 @@ type Question = {
question: string;
};

export type { Player, Question };
export type { Answer, Colour, Player, Question };
12 changes: 12 additions & 0 deletions server/events/severbound.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import type { Server, Socket } from "socket.io";

import { Colour } from "../@types/models";
import type { Lobby } from "../lobby";
import { Round } from "../round";
import type { SocketServer } from "../socketServer";
import { clientboundEvents } from "./clientbound";

Expand All @@ -19,6 +21,16 @@ const serverboundEvents = {
},
];
},
postAnswers(
socket: Socket,
round?: Round,
): [string, (data: { colours: Colour[] }) => void] {
return [
"answers:post",
(data: { colours: Colour[] }) =>
round?.addAnswer({ colours: data.colours, socketId: socket.id }),
];
},
postPlayers: (
lobby: Lobby,
socket: Socket,
Expand Down
11 changes: 10 additions & 1 deletion server/machines/round.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { assign, createMachine } from "xstate";
import { Answer } from "../@types/models";

type Question = {
answer: string[];
Expand All @@ -7,14 +8,16 @@ type Question = {
};

const context = {
answers: [] as Answer[],
questions: [] as Question[],
selectedQuestion: {} as Question | undefined,
};

type Context = typeof context;

type Events = {
type: string;
type: "playerSubmitsAnswer";
answer: Answer;
};

const gameMachine = createMachine(
Expand All @@ -30,12 +33,18 @@ const gameMachine = createMachine(
states: {
gameStart: {
entry: ["setQuestion"],
on: {
playerSubmitsAnswer: { actions: "addAnswer" },
},
},
},
tsTypes: {} as import("./round.typegen").Typegen0,
},
{
actions: {
addAnswer: assign({
answers: (context, event) => [...context.answers, event.answer],
}),
setQuestion: assign({
selectedQuestion: ({ questions }) => {
const questionIndex = Math.floor(
Expand Down
1 change: 1 addition & 0 deletions server/machines/round.typegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export interface Typegen0 {
services: never;
};
eventsCausingActions: {
addAnswer: "playerSubmitsAnswer";
setQuestion: "xstate.init";
};
eventsCausingDelays: {};
Expand Down
6 changes: 5 additions & 1 deletion server/round.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { InterpreterFrom } from "xstate";
import { interpret } from "xstate";

import { Question } from "./@types/models";
import { Answer, Question } from "./@types/models";
import questions from "./data/questions.json";
import { context, gameMachine } from "./machines/round";
import type { SocketServer } from "./socketServer";
Expand Down Expand Up @@ -31,6 +31,10 @@ class Round {
}
});
}

addAnswer(answer: Answer) {
this.machine.send({ type: "playerSubmitsAnswer", answer });
}
}

export { Round };
1 change: 1 addition & 0 deletions server/socketServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export class SocketServer {
...serverboundEvents.disconnect(this.lobby, socket, this.server),
);
socket.on(...serverboundEvents.startRound(this));
socket.on(...serverboundEvents.postAnswers(socket, this.round));
});
}

Expand Down

0 comments on commit f21dc09

Please sign in to comment.