added basic scaffold for wheel of fortune
This commit is contained in:
parent
9433546a3f
commit
553f09cc7c
92
index.html
Normal file
92
index.html
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Multiplayer Game</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<button id="create-room">Create Room</button>
|
||||||
|
<input id="join-code" placeholder="Enter room code">
|
||||||
|
<button id="join-room">Join Room</button>
|
||||||
|
|
||||||
|
<div id="status"></div>
|
||||||
|
<button id="start-game" style="display: none;">Start Game</button>
|
||||||
|
<button id="spin-wheel" style="display: none;">Spin Wheel</button>
|
||||||
|
<input id="guess-letter" placeholder="Guess a letter" style="display: none;">
|
||||||
|
<button id="guess-button" style="display: none;">Guess</button>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const socket = new WebSocket("ws://localhost:8080");
|
||||||
|
|
||||||
|
document.getElementById("create-room").onclick = () => {
|
||||||
|
socket.send(JSON.stringify({ type: "create_room" }));
|
||||||
|
};
|
||||||
|
|
||||||
|
document.getElementById("join-room").onclick = () => {
|
||||||
|
const roomCode = document.getElementById("join-code").value;
|
||||||
|
socket.send(JSON.stringify({ type: "join_room", roomCode }));
|
||||||
|
};
|
||||||
|
|
||||||
|
document.getElementById("start-game").onclick = () => {
|
||||||
|
socket.send(JSON.stringify({ type: "start_game" }));
|
||||||
|
};
|
||||||
|
|
||||||
|
document.getElementById("spin-wheel").onclick = () => {
|
||||||
|
socket.send(JSON.stringify({ type: "spin_wheel" }));
|
||||||
|
};
|
||||||
|
|
||||||
|
document.getElementById("guess-button").onclick = () => {
|
||||||
|
const letter = document.getElementById("guess-letter").value;
|
||||||
|
socket.send(JSON.stringify({ type: "guess_letter", letter }));
|
||||||
|
document.getElementById("guess-letter").value = ""; // Clear input
|
||||||
|
};
|
||||||
|
|
||||||
|
socket.onmessage = (event) => {
|
||||||
|
const message = JSON.parse(event.data);
|
||||||
|
|
||||||
|
if (message.type === "room_created") {
|
||||||
|
document.getElementById("status").innerText = `Room created! Code: ${message.roomCode}`;
|
||||||
|
if (message.isLeader) {
|
||||||
|
document.getElementById("start-game").style.display = "inline";
|
||||||
|
document.getElementById("spin-wheel").style.display = "inline";
|
||||||
|
document.getElementById("guess-letter").style.display = "inline";
|
||||||
|
document.getElementById("guess-button").style.display = "inline";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.type === "joined_room") {
|
||||||
|
const status = message.isLeader ? "You are the party leader!" : "You joined the room!";
|
||||||
|
document.getElementById("status").innerText = `Room Code: ${message.roomCode} - ${status}`;
|
||||||
|
if (message.isLeader) {
|
||||||
|
document.getElementById("start-game").style.display = "inline";
|
||||||
|
document.getElementById("spin-wheel").style.display = "inline";
|
||||||
|
document.getElementById("guess-letter").style.display = "inline";
|
||||||
|
document.getElementById("guess-button").style.display = "inline";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.type === "game_started") {
|
||||||
|
document.getElementById("status").innerText = "The game has started!";
|
||||||
|
document.getElementById("start-game").style.display = "none";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.type === "spin_result") {
|
||||||
|
document.getElementById("status").innerText = `Spin result: ${message.spinResult} points (${message.player})`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.type === "guess_result") {
|
||||||
|
const outcome = message.correct ? "correct" : "incorrect";
|
||||||
|
document.getElementById("status").innerText = `Guess '${message.letter}' was ${outcome} (${message.player})`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.type === "new_leader") {
|
||||||
|
document.getElementById("status").innerText = "You are now the party leader!";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message.type === "error") {
|
||||||
|
alert(message.message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
49
package-lock.json
generated
Normal file
49
package-lock.json
generated
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
{
|
||||||
|
"name": "wheeloffortune",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"name": "wheeloffortune",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"uuid": "^11.0.2",
|
||||||
|
"ws": "^8.18.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/uuid": {
|
||||||
|
"version": "11.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-11.0.2.tgz",
|
||||||
|
"integrity": "sha512-14FfcOJmqdjbBPdDjFQyk/SdT4NySW4eM0zcG+HqbHP5jzuH56xO3J1DGhgs/cEMCfwYi3HQI1gnTO62iaG+tQ==",
|
||||||
|
"funding": [
|
||||||
|
"https://github.com/sponsors/broofa",
|
||||||
|
"https://github.com/sponsors/ctavan"
|
||||||
|
],
|
||||||
|
"bin": {
|
||||||
|
"uuid": "dist/esm/bin/uuid"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ws": {
|
||||||
|
"version": "8.18.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
|
||||||
|
"integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"bufferutil": "^4.0.1",
|
||||||
|
"utf-8-validate": ">=5.0.2"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"bufferutil": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"utf-8-validate": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
15
package.json
Normal file
15
package.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "wheeloffortune",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "play Wheel Of Fortune with friends online",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"author": "Meleeman",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"uuid": "^11.0.2",
|
||||||
|
"ws": "^8.18.0"
|
||||||
|
}
|
||||||
|
}
|
24
puzzles.json
Normal file
24
puzzles.json
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"given": ["a","b","r"],
|
||||||
|
"answer": "naggers",
|
||||||
|
"category": "people who annoy you"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"given": ["a","b","r"],
|
||||||
|
"answer": "karen",
|
||||||
|
"category": "people who annoy you"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"given": ["a","b","r"],
|
||||||
|
"answer": "Andy",
|
||||||
|
"category": "people who annoy you"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"given": ["a","b","r"],
|
||||||
|
"answer": "Wet Back",
|
||||||
|
"category":"alternative names"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
95
server.js
Normal file
95
server.js
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
const WebSocket = require("ws");
|
||||||
|
const { v4: uuidv4 } = require("uuid");
|
||||||
|
const puzzles = require('./puzzles.json');
|
||||||
|
const crypto = require('crypto');
|
||||||
|
|
||||||
|
const wss = new WebSocket.Server({ port: 8080 });
|
||||||
|
const rooms = {}; // Stores rooms and their clients
|
||||||
|
const wheel = [
|
||||||
|
'lose a turn',800,350,450,700,300,600,5000,
|
||||||
|
300,600,300,500,800,550,400,300,900,500,'spin again',
|
||||||
|
900,'Bankrupt',600,400,300
|
||||||
|
] //represents wheel in wheel of fortune game.
|
||||||
|
function getRandomValue(array) {
|
||||||
|
const randomIndex = crypto.randomInt(0, array.length);
|
||||||
|
return array[randomIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
// server.js
|
||||||
|
wss.on("connection", (ws) => {
|
||||||
|
ws.on("message", (message) => {
|
||||||
|
const data = JSON.parse(message);
|
||||||
|
|
||||||
|
if (data.type === "create_room") {
|
||||||
|
const roomCode = uuidv4().slice(0, 5);
|
||||||
|
rooms[roomCode] = { clients: [ws], leader: ws, gameState: {} };
|
||||||
|
ws.roomCode = roomCode;
|
||||||
|
ws.send(JSON.stringify({ type: "room_created", roomCode, isLeader: true }));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.type === "join_room") {
|
||||||
|
const { roomCode } = data;
|
||||||
|
if (rooms[roomCode]) {
|
||||||
|
rooms[roomCode].clients.push(ws);
|
||||||
|
ws.roomCode = roomCode;
|
||||||
|
ws.send(JSON.stringify({ type: "joined_room", roomCode, isLeader: rooms[roomCode].leader === ws }));
|
||||||
|
} else {
|
||||||
|
ws.send(JSON.stringify({ type: "error", message: "Room not found" }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.type === "start_game") {
|
||||||
|
const room = rooms[ws.roomCode];
|
||||||
|
console.log('game started for:',room);
|
||||||
|
if (room && room.leader === ws) {
|
||||||
|
room.clients.forEach((client) => {
|
||||||
|
client.send(JSON.stringify({ type: "game_started", roomCode: ws.roomCode }));
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
ws.send(JSON.stringify({ type: "error", message: "Only the leader can start the game" }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.type === "spin_wheel" || data.type === "guess_letter") {
|
||||||
|
const room = rooms[ws.roomCode];
|
||||||
|
if (room && room.clients.includes(ws)) {
|
||||||
|
// Handle spin and guess events
|
||||||
|
if (data.type === "spin_wheel") {
|
||||||
|
// Simulate a wheel spin result and update room state
|
||||||
|
const spinResult = getRandomValue(wheel);
|
||||||
|
room.gameState.spinResult = spinResult;
|
||||||
|
room.clients.forEach((client) =>
|
||||||
|
client.send(JSON.stringify({ type: "spin_result", spinResult, player: ws === room.leader ? "Leader" : "Player" }))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.type === "guess_letter") {
|
||||||
|
const { letter } = data;
|
||||||
|
// Handle guess logic (e.g., check if the letter is in the puzzle)
|
||||||
|
const correctGuess = Math.random() > 0.5; // Random outcome for simplicity
|
||||||
|
room.gameState.lastGuess = { letter, correct: correctGuess };
|
||||||
|
room.clients.forEach((client) =>
|
||||||
|
client.send(JSON.stringify({ type: "guess_result", letter, correct: correctGuess, player: ws === room.leader ? "Leader" : "Player" }))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ws.send(JSON.stringify({ type: "error", message: "You are not in this room" }));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ws.on("close", () => {
|
||||||
|
if (ws.roomCode && rooms[ws.roomCode]) {
|
||||||
|
const room = rooms[ws.roomCode];
|
||||||
|
room.clients = room.clients.filter((client) => client !== ws);
|
||||||
|
if (room.leader === ws && room.clients.length > 0) {
|
||||||
|
room.leader = room.clients[0];
|
||||||
|
room.leader.send(JSON.stringify({ type: "new_leader" }));
|
||||||
|
}
|
||||||
|
if (room.clients.length === 0) delete rooms[ws.roomCode];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
console.log("WebSocket server is running on ws://localhost:8080");
|
Loading…
Reference in New Issue
Block a user