diff --git a/client/package-lock.json b/client/package-lock.json index aced44e..c21ee54 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -6408,6 +6408,11 @@ "to-regex-range": "^5.0.1" } }, + "filter-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz", + "integrity": "sha1-mzERErxsYSehbgFsbF1/GeCAXFs=" + }, "finalhandler": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", @@ -10314,6 +10319,22 @@ "prepend-http": "^1.0.0", "query-string": "^4.1.0", "sort-keys": "^1.0.0" + }, + "dependencies": { + "query-string": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", + "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", + "requires": { + "object-assign": "^4.1.0", + "strict-uri-encode": "^1.0.0" + } + }, + "strict-uri-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" + } } }, "npm-run-path": { @@ -12134,12 +12155,14 @@ "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" }, "query-string": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", - "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.14.0.tgz", + "integrity": "sha512-In3o+lUxlgejoVJgwEdYtdxrmlL0cQWJXj0+kkI7RWVo7hg5AhFtybeKlC9Dpgbr8eOC4ydpEh8017WwyfzqVQ==", "requires": { - "object-assign": "^4.1.0", - "strict-uri-encode": "^1.0.0" + "decode-uri-component": "^0.2.0", + "filter-obj": "^1.1.0", + "split-on-first": "^1.0.0", + "strict-uri-encode": "^2.0.0" } }, "querystring": { @@ -13853,6 +13876,11 @@ "wbuf": "^1.7.3" } }, + "split-on-first": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz", + "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==" + }, "split-string": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", @@ -14028,9 +14056,9 @@ "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" }, "strict-uri-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", + "integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY=" }, "string-length": { "version": "4.0.1", diff --git a/client/package.json b/client/package.json index 9014a7d..4b7644d 100644 --- a/client/package.json +++ b/client/package.json @@ -6,6 +6,7 @@ "@testing-library/jest-dom": "^5.11.9", "@testing-library/react": "^11.2.5", "@testing-library/user-event": "^12.7.0", + "query-string": "^6.14.0", "react": "^17.0.1", "react-dom": "^17.0.1", "react-router-dom": "^5.2.0", diff --git a/client/src/components/Game.js b/client/src/components/Game.js index 75fa80c..35cc0e1 100644 --- a/client/src/components/Game.js +++ b/client/src/components/Game.js @@ -2,6 +2,7 @@ import React, { useEffect, useState } from 'react' import PACK_OF_CARDS from '../utils/packOfCards' import shuffleArray from '../utils/shuffleArray' import io from 'socket.io-client' +import queryString from 'query-string' //NUMBER CODES FOR ACTION CARDS //SKIP - 404 @@ -12,8 +13,14 @@ import io from 'socket.io-client' let socket const ENDPOINT = 'http://localhost:5000' -const Game = () => { +const Game = (props) => { + const data = queryString.parse(props.location.search) + //initialize socket state + const [room, setRoom] = useState(data.roomCode) + const [roomFull, setRoomFull] = useState(false) + const [users, setUsers] = useState([]) + const [currentUser, setCurrentUser] = useState('') useEffect(() => { const connectionOptions = { @@ -24,6 +31,18 @@ const Game = () => { } socket = io.connect(ENDPOINT, connectionOptions) console.log(socket); + + socket.emit('join', {room: room}, (error) => { + if(error) + setRoomFull(true) + }) + + //cleanup on component unmount + return function cleanup() { + socket.emit('disconnect') + //shut down connnection instance + socket.off() + } }, []) //initialize game state @@ -69,16 +88,7 @@ const Game = () => { //store all remaining cards into drawCardPile const drawCardPile = shuffledCards - //set initial state - // setGameOver(false) - // setTurn('Player 1') - // setPlayer1Deck([...player1Deck]) - // setPlayer2Deck([...player2Deck]) - // setCurrentColor(playedCardsPile[0].charAt(1)) - // setCurrentNumber(playedCardsPile[0].charAt(0)) - // setPlayedCardsPile([...playedCardsPile]) - // setDrawCardPile([...drawCardPile]) - //send this state to server + //send initial state to server socket.emit('initGameState', { gameOver: false, turn: 'Player 1', @@ -115,6 +125,13 @@ const Game = () => { drawCardPile && setDrawCardPile(drawCardPile) }) + socket.on("roomData", ({ users }) => { + setUsers(users) + }) + + socket.on('currentUserData', ({ name }) => { + setCurrentUser(name) + }) }, []) //some util functions @@ -143,15 +160,7 @@ const Game = () => { //remove the played card from player1's deck and add it to playedCardsPile (immutably) //then update turn, currentColor and currentNumber const removeIndex = player1Deck.indexOf(played_card) - //set new state - // setGameOver(checkGameOver(player1Deck)) - // setWinner(checkWinner(player1Deck, 'Player 1')) - // setTurn('Player 2') - // setPlayedCardsPile([...playedCardsPile.slice(0, playedCardsPile.length), played_card, ...playedCardsPile.slice(playedCardsPile.length)]) - // setPlayer1Deck([...player1Deck.slice(0, removeIndex), ...player1Deck.slice(removeIndex + 1)]) - // setCurrentColor(colorOfPlayedCard) - // setCurrentNumber(numberOfPlayedCard) - //send this state to server + //send new state to server socket.emit('updateGameState', { gameOver: checkGameOver(player1Deck), winner: checkWinner(player1Deck, 'Player 1'), @@ -166,15 +175,7 @@ const Game = () => { //remove the played card from player2's deck and add it to playedCardsPile (immutably) //then update turn, currentColor and currentNumber const removeIndex = player2Deck.indexOf(played_card) - //set new state - // setGameOver(checkGameOver(player2Deck)) - // setWinner(checkWinner(player2Deck, 'Player 2')) - // setTurn('Player 1') - // setPlayedCardsPile([...playedCardsPile.slice(0, playedCardsPile.length), played_card, ...playedCardsPile.slice(playedCardsPile.length)]) - // setPlayer2Deck([...player2Deck.slice(0, removeIndex), ...player2Deck.slice(removeIndex + 1)]) - // setCurrentColor(colorOfPlayedCard) - // setCurrentNumber(numberOfPlayedCard) - //send this state to server + //send new state to server socket.emit('updateGameState', { gameOver: checkGameOver(player2Deck), winner: checkWinner(player2Deck, 'Player 2'), @@ -194,15 +195,7 @@ const Game = () => { //remove the played card from player1's deck and add it to playedCardsPile (immutably) //then update turn, currentColor and currentNumber const removeIndex = player1Deck.indexOf(played_card) - //set new state - // setGameOver(checkGameOver(player1Deck)) - // setWinner(checkWinner(player1Deck, 'Player 1')) - // setTurn('Player 2') - // setPlayedCardsPile([...playedCardsPile.slice(0, playedCardsPile.length), played_card, ...playedCardsPile.slice(playedCardsPile.length)]) - // setPlayer1Deck([...player1Deck.slice(0, removeIndex), ...player1Deck.slice(removeIndex + 1)]) - // setCurrentColor(colorOfPlayedCard) - // setCurrentNumber(numberOfPlayedCard) - //send this state to server + //send new state to server socket.emit('updateGameState', { gameOver: checkGameOver(player1Deck), winner: checkWinner(player1Deck, 'Player 1'), @@ -217,15 +210,7 @@ const Game = () => { //remove the played card from player2's deck and add it to playedCardsPile (immutably) //then update turn, currentColor and currentNumber const removeIndex = player2Deck.indexOf(played_card) - //set new state - setGameOver(checkGameOver(player2Deck)) - setWinner(checkWinner(player2Deck, 'Player 2')) - setTurn('Player 1') - setPlayedCardsPile([...playedCardsPile.slice(0, playedCardsPile.length), played_card, ...playedCardsPile.slice(playedCardsPile.length)]) - setPlayer2Deck([...player2Deck.slice(0, removeIndex), ...player2Deck.slice(removeIndex + 1)]) - setCurrentColor(colorOfPlayedCard) - setCurrentNumber(numberOfPlayedCard) - //send this state to server + //send new state to server socket.emit('updateGameState', { gameOver: checkGameOver(player2Deck), winner: checkWinner(player2Deck, 'Player 2'), @@ -237,7 +222,6 @@ const Game = () => { }) } } - //if no color or number match, invalid move - do not update state else { alert('Invalid Move!') @@ -256,14 +240,7 @@ const Game = () => { //remove the played card from player1's deck and add it to playedCardsPile (immutably) //then update currentColor and currentNumber const removeIndex = player1Deck.indexOf(played_card) - //set new state - // setGameOver(checkGameOver(player1Deck)) - // setWinner(checkWinner(player1Deck, 'Player 1')) - // setPlayedCardsPile([...playedCardsPile.slice(0, playedCardsPile.length), played_card, ...playedCardsPile.slice(playedCardsPile.length)]) - // setPlayer1Deck([...player1Deck.slice(0, removeIndex), ...player1Deck.slice(removeIndex + 1)]) - // setCurrentColor(colorOfPlayedCard) - // setCurrentNumber(404) - //send this state to server + //send new state to server socket.emit('updateGameState', { gameOver: checkGameOver(player1Deck), winner: checkWinner(player1Deck, 'Player 1'), @@ -277,14 +254,7 @@ const Game = () => { //remove the played card from player2's deck and add it to playedCardsPile (immutably) //then update currentColor and currentNumber const removeIndex = player2Deck.indexOf(played_card) - //set new state - // setGameOver(checkGameOver(player2Deck)) - // setWinner(checkWinner(player2Deck, 'Player 2')) - // setPlayedCardsPile([...playedCardsPile.slice(0, playedCardsPile.length), played_card, ...playedCardsPile.slice(playedCardsPile.length)]) - // setPlayer2Deck([...player2Deck.slice(0, removeIndex), ...player2Deck.slice(removeIndex + 1)]) - // setCurrentColor(colorOfPlayedCard) - // setCurrentNumber(404) - //send this state to server + //send new state to server socket.emit('updateGameState', { gameOver: checkGameOver(player2Deck), winner: checkWinner(player2Deck, 'Player 2'), @@ -303,14 +273,7 @@ const Game = () => { //remove the played card from player1's deck and add it to playedCardsPile (immutably) //then update currentColor and currentNumber - turn will remain same const removeIndex = player1Deck.indexOf(played_card) - //set new state - // setGameOver(checkGameOver(player1Deck)) - // setWinner(checkWinner(player1Deck, 'Player 1')) - // setPlayedCardsPile([...playedCardsPile.slice(0, playedCardsPile.length), played_card, ...playedCardsPile.slice(playedCardsPile.length)]) - // setPlayer1Deck([...player1Deck.slice(0, removeIndex), ...player1Deck.slice(removeIndex + 1)]) - // setCurrentColor(colorOfPlayedCard) - // setCurrentNumber(404) - //send this state to server + //send new state to server socket.emit('updateGameState', { gameOver: checkGameOver(player1Deck), winner: checkWinner(player1Deck, 'Player 1'), @@ -324,14 +287,7 @@ const Game = () => { //remove the played card from player2's deck and add it to playedCardsPile (immutably) //then update currentColor and currentNumber - turn will remain same const removeIndex = player2Deck.indexOf(played_card) - //set new state - // setGameOver(checkGameOver(player2Deck)) - // setWinner(checkWinner(player2Deck, 'Player 2')) - // setPlayedCardsPile([...playedCardsPile.slice(0, playedCardsPile.length), played_card, ...playedCardsPile.slice(playedCardsPile.length)]) - // setPlayer2Deck([...player2Deck.slice(0, removeIndex), ...player2Deck.slice(removeIndex + 1)]) - // setCurrentColor(colorOfPlayedCard) - // setCurrentNumber(404) - //send this state to server + //send new state to server socket.emit('updateGameState', { gameOver: checkGameOver(player2Deck), winner: checkWinner(player2Deck, 'Player 2'), @@ -366,16 +322,7 @@ const Game = () => { //pull out last two elements from it const drawCard1 = copiedDrawCardPileArray.pop() const drawCard2 = copiedDrawCardPileArray.pop() - //set new state - setGameOver(checkGameOver(player1Deck)) - setWinner(checkWinner(player1Deck, 'Player 1')) - setPlayedCardsPile([...playedCardsPile.slice(0, playedCardsPile.length), played_card, ...playedCardsPile.slice(playedCardsPile.length)]) - setPlayer1Deck([...player1Deck.slice(0, removeIndex), ...player1Deck.slice(removeIndex + 1)]) - setPlayer2Deck([...player2Deck.slice(0, player2Deck.length), drawCard1, drawCard2, ...player2Deck.slice(player2Deck.length)]) - setCurrentColor(colorOfPlayedCard) - setCurrentNumber(252) - setDrawCardPile([...copiedDrawCardPileArray]) - //send this state to server + //send new state to server socket.emit('updateGameState', { gameOver: checkGameOver(player1Deck), winner: checkWinner(player1Deck, 'Player 1'), @@ -397,16 +344,6 @@ const Game = () => { //pull out last two elements from it const drawCard1 = copiedDrawCardPileArray.pop() const drawCard2 = copiedDrawCardPileArray.pop() - //set new state - // setGameOver(checkGameOver(player2Deck)) - // setWinner(checkWinner(player2Deck, 'Player 2')) - // setPlayedCardsPile([...playedCardsPile.slice(0, playedCardsPile.length), played_card, ...playedCardsPile.slice(playedCardsPile.length)]) - // setPlayer2Deck([...player2Deck.slice(0, removeIndex), ...player2Deck.slice(removeIndex + 1)]) - // setPlayer1Deck([...player1Deck.slice(0, player1Deck.length), drawCard1, drawCard2, ...player1Deck.slice(player1Deck.length)]) - // setCurrentColor(colorOfPlayedCard) - // setCurrentNumber(252) - // setDrawCardPile([...copiedDrawCardPileArray]) - //send this state to server socket.emit('updateGameState', { gameOver: checkGameOver(player2Deck), winner: checkWinner(player2Deck, 'Player 2'), @@ -433,16 +370,7 @@ const Game = () => { //pull out last two elements from it const drawCard1 = copiedDrawCardPileArray.pop() const drawCard2 = copiedDrawCardPileArray.pop() - //set new state - // setGameOver(checkGameOver(player1Deck)) - // setWinner(checkWinner(player1Deck, 'Player 1')) - // setPlayedCardsPile([...playedCardsPile.slice(0, playedCardsPile.length), played_card, ...playedCardsPile.slice(playedCardsPile.length)]) - // setPlayer1Deck([...player1Deck.slice(0, removeIndex), ...player1Deck.slice(removeIndex + 1)]) - // setPlayer2Deck([...player2Deck.slice(0, player2Deck.length), drawCard1, drawCard2, ...player2Deck.slice(player2Deck.length)]) - // setCurrentColor(colorOfPlayedCard) - // setCurrentNumber(252) - // setDrawCardPile([...copiedDrawCardPileArray]) - //send this state to server + //send new state to server socket.emit('updateGameState', { gameOver: checkGameOver(player1Deck), winner: checkWinner(player1Deck, 'Player 1'), @@ -464,16 +392,7 @@ const Game = () => { //pull out last two elements from it const drawCard1 = copiedDrawCardPileArray.pop() const drawCard2 = copiedDrawCardPileArray.pop() - //set new state - // setGameOver(checkGameOver(player2Deck)) - // setWinner(checkWinner(player2Deck, 'Player 2')) - // setPlayedCardsPile([...playedCardsPile.slice(0, playedCardsPile.length), played_card, ...playedCardsPile.slice(playedCardsPile.length)]) - // setPlayer2Deck([...player2Deck.slice(0, removeIndex), ...player2Deck.slice(removeIndex + 1)]) - // setPlayer1Deck([...player1Deck.slice(0, player1Deck.length), drawCard1, drawCard2, ...player1Deck.slice(player1Deck.length)]) - // setCurrentColor(colorOfPlayedCard) - // setCurrentNumber(252) - // setDrawCardPile([...copiedDrawCardPileArray]) - //send this state to server + //send new state to server socket.emit('updateGameState', { gameOver: checkGameOver(player2Deck), winner: checkWinner(player2Deck, 'Player 2'), @@ -501,15 +420,7 @@ const Game = () => { //remove the played card from player1's deck and add it to playedCardsPile (immutably) const removeIndex = player1Deck.indexOf(played_card) //then update turn, currentColor and currentNumber - //set new state - setGameOver(checkGameOver(player1Deck)) - setWinner(checkWinner(player1Deck, 'Player 1')) - setTurn('Player 2') - setPlayedCardsPile([...playedCardsPile.slice(0, playedCardsPile.length), played_card, ...playedCardsPile.slice(playedCardsPile.length)]) - setPlayer1Deck([...player1Deck.slice(0, removeIndex), ...player1Deck.slice(removeIndex + 1)]) - setCurrentColor(newColor) - setCurrentNumber(300) - //send this state to server + //send new state to server socket.emit('updateGameState', { gameOver: checkGameOver(player1Deck), winner: checkWinner(player1Deck, 'Player 1'), @@ -526,15 +437,6 @@ const Game = () => { //remove the played card from player2's deck and add it to playedCardsPile (immutably) const removeIndex = player2Deck.indexOf(played_card) //then update turn, currentColor and currentNumber - //set new state - // setGameOver(checkGameOver(player2Deck)) - // setWinner(checkWinner(player2Deck, 'Player 2')) - // setTurn('Player 1') - // setPlayedCardsPile([...playedCardsPile.slice(0, playedCardsPile.length), played_card, ...playedCardsPile.slice(playedCardsPile.length)]) - // setPlayer2Deck([...player2Deck.slice(0, removeIndex), ...player2Deck.slice(removeIndex + 1)]) - // setCurrentColor(newColor) - // setCurrentNumber(300) - //send this state to server socket.emit('updateGameState', { gameOver: checkGameOver(player2Deck), winner: checkWinner(player2Deck, 'Player 2'), @@ -564,16 +466,7 @@ const Game = () => { const drawCard3 = copiedDrawCardPileArray.pop() const drawCard4 = copiedDrawCardPileArray.pop() //then update currentColor and currentNumber - turn will remain same - //set new state - // setGameOver(checkGameOver(player1Deck)) - // setWinner(checkWinner(player1Deck, 'Player 1')) - // setPlayedCardsPile([...playedCardsPile.slice(0, playedCardsPile.length), played_card, ...playedCardsPile.slice(playedCardsPile.length)]) - // setPlayer1Deck([...player1Deck.slice(0, removeIndex), ...player1Deck.slice(removeIndex + 1)]) - // setPlayer2Deck([...player2Deck.slice(0, player2Deck.length), drawCard1, drawCard2, drawCard3, drawCard4, ...player2Deck.slice(player2Deck.length)]) - // setCurrentColor(newColor) - // setCurrentNumber(600) - // setDrawCardPile([...copiedDrawCardPileArray]) - //send this state to server + //send new state to server socket.emit('updateGameState', { gameOver: checkGameOver(player1Deck), winner: checkWinner(player1Deck, 'Player 1'), @@ -599,16 +492,7 @@ const Game = () => { const drawCard3 = copiedDrawCardPileArray.pop() const drawCard4 = copiedDrawCardPileArray.pop() //then update currentColor and currentNumber - turn will remain same - //set new state - // setGameOver(checkGameOver(player2Deck)) - // setWinner(checkWinner(player2Deck, 'Player 2')) - // setPlayedCardsPile([...playedCardsPile.slice(0, playedCardsPile.length), played_card, ...playedCardsPile.slice(playedCardsPile.length)]) - // setPlayer2Deck([...player2Deck.slice(0, removeIndex), ...player2Deck.slice(removeIndex + 1)]) - // setPlayer1Deck([...player1Deck.slice(0, player1Deck.length), drawCard1, drawCard2, drawCard3, drawCard4, ...player1Deck.slice(player1Deck.length)]) - // setCurrentColor(newColor) - // setCurrentNumber(600) - // setDrawCardPile([...copiedDrawCardPileArray]) - //send this state to server + //send new state to server socket.emit('updateGameState', { gameOver: checkGameOver(player2Deck), winner: checkWinner(player2Deck, 'Player 2'), @@ -640,12 +524,7 @@ const Game = () => { let numberOfDrawnCard = drawCard.charAt(0) if(colorOfDrawnCard === currentColor && (drawCard === 'skipR' || drawCard === 'skipG' || drawCard === 'skipB' || drawCard === 'skipY')) { alert(`You drew ${drawCard}. It was played for you.`) - //set new state - // setPlayedCardsPile([...playedCardsPile.slice(0, playedCardsPile.length), drawCard, ...playedCardsPile.slice(playedCardsPile.length)]) - // setCurrentColor(colorOfDrawnCard) - // setCurrentNumber(404) - // setDrawCardPile([...copiedDrawCardPileArray]) - //send this state to server + //send new state to server socket.emit('updateGameState', { playedCardsPile: [...playedCardsPile.slice(0, playedCardsPile.length), drawCard, ...playedCardsPile.slice(playedCardsPile.length)], currentColor: colorOfDrawnCard, @@ -661,13 +540,7 @@ const Game = () => { //pull out last two elements from it const drawCard1 = copiedDrawCardPileArray.pop() const drawCard2 = copiedDrawCardPileArray.pop() - //set new state - // setPlayedCardsPile([...playedCardsPile.slice(0, playedCardsPile.length), drawCard, ...playedCardsPile.slice(playedCardsPile.length)]) - // setPlayer2Deck([...player2Deck.slice(0, player2Deck.length), drawCard1, drawCard2, ...player2Deck.slice(player2Deck.length)]) - // setCurrentColor(colorOfDrawnCard) - // setCurrentNumber(252) - // setDrawCardPile([...copiedDrawCardPileArray]) - //send this state to server + //send new state to server socket.emit('updateGameState', { playedCardsPile: [...playedCardsPile.slice(0, playedCardsPile.length), drawCard, ...playedCardsPile.slice(playedCardsPile.length)], player2Deck: [...player2Deck.slice(0, player2Deck.length), drawCard1, drawCard2, ...player2Deck.slice(player2Deck.length)], @@ -680,15 +553,8 @@ const Game = () => { alert(`You drew ${drawCard}. It was played for you.`) //ask for new color const newColor = prompt('Enter first letter of new color in uppercase (R/G/B/Y)') - //set new state - // setTurn('Player 2') - // setPlayedCardsPile([...playedCardsPile.slice(0, playedCardsPile.length), drawCard, ...playedCardsPile.slice(playedCardsPile.length)]) - // setCurrentColor(newColor) - // setCurrentNumber(300) - // setDrawCardPile([...copiedDrawCardPileArray]) - //send this state to server + //send new state to server socket.emit('updateGameState', { - turn: 'Player 2', playedCardsPile: [...playedCardsPile.slice(0, playedCardsPile.length), drawCard, ...playedCardsPile.slice(playedCardsPile.length)], currentColor: newColor, currentNumber: 300, @@ -699,7 +565,7 @@ const Game = () => { alert(`You drew ${drawCard}. It was played for you.`) //ask for new color const newColor = prompt('Enter first letter of new color in uppercase (R/G/B/Y)') - //remove 2 new cards from drawCardPile and add them to player1's deck (immutably) + //remove 2 new cards from drawCardPile and add them to player2's deck (immutably) //make a copy of drawCardPile array const copiedDrawCardPileArray = [...drawCardPile] //pull out last four elements from it @@ -707,16 +573,10 @@ const Game = () => { const drawCard2 = copiedDrawCardPileArray.pop() const drawCard3 = copiedDrawCardPileArray.pop() const drawCard4 = copiedDrawCardPileArray.pop() - //set new state - // setPlayedCardsPile([...playedCardsPile.slice(0, playedCardsPile.length), drawCard, ...playedCardsPile.slice(playedCardsPile.length)]) - // setPlayer1Deck([...player1Deck.slice(0, player1Deck.length), drawCard1, drawCard2, drawCard3, drawCard4, ...player1Deck.slice(player1Deck.length)]) - // setCurrentColor(newColor) - // setCurrentNumber(600) - // setDrawCardPile([...copiedDrawCardPileArray]) - //send this state to server + //send new state to server socket.emit('updateGameState', { playedCardsPile: [...playedCardsPile.slice(0, playedCardsPile.length), drawCard, ...playedCardsPile.slice(playedCardsPile.length)], - player1Deck: [...player1Deck.slice(0, player1Deck.length), drawCard1, drawCard2, drawCard3, drawCard4, ...player1Deck.slice(player1Deck.length)], + player2Deck: [...player2Deck.slice(0, player2Deck.length), drawCard1, drawCard2, drawCard3, drawCard4, ...player2Deck.slice(player2Deck.length)], currentColor: newColor, currentNumber: 600, drawCardPile: [...copiedDrawCardPileArray] @@ -725,13 +585,7 @@ const Game = () => { //if not action card - check if drawn card is playable else if(numberOfDrawnCard === currentNumber || colorOfDrawnCard === currentColor) { alert(`You drew ${drawCard}. It was played for you.`) - //set new state - // setTurn('Player 2') - // setPlayedCardsPile([...playedCardsPile.slice(0, playedCardsPile.length), drawCard, ...playedCardsPile.slice(playedCardsPile.length)]) - // setCurrentColor(colorOfDrawnCard) - // setCurrentNumber(numberOfDrawnCard) - // setDrawCardPile([...copiedDrawCardPileArray]) - //send this state to server + //send new state to server socket.emit('updateGameState', { turn: 'Player 2', playedCardsPile: [...playedCardsPile.slice(0, playedCardsPile.length), drawCard, ...playedCardsPile.slice(playedCardsPile.length)], @@ -743,11 +597,7 @@ const Game = () => { //else add the drawn card to player1's deck else { alert(`You drew ${drawCard}.`) - //set new state - // setTurn('Player 2') - // setPlayer1Deck([...player1Deck.slice(0, player1Deck.length), drawCard, ...player1Deck.slice(player1Deck.length)]) - // setDrawCardPile([...copiedDrawCardPileArray]) - //send this state to server + //send new state to server socket.emit('updateGameState', { turn: 'Player 2', player1Deck: [...player1Deck.slice(0, player1Deck.length), drawCard, ...player1Deck.slice(player1Deck.length)], @@ -766,12 +616,7 @@ const Game = () => { let numberOfDrawnCard = drawCard.charAt(0) if(colorOfDrawnCard === currentColor && (drawCard === 'skipR' || drawCard === 'skipG' || drawCard === 'skipB' || drawCard === 'skipY')) { alert(`You drew ${drawCard}. It was played for you.`) - //set new state - // setPlayedCardsPile([...playedCardsPile.slice(0, playedCardsPile.length), drawCard, ...playedCardsPile.slice(playedCardsPile.length)]) - // setCurrentColor(colorOfDrawnCard) - // setCurrentNumber(404) - // setDrawCardPile([...copiedDrawCardPileArray]) - //send this state to server + //send new state to server socket.emit('updateGameState', { playedCardsPile: [...playedCardsPile.slice(0, playedCardsPile.length), drawCard, ...playedCardsPile.slice(playedCardsPile.length)], currentColor: colorOfDrawnCard, @@ -781,22 +626,16 @@ const Game = () => { } else if(colorOfDrawnCard === currentColor && (drawCard === 'D2R' || drawCard === 'D2G' || drawCard === 'D2B' || drawCard === 'D2Y')) { alert(`You drew ${drawCard}. It was played for you.`) - //remove 2 new cards from drawCardPile and add them to player2's deck (immutably) + //remove 2 new cards from drawCardPile and add them to player1's deck (immutably) //make a copy of drawCardPile array const copiedDrawCardPileArray = [...drawCardPile] //pull out last two elements from it const drawCard1 = copiedDrawCardPileArray.pop() const drawCard2 = copiedDrawCardPileArray.pop() - //set new state - // setPlayedCardsPile([...playedCardsPile.slice(0, playedCardsPile.length), drawCard, ...playedCardsPile.slice(playedCardsPile.length)]) - // setPlayer2Deck([...player2Deck.slice(0, player2Deck.length), drawCard1, drawCard2, ...player2Deck.slice(player2Deck.length)]) - // setCurrentColor(colorOfDrawnCard) - // setCurrentNumber(252) - // setDrawCardPile([...copiedDrawCardPileArray]) - //send this state to server + //send new state to server socket.emit('updateGameState', { playedCardsPile: [...playedCardsPile.slice(0, playedCardsPile.length), drawCard, ...playedCardsPile.slice(playedCardsPile.length)], - player2Deck: [...player2Deck.slice(0, player2Deck.length), drawCard1, drawCard2, ...player2Deck.slice(player2Deck.length)], + player1Deck: [...player1Deck.slice(0, player1Deck.length), drawCard1, drawCard2, ...player1Deck.slice(player1Deck.length)], currentColor: colorOfDrawnCard, currentNumber: 252, drawCardPile: [...copiedDrawCardPileArray] @@ -806,15 +645,8 @@ const Game = () => { alert(`You drew ${drawCard}. It was played for you.`) //ask for new color const newColor = prompt('Enter first letter of new color in uppercase (R/G/B/Y)') - //set new state - // setTurn('Player 1') - // setPlayedCardsPile([...playedCardsPile.slice(0, playedCardsPile.length), drawCard, ...playedCardsPile.slice(playedCardsPile.length)]) - // setCurrentColor(newColor) - // setCurrentNumber(300) - // setDrawCardPile([...copiedDrawCardPileArray]) - //send this state to server + //send new state to server socket.emit('updateGameState', { - turn: 'Player 1', playedCardsPile: [...playedCardsPile.slice(0, playedCardsPile.length), drawCard, ...playedCardsPile.slice(playedCardsPile.length)], currentColor: newColor, currentNumber: 300, @@ -833,13 +665,7 @@ const Game = () => { const drawCard2 = copiedDrawCardPileArray.pop() const drawCard3 = copiedDrawCardPileArray.pop() const drawCard4 = copiedDrawCardPileArray.pop() - //set new state - // setPlayedCardsPile([...playedCardsPile.slice(0, playedCardsPile.length), drawCard, ...playedCardsPile.slice(playedCardsPile.length)]) - // setPlayer1Deck([...player1Deck.slice(0, player1Deck.length), drawCard1, drawCard2, drawCard3, drawCard4, ...player1Deck.slice(player1Deck.length)]) - // setCurrentColor(newColor) - // setCurrentNumber(600) - // setDrawCardPile([...copiedDrawCardPileArray]) - //send this state to server + //send new state to server socket.emit('updateGameState', { playedCardsPile: [...playedCardsPile.slice(0, playedCardsPile.length), drawCard, ...playedCardsPile.slice(playedCardsPile.length)], player1Deck: [...player1Deck.slice(0, player1Deck.length), drawCard1, drawCard2, drawCard3, drawCard4, ...player1Deck.slice(player1Deck.length)], @@ -851,13 +677,7 @@ const Game = () => { //if not action card - check if drawn card is playable else if(numberOfDrawnCard === currentNumber || colorOfDrawnCard === currentColor) { alert(`You drew ${drawCard}. It was played for you.`) - //set new state - // setTurn('Player 1') - // setPlayedCardsPile([...playedCardsPile.slice(0, playedCardsPile.length), drawCard, ...playedCardsPile.slice(playedCardsPile.length)]) - // setCurrentColor(colorOfDrawnCard) - // setCurrentNumber(numberOfDrawnCard) - // setDrawCardPile([...copiedDrawCardPileArray]) - //send this state to server + //send new state to server socket.emit('updateGameState', { turn: 'Player 1', playedCardsPile: [...playedCardsPile.slice(0, playedCardsPile.length), drawCard, ...playedCardsPile.slice(playedCardsPile.length)], @@ -869,11 +689,7 @@ const Game = () => { //else add the drawn card to player2's deck else { alert(`You drew ${drawCard}.`) - //set new state - // setTurn('Player 1') - // setPlayer2Deck([...player2Deck.slice(0, player2Deck.length), drawCard, ...player2Deck.slice(player2Deck.length)]) - // setDrawCardPile([...copiedDrawCardPileArray]) - //send this state to server + //send new state to server socket.emit('updateGameState', { turn: 'Player 1', player2Deck: [...player2Deck.slice(0, player2Deck.length), drawCard, ...player2Deck.slice(player2Deck.length)], @@ -884,9 +700,14 @@ const Game = () => { } return ( - gameOver ?
{winner !== '' && <>

GAME OVER

{winner} wins!

}Home
: + (!roomFull) ? <> + + {users.length===2 ? <> + + {gameOver ?
{winner !== '' && <>

GAME OVER

{winner} wins!

}Home
:

Turn: {turn}

+ {currentUser === 'Player 1' &&
{player1Deck.map((item) => ( { {item} ))} -
+ +
}

Current Card: {playedCardsPile[playedCardsPile.length-1]}

Current Color: {currentColor}

- +

+ {currentUser === 'Player 2' &&
{player2Deck.map((item) => ( { {item} ))} + +
} +
+
+

Users in room:

+ {users.map(user => { + return
{user.name}
+ })}
Home - + } + + :

Waiting for other player

} + + :

Room full

) } diff --git a/client/src/components/Homepage.js b/client/src/components/Homepage.js index 0819410..f83605f 100644 --- a/client/src/components/Homepage.js +++ b/client/src/components/Homepage.js @@ -1,11 +1,14 @@ -import React from 'react' +import React, { useState } from 'react' import { Link } from 'react-router-dom' const Homepage = () => { + const [roomCode, setRoomCode] = useState('') + return (

UNO

- +
setRoomCode(event.target.value)} />
+
) } diff --git a/package.json b/package.json index becffdd..16aeb7e 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,8 @@ "description": "Online multiplayer card game", "main": "server.js", "scripts": { - "start": "node server" + "start": "node server", + "client": "npm start --prefix client" }, "repository": { "type": "git", diff --git a/server.js b/server.js index 3f94a02..0d71d1c 100644 --- a/server.js +++ b/server.js @@ -2,6 +2,7 @@ const express = require('express') const socketio = require('socket.io') const http = require('http') const cors = require('cors') +const { addUser, removeUser, getUser, getUsersInRoom } = require('./users') const PORT = process.env.PORT || 5000 @@ -12,18 +13,41 @@ const io = socketio(server) app.use(cors()) io.on('connection', socket => { - console.log('connection made') + socket.on('join', (payload, callback) => { + let numberOfUsersInRoom = getUsersInRoom(payload.room).length + + const { error, newUser} = addUser({ + id: socket.id, + name: numberOfUsersInRoom===0 ? 'Player 1' : 'Player 2', + room: payload.room + }) + + if(error) + return callback(error) + + socket.join(newUser.room) + + io.to(newUser.room).emit('roomData', {room: newUser.room, users: getUsersInRoom(newUser.room)}) + socket.emit('currentUserData', {name: newUser.name}) + callback() + }) socket.on('initGameState', gameState => { - io.emit('initGameState', gameState) + const user = getUser(socket.id) + if(user) + io.to(user.room).emit('initGameState', gameState) }) socket.on('updateGameState', gameState => { - io.emit('updateGameState', gameState) + const user = getUser(socket.id) + if(user) + io.to(user.room).emit('updateGameState', gameState) }) socket.on('disconnect', () => { - console.log('connection lost') + const user = removeUser(socket.id) + if(user) + io.to(user.room).emit('roomData', {room: user.room, users: getUsersInRoom(user.room)}) }) }) diff --git a/users.js b/users.js new file mode 100644 index 0000000..c44c1f6 --- /dev/null +++ b/users.js @@ -0,0 +1,28 @@ + const users = [] + + const addUser = ({id, name, room}) => { + const numberOfUsersInRoom = users.filter(user => user.room === room).length + if(numberOfUsersInRoom === 2) + return { error: 'Room full' } + + const newUser = { id, name, room } + users.push(newUser) + return { newUser } +} + +const removeUser = id => { + const removeIndex = users.findIndex(user => user.id === id) + + if(removeIndex!==-1) + return users.splice(removeIndex, 1)[0] +} + +const getUser = id => { + return users.find(user => user.id === id) +} + +const getUsersInRoom = room => { + return users.filter(user => user.room === room) +} + +module.exports = { addUser, removeUser, getUser, getUsersInRoom } \ No newline at end of file