From 01ca3f4d9393a5d46e2852669e7d80f45f2b1b2b Mon Sep 17 00:00:00 2001 From: Meleeman01 Date: Sun, 5 Jan 2025 04:32:57 -0600 Subject: [PATCH] puzzle visualized, added puzzle validator on server, and uploading before storm wrecks my shit --- README.md | 26 +++++++++- index.html | 129 +++++++++++++++++++++++++++++++++++++++++++++++--- puzzles.json | 5 ++ puzzles2.json | 9 ++++ server.js | 98 +++++++++++++++++++++++++++++--------- 5 files changed, 237 insertions(+), 30 deletions(-) create mode 100644 puzzles2.json diff --git a/README.md b/README.md index ab68d3a..5561b5e 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,27 @@ # WheelOfFortune -a webgame to play wheel of fortune with friends \ No newline at end of file +## a webgame to play wheel of fortune with friends + +when creating puzzles make sure there are no words greater than 12 characters. +make sure you specify 4 slots on the answer property in array format like so: + +```json +{ + "given": ["a", "b", "r"], + "answer": ["", "Andy and", "the Backs", ""], + "category": "alternative names" +} +``` +not doing this will give you an error. + +you can see the format in puzzles.json + +if you have a one line puzzle you can shorten it: + +```json +{ + "given": ["a", "b", "r"], + "answer": "Amerimutt", + "category": "alternative names" +} +``` \ No newline at end of file diff --git a/index.html b/index.html index 61f9fce..7293687 100644 --- a/index.html +++ b/index.html @@ -12,7 +12,50 @@ .div-shadow { box-shadow: rgba(0, 0, 0, 0.15) 1.95px 1.95px 2.6px; } - + .puzzleboard { + display: grid; + grid-template-columns: repeat(12, 1fr); /* 12 columns, equal width */ + grid-template-rows: repeat(4, auto); /* 4 rows, height adjusts to content */ + gap: 1px; /* Optional: spacing between grid items */ + height: 205px; + width: 500px; + max-width: 100%; /* Optional: ensures grid fits within the container */ + max-height: 100%; /* Optional: ensures the grid respects height limits */ + } + .grid-item { + background-image: radial-gradient(circle,#21D375 ,green); /* For visualization */ + border: 1px solid black; /* Optional: visual boundary for items */ + text-align: center; + padding: 1px; + border-radius: 5px; + } + .grid-item-2 { + background-color: white; /* For visualization */ + border: 1px solid black; /* Optional: visual boundary for items */ + text-align: center; + padding: 1px; + display: flex; + justify-content: center; + align-items: center; + font-size:1.2rem; + font-family:'sans'; + font-weight:bold; + border-radius: 5px; + } + .category { + background-image: radial-gradient(circle,#1f57dd ,#0000ae); + color: white; + max-width: 500px; + font-size:1.2rem; + font-family:'sans'; + font-weight:bold; + border-radius: 5px; + text-align: center; + } + .hidden { + display: none; + visibility: hidden; + } /* Dialog styling */ dialog { border: none; @@ -54,7 +97,7 @@ - +
@@ -62,6 +105,11 @@ + + +
+
+
arrow-down-bold @@ -288,6 +336,66 @@ players.innerHTML = playersHtml; } + function drawPuzzle(message, gridRows = 4, gridCols = 12) { + //legend null = space, "" = white space to guess, "a" is a letter already solved for you. + console.log(message); + //wheel of fortune puzzles must fit within a 12x4 grid of letter spaces + //first we draw the spaces + let puzzle = message.puzzle.puzzle; + let puzzleBoard = document.querySelector('.puzzleboard'); + let resultingPuzzleBoard = []; + //if the first entry of the puzzle is an array and not a string display the puzzle differently + if (Array.isArray(message.puzzle.puzzle[0])) { + console.log('first entry is an array in this puzzle...'); + } + else if (typeof message.puzzle.puzzle[0] == 'string') { + console.log('first entry is a string in this puzzle...'); + //if we have a single string we need to return it on the second line from the bottom + + resultingPuzzleBoard.push(Array(12).fill(null)); + resultingPuzzleBoard.push(Array(12).fill(null)); + + const nextLine = Array(12).fill(null); + const startIndex = Math.floor((12 - message.puzzle.puzzle.length) / 2); + console.log(startIndex); + for (let i = 0; i < message.puzzle.puzzle.length; i++) { + nextLine[startIndex + i] = message.puzzle.puzzle[i]; + } + console.log(nextLine); + resultingPuzzleBoard.push(nextLine); + resultingPuzzleBoard.push(Array(12).fill(null)); + console.log(resultingPuzzleBoard); + //after we've drawn our data for our board,now its time to visualize it to the user + for(let i of resultingPuzzleBoard) { + for (let j in i) { + const letter = i[j]; + if (letter == null || letter == ' ') { + let el = document.createElement('div'); + el.classList.add('grid-item'); + el.innerHTML = ' '; + // el.style.height = '50px'; + // el.style.width = '50px'; + // el.style.border = 'solid' + puzzleBoard.appendChild(el); + } + else if (letter != null && letter != ' ') { + let el = document.createElement('div'); + el.classList.add('grid-item-2'); + el.innerText = letter; + puzzleBoard.appendChild(el); + } + } + } + } + else { + console.error('error: ','message does not have correct datatype of string or array'); + } + //finally draw the category! + document.querySelector('.category').classList.add('pt-2','pb-2'); + document.querySelector('.category').innerHTML = `${message.puzzle.category}` + + } + function changeName() { console.log('change name hit.'); const nameDialog = document.querySelector('.nameDialog'); @@ -306,13 +414,19 @@ } const socket = new WebSocket("ws://localhost:8080"); - document.getElementById("create-room").onclick = () => { + document.getElementById("create-room").onclick = function () { socket.send(JSON.stringify({ type: "create_room" })); + this.style.display = 'none'; + document.getElementById("join-room").style.display = 'none'; + document.getElementById('join-code').style.display = 'none'; }; document.getElementById("join-room").onclick = () => { const roomCode = document.getElementById("join-code").value; socket.send(JSON.stringify({ type: "join_room", roomCode })); + this.style.display = 'none'; + document.getElementById("create-room").style.display = 'none'; + document.getElementById('join-code').style.display = 'none'; }; document.getElementById("start-game").onclick = () => { @@ -336,7 +450,8 @@ if (message.type === "room_created") { window.you = message.you; - document.getElementById("status").innerText = `Room created! Code: ${message.roomCode}`; + document.querySelector(".room-code").innerText =`Room Code: ${message.roomCode}`; + document.getElementById("status").innerText = `Room created!`; drawPlayers(message); if (message.isLeader) { document.getElementById("start-game").style.display = "inline"; @@ -359,7 +474,8 @@ const status = message.isLeader ? "You are the party leader!" : "You joined the room!"; // document.querySelector('.players').innerHtml += `${}` - document.getElementById("status").innerText = `Room Code: ${message.roomCode} - ${status}`; + document.getElementById("status").innerText = `${status}`; + document.querySelector(".room-code").innerText =`Room Code: ${message.roomCode}`; if (message.isLeader) { document.getElementById("start-game").style.display = "inline"; document.getElementById("spin-wheel").style.display = "inline"; @@ -369,7 +485,8 @@ } if (message.type === "game_started") { - console.log(message); + let result = drawPuzzle(message); + console.log(result); document.getElementById("status").innerText = "The game has started!"; document.getElementById("start-game").style.display = "none"; document.getElementById("start-game").style.display = "inline"; diff --git a/puzzles.json b/puzzles.json index 7753588..9e96ab8 100644 --- a/puzzles.json +++ b/puzzles.json @@ -18,6 +18,11 @@ "given": ["a","b","r"], "answer": "Wet Back", "category":"alternative names" + }, + { + "given": ["a","b","r"], + "answer": ["","Wetting", "the Backs","Wet Backs"], + "category":"alternative names" } ] diff --git a/puzzles2.json b/puzzles2.json new file mode 100644 index 0000000..133b997 --- /dev/null +++ b/puzzles2.json @@ -0,0 +1,9 @@ +[ + { + "given": ["a","b","r"], + "answer": ["","Wetting", "the Backs","Wet Backs"], + "category":"alternative names" + } +] + + diff --git a/server.js b/server.js index 336ecca..7858903 100644 --- a/server.js +++ b/server.js @@ -11,6 +11,31 @@ const wheel = [ 300,600,300,500,800,550,400,300,900,500,'spin again', 900,'Bankrupt',600,400,300 ] //represents wheel in wheel of fortune game. + +//make sure this is run so puzzles are easier to contruct +function checkPuzzleData(puzzles) { + for(let puzzle in puzzles) { + let i = puzzle; + puzzle = puzzles[puzzle]; + if (Array.isArray(puzzle.answer)) { + if (puzzle.answer.length != 4) { + throw new Error(` + puzzle at index ${i} doesn't have the correct amount of slots defined. The proper amount of slots is 4, and you have ${puzzle.answer.length}. use "" to denote an empty line. + `); + } + for (let p of puzzle.answer){ + if (p.length > 12) { + throw new Error(`${p} (${p.length} characters long) is longer than 12 characters. only twelve characters allowed per line`); + } + } + } + else if (typeof puzzle.answer == 'string') { + if (puzzle.answer.length > 12) { + throw new Error(`${puzzle.answer} (${puzzle.answer.length} characters long) is longer than 12 characters. only twelve characters allowed per line`); + } + } + } +} function getRandomValue(array) { const randomIndex = crypto.randomInt(0, array.length); return array[randomIndex]; @@ -38,39 +63,66 @@ function getRandomName() { return NameIndex === 0 ? DefaultNames[NameIndex] : DefaultNames[NameIndex-1]; } + + function loadCurrentPuzzle(gameStateObject) { console.log(gameStateObject); + let letterArray; + //make sure we only show whats given in the letterArray, and empty values for everything else + function processPuzzle(letterArray,given) { + let puzzleArray = []; + for (let letter of letterArray) { + if (letter == ' ') { + puzzleArray.push(' '); + continue; + } + letterFound = false; + for (let g of given ) { + if(g.toUpperCase() == letter.toUpperCase()) { + puzzleArray.push(g); + letterFound = true; + } + } + if (!letterFound) {puzzleArray.push('');} + } + console.log('in loadCurrentPuzzle: ',puzzleArray); + return puzzleArray; + } + //calculate the puzzle for now we'll just go through however many iterations there are //for each slot - let letterArray = gameStateObject.puzzles[gameStateObject.puzzleLevel].answer.split(''); - const given =gameStateObject.puzzles[gameStateObject.puzzleLevel].given; - console.log('letterArray',letterArray); - let puzzleArray = []; - for (let letter of letterArray) { - if (letter == ' ') { - puzzleArray.push(' '); + if (Array.isArray(gameStateObject.puzzles[gameStateObject.puzzleLevel].answer)) { + let formattedPuzzle = []; + for (let i of gameStateObject.puzzles[gameStateObject.puzzleLevel].answer) { + letterArray = i.split(''); + const given = gameStateObject.puzzles[gameStateObject.puzzleLevel].given; + formattedPuzzle.push(processPuzzle(letterArray,given)); } - letterFound = false; - for (let g of given ) { - if(g.toUpperCase() == letter.toUpperCase()) { - puzzleArray.push(g); - letterFound = true; - } + return { + 'puzzleLevel':gameStateObject.puzzleLevel, + 'given':gameStateObject.puzzles[gameStateObject.puzzleLevel].given, + 'category':gameStateObject.puzzles[gameStateObject.puzzleLevel].category, + 'puzzle':formattedPuzzle, + 'levelsRemaining':(gameStateObject.puzzles.length - 1 - gameStateObject.puzzleLevel) } - if (!letterFound) {puzzleArray.push('');} - } - console.log(puzzleArray); - gameStateObject.puzzles[gameStateObject.puzzleLevel].puzzle = puzzleArray; - return { - 'puzzleLevel':gameStateObject.puzzleLevel, - 'given':gameStateObject.puzzles[gameStateObject.puzzleLevel].given, - 'category':gameStateObject.puzzles[gameStateObject.puzzleLevel].category, - 'puzzle':puzzleArray, - 'levelsRemaining':(gameStateObject.puzzles.length - 1 - gameStateObject.puzzleLevel) + else { + letterArray = gameStateObject.puzzles[gameStateObject.puzzleLevel].answer.split(''); + const given = gameStateObject.puzzles[gameStateObject.puzzleLevel].given; + gameStateObject.puzzles[gameStateObject.puzzleLevel].puzzle = processPuzzle(letterArray, given); + //console.log(gameStateObject.puzzles[gameStateObject.puzzleLevel].puzzle); + + return { + 'puzzleLevel':gameStateObject.puzzleLevel, + 'given':gameStateObject.puzzles[gameStateObject.puzzleLevel].given, + 'category':gameStateObject.puzzles[gameStateObject.puzzleLevel].category, + 'puzzle':gameStateObject.puzzles[gameStateObject.puzzleLevel].puzzle, + 'levelsRemaining':(gameStateObject.puzzles.length - 1 - gameStateObject.puzzleLevel) + } } } +checkPuzzleData(puzzles); // server.js wss.on("connection", (ws) => {