diff options
| author | Vidhu Kant Sharma <araararagikoyomi@protonmail.com> | 2021-08-01 02:36:22 +0530 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-08-01 02:36:22 +0530 | 
| commit | 69d3376df1db5659bd413dbac2b563b2bd1850b6 (patch) | |
| tree | 3aa3f708e3f3c6b7d804ecdc53c4fce755853c91 | |
| parent | 6b58ffac163b9b3637bfab1294069c55b6d5702c (diff) | |
| parent | b8babd592b60b1a2cfedac3956184207a3d4bb8d (diff) | |
Merge pull request #2 from MikunoNaka/multiplayer
Merge multiplayer into main
| -rw-r--r-- | src/components/App.js | 3 | ||||
| -rw-r--r-- | src/components/GamemodeChooser.js | 1 | ||||
| -rw-r--r-- | src/components/MultiplayerGrid.js | 38 | ||||
| -rw-r--r-- | src/components/MultiplayerMenu.js | 45 | ||||
| -rw-r--r-- | src/server/index.js | 48 | 
5 files changed, 116 insertions, 19 deletions
| diff --git a/src/components/App.js b/src/components/App.js index db5af1b..5b13230 100644 --- a/src/components/App.js +++ b/src/components/App.js @@ -33,6 +33,7 @@ const App = () => {    const [showMessageBox, setShowMessageBox] = useState(false);    const [message, setMessage] = useState("");    const [isHost, setIsHost] = useState(false); +  const [joinCode, setJoinCode] = useState();    return gameStarted ? (      <> @@ -61,6 +62,7 @@ const App = () => {            setScoreO={setScoreO}             setMessage={setMessage}             setShowMessage={setShowMessageBox} +          joinCode={joinCode}          /> : <Grid             turn={turn}             setTurn={setTurn}  @@ -81,6 +83,7 @@ const App = () => {          setMultiplayer={setMultiplayer}          setGameStarted={setGameStarted}          setIsHost={setIsHost} +        setJoinCode={setJoinCode}        />        <Footer/>      </> diff --git a/src/components/GamemodeChooser.js b/src/components/GamemodeChooser.js index 91010e4..6b2e985 100644 --- a/src/components/GamemodeChooser.js +++ b/src/components/GamemodeChooser.js @@ -47,6 +47,7 @@ const GamemodeChooser = (props) => {            <MultiplayerMenu              setIsHost={props.setIsHost}              setGameStarted={props.setGameStarted} +            setJoinCode={props.setJoinCode}            />            <div className={"GamemodeButton"} onClick={() => { diff --git a/src/components/MultiplayerGrid.js b/src/components/MultiplayerGrid.js index 88a8259..d7eae36 100644 --- a/src/components/MultiplayerGrid.js +++ b/src/components/MultiplayerGrid.js @@ -26,11 +26,43 @@ const socket = io("http://localhost:5000");  const MultiplayerGrid = (props) => {    // 0 is O, 1 is X, 2 is blank    const [board, setBoard] = useState([2,2,2,2,2,2,2,2,2]); +    const turn = props.turn; +  const isHost = props.isHost; +  const joinCode = props.joinCode; +  const setMessage = props.setMessage; +  const setShowMessage = props.setShowMessage; + +  // host/join room +  useEffect(() => { +    if (isHost) { +      socket.emit("host"); + +      socket.on("broadcast code", (code) => { +        setMessage(`Game Code: ${code}`); +        setShowMessage(true); +      }); + +      socket.on("player joined", () => { +        setMessage("Opponent Joined") +        setShowMessage(true) +        setTimeout(() => setShowMessage(false), 3000) +      }) +    } else { +      socket.emit("join", joinCode); + +      // error if room doesn't exist +      socket.on("join failed", () => { +        setMessage("Error: room not found") +        setShowMessage(true) +        setTimeout(() => window.location.reload(), 3000) +      }); +    } +  }, [isHost, setMessage, setShowMessage, joinCode]);    const getBoard = (index) => {      // if it's not your turn you can't play -    if ((turn === 0) === props.isHost) return; +    if ((turn === 0) === isHost) return;      const newBoard = board.slice(0, index).concat(turn).concat(board.slice(index+1, 9));      socket.emit("update-remote-data", { @@ -42,10 +74,10 @@ const MultiplayerGrid = (props) => {    }    const endGame = (data) => { -    props.setMessage( +    setMessage(        `${data.winner === "Data" ? "" : "WINNER: "}${data.winner}`      ); -    props.setShowMessage(true); +    setShowMessage(true);      props.setScoreX(data.scoreX);      props.setScoreO(data.scoreO); diff --git a/src/components/MultiplayerMenu.js b/src/components/MultiplayerMenu.js index 1dfe9dd..aa77507 100644 --- a/src/components/MultiplayerMenu.js +++ b/src/components/MultiplayerMenu.js @@ -15,24 +15,45 @@   * along with this program.  If not, see <https://www.gnu.org/licenses/>.   */ -import React from 'react'; +import React, { useState } from 'react';  import './style.css';  const MultiplayerMenu = (props) => { +  const [showCodeInput, setShowCodeInput] = useState(false) +  const [joinCode, setJoinCode] = useState(""); +    return (      <div className={"MultiplayerMenu"}> -      <div className={"GamemodeButton"} onClick={() => { -        props.setIsHost(true); -        props.setGameStarted(true); -      }}> -        HOST GAME -      </div> +      {showCodeInput  +        ? <> +          <input type="text" placeholder={"ENTER CODE"} +            className={"GamemodeButton"} onChange={ +              (event) => setJoinCode(event.target.value) +            } +          /> + +          <div className={"GamemodeButton"} onClick={() => { +            props.setGameStarted(true); +            props.setJoinCode(joinCode); +          }}> +            START +          </div> +        </> +        : <> +          <div className={"GamemodeButton"} onClick={() => { +            props.setIsHost(true); +            props.setGameStarted(true); +          }}> +            HOST GAME +          </div> -      <div className={"GamemodeButton"} onClick={() => { -        props.setGameStarted(true); -      }}> -        JOIN GAME -      </div> +          <div className={"GamemodeButton"} onClick={() => { +            setShowCodeInput(true); +          }}> +            JOIN GAME +          </div> +        </> +      }      </div>    );  } diff --git a/src/server/index.js b/src/server/index.js index 2799805..a5aa97f 100644 --- a/src/server/index.js +++ b/src/server/index.js @@ -3,15 +3,37 @@ const app = express();  const http = require('http').Server(app);  const path = require('path'); -// const io = require('socket.io')(http);  const io = require("socket.io")(http, {    cors: { -    origin: ["http://localhost:5000", "http://localhost:3000"], +    origin: [ +      "http://localhost:5000",  +      "http://localhost:3000", +      "https://mikunonaka-tic-tac-toe.herokuapp.com",  +      "http://mikunonaka-tic-tac-toe.herokuapp.com" +    ],      "Access-Control-Allow-Origin": "*",      methods: ["GET", "POST"]    }  }); +// check if room exists +const checkCode = (code) => { +  const connectedSockets = []; +  io.sockets.sockets.forEach( +    (i) => connectedSockets.push(i) +  ); + +  // returns true if room exists +  return connectedSockets.some( +    (i) => Array.from(i.rooms)[1] === code +  ); +} + +// generate new room code +// also checks for duplicates +const getCode = (code = `${Math.floor(1000 + Math.random() * 9000)}`) => +  checkCode(code) ? getCode : code; +  const allEqual = (arr) =>    arr.includes(2) ? false : arr.every(i => i === arr[0]) @@ -38,7 +60,25 @@ const getScore = (winner, scoreX, scoreO, board) => ({  })  io.on('connection', (socket) => { +  socket.on('host', () => { +    const code = getCode(); +    socket.join(code); +    io.to(code).emit('broadcast code', code); +  }); + +  socket.on('join', (code) => { +    if (checkCode(code)) { +      socket.join(code); +      io.to(code).emit('player joined'); +    } else { +      // error if room doesn't exist +      socket.emit('join failed') +    } +  }); +    socket.on('update-remote-data', (data) => { +    const room = Array.from(socket.rooms)[1] +      if (data.board.includes(0) || data.board.includes(1)) {        const rows = getRows(data.board);        const winner = (rows.some((i) => allEqual(i)) @@ -47,13 +87,13 @@ io.on('connection', (socket) => {        ) ? data.turn : 2;        const score = getScore(winner, data.scoreX, data.scoreO, data.board) -      io.emit('update-client-data', { +      io.to(room).emit('update-client-data', {          board: data.board,           turn: score.winner ? data.turn : (data.turn === 0 ? 1 : 0),          score: score        }); -      score.winner && io.emit('update-winner', score) +      score.winner && io.to(room).emit('update-winner', score)      };    });  }); |