working on gameflow added turnState logic, basic puzzle solving logic

This commit is contained in:
Meleeman01 2025-01-18 21:08:50 -06:00
parent 5a3095aa73
commit 7c3eb6ed57
3 changed files with 173 additions and 25 deletions

View File

@ -264,7 +264,7 @@
// Start spinning // Start spinning
function startSpin(targetIndex) { function startSpin(targetIndex) {
console.log('targetIndex: ',targetIndex); console.log('targetIndex: ',targetIndex);
let resultingSpeed = wheelSpinSpeedData[targetIndex]; let resultingSpeed = wheelSpinSpeedData[targetIndex[0]];
console.log('resultingSpeed: ', resultingSpeed); console.log('resultingSpeed: ', resultingSpeed);
if (spinning) return; if (spinning) return;
rotation = 0 - (.283*6) rotation = 0 - (.283*6)
@ -276,12 +276,13 @@
console.log(anglePerSegment); console.log(anglePerSegment);
let currentRotation = rotation; // Start from the current rotation let currentRotation = rotation; // Start from the current rotation
spinSpeed = wheelSpinSpeedData[targetIndex]; // Initial speed spinSpeed = wheelSpinSpeedData[targetIndex[0]]; // Initial speed
function animate() { function animate() {
if ( spinSpeed < 0.001) { if ( spinSpeed < 0.001) {
spinning = false; spinning = false;
console.log(`Landed on: ${wheel[targetIndex]}`); spinSpeed = 0;
console.log(`Landed on: ${wheel[targetIndex[0]]}`);
return; return;
} }
// console.log('currentRotation: ',currentRotation); // console.log('currentRotation: ',currentRotation);
@ -413,6 +414,20 @@
nameDialog.close(); nameDialog.close();
}); });
} }
function changeSpinGuessState(message) {
if(message.turnState == 'spin') {
document.getElementById("spin-wheel").style.display = "none";
document.getElementById("guess-letter").style.display = "inline";
document.getElementById("guess-button").style.display = "inline";
}
if (message.turnState == 'guess') {
document.getElementById("spin-wheel").style.display = "none";
document.getElementById("guess-letter").style.display = "inline";
document.getElementById("guess-button").style.display = "inline";
}
}
const socket = new WebSocket("ws://localhost:8080"); const socket = new WebSocket("ws://localhost:8080");
document.getElementById("create-room").onclick = function () { document.getElementById("create-room").onclick = function () {
@ -495,6 +510,16 @@
document.getElementById("guess-letter").style.display = "none"; document.getElementById("guess-letter").style.display = "none";
document.getElementById("guess-button").style.display = "none"; document.getElementById("guess-button").style.display = "none";
} }
if (message.type === "new_puzzle") {
let result = drawPuzzle(message);
console.log('new_puzzle', message);
console.log(result);
document.getElementById("status").innerText = "New Puzzle!";
document.getElementById("start-game").style.display = "none";
document.getElementById("spin-wheel").style.display = "inline";
document.getElementById("guess-letter").style.display = "none";
document.getElementById("guess-button").style.display = "none";
}
if (message.type === "spin_result") { if (message.type === "spin_result") {
console.log('spin result recieved'); console.log('spin result recieved');
@ -510,9 +535,11 @@
console.log(filterResultsArr[0][0]); console.log(filterResultsArr[0][0]);
//if there is multiple entries where the spin exists pick a random index. //if there is multiple entries where the spin exists pick a random index.
if(filterResultsArr.length > 1) { if(filterResultsArr.length > 1) {
startSpin(filterResultsArr[Math.floor(Math.random() * filterResultsArr.length)][0]); console.log('if fra.length > 1',filterResultsArr[0])
startSpin(filterResultsArr[0][0]);
} }
else{ else{
console.log('else',filterResultsArr[0])
startSpin(filterResultsArr[0]); startSpin(filterResultsArr[0]);
} }
document.getElementById("spin-wheel").style.display = "none"; document.getElementById("spin-wheel").style.display = "none";
@ -527,9 +554,39 @@
if (message.puzzle) { if (message.puzzle) {
drawPuzzle(message); drawPuzzle(message);
} }
if (message.turnState) {
changeSpinGuessState(message);
}
} }
if (message.type === "next_turn") {
document.getElementById("spin-wheel").style.display = "none";
document.getElementById("guess-letter").style.display = "none";
document.getElementById("guess-button").style.display = "none";
if (window.you == message.user) {
//send message since
socket.send(JSON.stringify({ type: "confirm_id"}));
}
}
if (message.type === "next_turn_confirmed") {
//this means its your turn
console.log('its your turn, id confirmed');
document.getElementById("spin-wheel").style.display = "inline";
document.getElementById("guess-letter").style.display = "none";
document.getElementById("guess-button").style.display = "none";
}
if (message.type === "next_turn_denied") {
//silently deny the user the next turn if trying to assume the same name as another user
console.log('its not your turn yet!');
document.getElementById("spin-wheel").style.display = "none";
document.getElementById("guess-letter").style.display = "none";
document.getElementById("guess-button").style.display = "none";
}
if (message.type === "puzzle_solved") {
console.log('puzzle has been solved!!!');
}
if (message.type === "new_leader") { if (message.type === "new_leader") {
drawPlayers(message); drawPlayers(message);
document.getElementById("status").innerText = "You are now the party leader!"; document.getElementById("status").innerText = "You are now the party leader!";

125
server.js
View File

@ -6,11 +6,12 @@ const crypto = require('crypto')
const wss = new WebSocket.Server({ port: 8080 }) const wss = new WebSocket.Server({ port: 8080 })
const rooms = {} // Stores rooms and their clients const rooms = {} // Stores rooms and their clients
const wheel = [ // const wheel = [
'lose a turn',800,350,450,700,300,600,5000, // 'lose a turn',800,350,450,700,300,600,5000,
300,600,300,500,800,550,400,300,900,500,'spin again', // 300,600,300,500,800,550,400,300,900,500,'spin again',
900,'Bankrupt',600,400,300 // 900,'Bankrupt',600,400,300
] //represents wheel in wheel of fortune game. // ] //represents wheel in wheel of fortune game.
const wheel = ['spin again','Bankrupt','lose a turn']
function removeProp(obj, prop) { function removeProp(obj, prop) {
obj = JSON.parse(JSON.stringify(obj)) obj = JSON.parse(JSON.stringify(obj))
if(!Array.isArray(prop)){ if(!Array.isArray(prop)){
@ -146,8 +147,12 @@ function checkGuess(letter,gameStateObject) {
console.log(currentPuzzle) console.log(currentPuzzle)
if (typeof currentPuzzle.answer == 'string') { if (typeof currentPuzzle.answer == 'string') {
//check if user already guessed one of teh given letters
if (currentPuzzle.puzzle.find((x)=> x.toUpperCase() == letter.toUpperCase())) {
console.log('user gave a guess on a given letter...')
return false
}
//first create an indexed hashMap //first create an indexed hashMap
let charArray = currentPuzzle.answer.split('') let charArray = currentPuzzle.answer.split('')
let matches = [] let matches = []
for(const c in charArray) { for(const c in charArray) {
@ -156,6 +161,7 @@ function checkGuess(letter,gameStateObject) {
matches.push({id:c,letter:char}) matches.push({id:c,letter:char})
} }
} }
//if there are any matches write them to the gameState Object //if there are any matches write them to the gameState Object
if (!matches.length) { if (!matches.length) {
return false return false
@ -164,6 +170,12 @@ function checkGuess(letter,gameStateObject) {
for(const m of matches) { for(const m of matches) {
gameStateObject.puzzles[gameStateObject.puzzleLevel].puzzle[m.id] = m.letter gameStateObject.puzzles[gameStateObject.puzzleLevel].puzzle[m.id] = m.letter
} }
//make sure to check if a win occurred
// convert the answer string into an array of characters
let checkAnswer = currentPuzzle.answer.split('')
if (currentPuzzle.puzzle.every((val,i)=> val.toUpperCase() === checkAnswer[i].toUpperCase())) {
return 'puzzleSolved'
}
console.log('matches found!!!', gameStateObject.puzzles[gameStateObject.puzzleLevel].puzzle) console.log('matches found!!!', gameStateObject.puzzles[gameStateObject.puzzleLevel].puzzle)
return [true, matches.length] return [true, matches.length]
} }
@ -174,7 +186,56 @@ function checkGuess(letter,gameStateObject) {
else console.error('invalid input to checkGuess() function',currentPuzzle.puzzle[0]) else console.error('invalid input to checkGuess() function',currentPuzzle.puzzle[0])
} }
//these functions must have both gameStateobject and websockets initialized before use!!!
function rewardUser(gameStateObject,ws) {
const roomCode = ws.roomCode
const room = rooms[ws.roomCode]
//find the current player
let currentUserTurn = gameStateObject.players[gameStateObject.turn]
currentUserTurn.win++
gameStateObject.puzzleLevel++
room.clients.forEach((client) => {
client.send(JSON.stringify({
type: 'puzzle_solved', roomCode,
user: currentUserTurn.name
}))
})
}
function changeTurn(gameStateObject,ws) {
const room = rooms[ws.roomCode]
if (gameStateObject.turn == gameStateObject.players.length - 1) {
gameStateObject.turn = 0
}
else gameStateObject.turn++
//alert next user of their turn
room.clients.forEach((client) => {
client.send(JSON.stringify(
{ type: 'next_turn',
user:room.gameState.players[room.gameState.turn].name,
}))
})
}
function loadNewPuzzle(gameStateObject,ws) {
const room = rooms[ws.roomCode]
const newPuzzle = loadCurrentPuzzle(gameStateObject)
room.gameState.turnState = 'spin'
room.gameState.puzzles[room.gameState.puzzleLevel] = newPuzzle
room.gameState.levelsRemaining = (room.gameState.puzzles.length - 1 - room.gameState.puzzleLevel)
room.clients.forEach((client) => {
client.send(JSON.stringify({
type: 'new_puzzle',
roomCode: ws.roomCode,
// eslint-disable-next-line no-undef
puzzle: removeProp(newPuzzle,'answer'),
turn:room.gameState.turn,
turnState:room.gameState.turnState
}))
})
}
// function checkIfClientExistsInRoom(ws,room) { // function checkIfClientExistsInRoom(ws,room) {
// console.log(room,ws) // console.log(room,ws)
// //assumes ws message is sent and room code exists // //assumes ws message is sent and room code exists
@ -234,6 +295,14 @@ wss.on('connection', (ws) => {
}) })
} }
if (data.type === 'confirm_id') {
const room = rooms[ws.roomCode]
const currentUserTurn = room.gameState.players[room.gameState.turn]
room.gameState.turnState = 'spin'
if (ws.name == currentUserTurn.name && ws.identifierToken == currentUserTurn.id) {
ws.send(JSON.stringify({ type:'next_turn_confirmed'}))
} else ws.send(JSON.stringify({ type:'next_turn_denied'}))
}
if (data.type === 'create_room') { if (data.type === 'create_room') {
const roomCode = uuidv4().slice(0, 5) const roomCode = uuidv4().slice(0, 5)
ws.name = getRandomName() ws.name = getRandomName()
@ -298,8 +367,11 @@ wss.on('connection', (ws) => {
} }
if (data.type === 'start_game') { if (data.type === 'start_game') {
const room = rooms[ws.roomCode] const room = rooms[ws.roomCode]
if (room.gameState.started) {
ws.send(JSON.stringify({ type: 'error', message: 'game has already been started' }))
}
const currentPuzzle = loadCurrentPuzzle(room.gameState) const currentPuzzle = loadCurrentPuzzle(room.gameState)
// const clientPuzzle = Object.entries(currentPuzzle).filter(([key])=> key != 'answer') // const clientPuzzle = Object.entries(currentPuzzle).filter(([key])=> key != 'answer')
@ -312,7 +384,8 @@ wss.on('connection', (ws) => {
room.gameState.players.push({ room.gameState.players.push({
id:client.identifierToken, id:client.identifierToken,
name:client.name, name:client.name,
points:0 points:0,
wins:0
}) })
}) })
console.log(room.gameState) console.log(room.gameState)
@ -350,16 +423,22 @@ wss.on('connection', (ws) => {
// Simulate a wheel spin result and update room state // Simulate a wheel spin result and update room state
let spinResult = getRandomValue(wheel) let spinResult = getRandomValue(wheel)
if (spinResult == 'Bankrupt') { if (spinResult == 'Bankrupt') {
spinResult = 0
}
if (spinResult == 'spin again') {
spinResult = 0
room.gameState.players = room.gameState.players.map((player) => { room.gameState.players = room.gameState.players.map((player) => {
return player.id == ws.identifierToken ? {...player, points:player.points + spinResult, condition:'spin again'} : player return player.id == ws.identifierToken ? {...player, points:0} : player
}) })
} }
if (spinResult == 'spin again') {
room.gameState.players = room.gameState.players.map((player) => {
return player.id == ws.identifierToken ? {...player, points:player.points + 0, condition:'spin again'} : player
})
}
if (spinResult == 'lose a turn') {
console.log('lose a turn here ig...?')
changeTurn(room.gameState,ws)
}
room.gameState.players = room.gameState.players.map((player) => { room.gameState.players = room.gameState.players.map((player) => {
return player.id == ws.identifierToken ? {...player, points:player.points + spinResult} : player return player.id == ws.identifierToken ? {...player, points:player.points + 0} : player
}) })
console.log('players', room.gameState.players) console.log('players', room.gameState.players)
room.gameState.spinResult = spinResult room.gameState.spinResult = spinResult
@ -380,29 +459,35 @@ wss.on('connection', (ws) => {
ws.send(JSON.stringify({ type: 'error', message: 'its not your turn to guess!' })) ws.send(JSON.stringify({ type: 'error', message: 'its not your turn to guess!' }))
return return
} }
room.gameState.turnState = 'spin' room.gameState.turnState = 'guess'
const { letter } = data const { letter } = data
// Handle guess logic (e.g., check if the letter is in the puzzle) // Handle guess logic (e.g., check if the letter is in the puzzle)
const guessResult = checkGuess(letter,room.gameState) const guessResult = checkGuess(letter,room.gameState)
if (!guessResult) { if (!guessResult) {
room.gameState.turnState = 'spin'
//if the player guesses incorrectly, and theres more than one player, //if the player guesses incorrectly, and theres more than one player,
//its the next players turn //its the next players turn
room.clients.forEach((client) => { room.clients.forEach((client) => {
client.send(JSON.stringify( client.send(JSON.stringify(
{ type: 'guess_result', letter, { type: 'guess_result', letter,
correct: guessResult, correct: guessResult,
player: ws === room.leader ? 'Leader' : 'Player' })) player: ws === room.leader ? 'Leader' : 'Player',
turnState:room.gameState.turnState
}))
}) })
if (room.gameState.turn == room.gameState.players.length - 1) { changeTurn(room.gameState,ws)
room.gameState.turn = 0
} }
else room.gameState.turn++ else if(guessResult === 'puzzleSolved') {
rewardUser(room.gameState,ws)
loadNewPuzzle(room.gameState,ws)
} }
else { else {
//the player guessed correctly and its still their turn //the player guessed correctly and its still their turn
room.gameState.turn = 'spin'
room.clients.forEach((client) => room.clients.forEach((client) =>
client.send(JSON.stringify( client.send(JSON.stringify(
{ type: 'guess_result', letter, { type: 'guess_result', letter,

View File

@ -2,4 +2,10 @@ things to test.txt
test joining room on already started game test joining room on already started game
don't use async testing in mocha if possible. don't use async testing in mocha if possible.
//check spin again and unify the UI to check turnState,
//make sure the messages being recieved are canonized.
//figure out how to check for string data vs number data when doing the spin wheel
//only pass an integer to the startSpin function, so less code needs to be changed.