working on gameflow added turnState logic, basic puzzle solving logic
This commit is contained in:
parent
5a3095aa73
commit
7c3eb6ed57
65
index.html
65
index.html
@ -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
125
server.js
@ -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,
|
||||||
|
@ -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.
|
Loading…
Reference in New Issue
Block a user