aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/components/App.js3
-rw-r--r--src/components/GamemodeChooser.js1
-rw-r--r--src/components/MultiplayerGrid.js38
-rw-r--r--src/components/MultiplayerMenu.js45
-rw-r--r--src/server/index.js48
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)
};
});
});