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
function startSpin(targetIndex) {
console.log('targetIndex: ',targetIndex);
let resultingSpeed = wheelSpinSpeedData[targetIndex];
let resultingSpeed = wheelSpinSpeedData[targetIndex[0]];
console.log('resultingSpeed: ', resultingSpeed);
if (spinning) return;
rotation = 0 - (.283*6)
@ -276,12 +276,13 @@
console.log(anglePerSegment);
let currentRotation = rotation; // Start from the current rotation
spinSpeed = wheelSpinSpeedData[targetIndex]; // Initial speed
spinSpeed = wheelSpinSpeedData[targetIndex[0]]; // Initial speed
function animate() {
if ( spinSpeed < 0.001) {
spinning = false;
console.log(`Landed on: ${wheel[targetIndex]}`);
spinSpeed = 0;
console.log(`Landed on: ${wheel[targetIndex[0]]}`);
return;
}
// console.log('currentRotation: ',currentRotation);
@ -413,6 +414,20 @@
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");
document.getElementById("create-room").onclick = function () {
@ -495,6 +510,16 @@
document.getElementById("guess-letter").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") {
console.log('spin result recieved');
@ -510,9 +535,11 @@
console.log(filterResultsArr[0][0]);
//if there is multiple entries where the spin exists pick a random index.
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{
console.log('else',filterResultsArr[0])
startSpin(filterResultsArr[0]);
}
document.getElementById("spin-wheel").style.display = "none";
@ -527,9 +554,39 @@
if (message.puzzle) {
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") {
drawPlayers(message);
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 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.
// 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.
const wheel = ['spin again','Bankrupt','lose a turn']
function removeProp(obj, prop) {
obj = JSON.parse(JSON.stringify(obj))
if(!Array.isArray(prop)){
@ -146,8 +147,12 @@ function checkGuess(letter,gameStateObject) {
console.log(currentPuzzle)
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
let charArray = currentPuzzle.answer.split('')
let matches = []
for(const c in charArray) {
@ -156,6 +161,7 @@ function checkGuess(letter,gameStateObject) {
matches.push({id:c,letter:char})
}
}
//if there are any matches write them to the gameState Object
if (!matches.length) {
return false
@ -164,6 +170,12 @@ function checkGuess(letter,gameStateObject) {
for(const m of matches) {
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)
return [true, matches.length]
}
@ -174,7 +186,56 @@ function checkGuess(letter,gameStateObject) {
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) {
// console.log(room,ws)
// //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') {
const roomCode = uuidv4().slice(0, 5)
ws.name = getRandomName()
@ -298,8 +367,11 @@ wss.on('connection', (ws) => {
}
if (data.type === 'start_game') {
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 clientPuzzle = Object.entries(currentPuzzle).filter(([key])=> key != 'answer')
@ -312,7 +384,8 @@ wss.on('connection', (ws) => {
room.gameState.players.push({
id:client.identifierToken,
name:client.name,
points:0
points:0,
wins:0
})
})
console.log(room.gameState)
@ -350,16 +423,22 @@ wss.on('connection', (ws) => {
// Simulate a wheel spin result and update room state
let spinResult = getRandomValue(wheel)
if (spinResult == 'Bankrupt') {
spinResult = 0
}
if (spinResult == 'spin again') {
spinResult = 0
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) => {
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)
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!' }))
return
}
room.gameState.turnState = 'spin'
room.gameState.turnState = 'guess'
const { letter } = data
// Handle guess logic (e.g., check if the letter is in the puzzle)
const guessResult = checkGuess(letter,room.gameState)
if (!guessResult) {
room.gameState.turnState = 'spin'
//if the player guesses incorrectly, and theres more than one player,
//its the next players turn
room.clients.forEach((client) => {
client.send(JSON.stringify(
{ type: 'guess_result', letter,
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) {
room.gameState.turn = 0
}
else room.gameState.turn++
changeTurn(room.gameState,ws)
}
else if(guessResult === 'puzzleSolved') {
rewardUser(room.gameState,ws)
loadNewPuzzle(room.gameState,ws)
}
else {
//the player guessed correctly and its still their turn
room.gameState.turn = 'spin'
room.clients.forEach((client) =>
client.send(JSON.stringify(
{ type: 'guess_result', letter,

View File

@ -2,4 +2,10 @@ things to test.txt
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.