diff --git a/BakcendTemplate/app.js b/BakcendTemplate/app.js index a42e4fb..8f32422 100644 --- a/BakcendTemplate/app.js +++ b/BakcendTemplate/app.js @@ -6,7 +6,7 @@ const { Server } = require("socket.io"); app.use(cors()); const server = http.createServer(app); -const connectedUsers = {}; +const connectedUsers = []; const io = new Server(server, { cors: { @@ -14,28 +14,68 @@ const io = new Server(server, { methods: ["GET", "POST"], }, }); - +const usersInRoom = {}, curShuffle = {}; io.on("connection", (socket) => { socket.on("join_room", (data) => { - socket.join(data); - // console.log(data); + socket.join(data.room); + if (!usersInRoom[data.room]) { + usersInRoom[data.room] = []; + } + + if(data.username !== ""){ + usersInRoom[data.room].push({ id: socket.id, username: data.username }); + } + + // Emit the updated list of users to the frontend + io.to(data.room).emit("users_list", usersInRoom[data.room]); + console.log(usersInRoom[data.room]); }); - socket.on("send_message", (data) => { - console.log(data); - socket.to(data.room).emit("receive_message", data); - }); - + socket.on("notify_others_to_start", (data) => { + const isStart = true; + curShuffle[data.room] = []; + io.to(data.room).emit("start_game", isStart); + console.log(curShuffle); + }); - + //guti shake + socket.on("guti_shake", (data) => { + curShuffle[data.room] = data.shuffleArray; + io.to(data.room).emit("recieve_shuffle", curShuffle[data.room]); + console.log("shuffle recived and sent to all", curShuffle[data.room]); + }); + + //police kare dhorse + socket.on("dhorsi_ore", (data) => { + io.to(data.room).emit("dhorse_ore", data.guess); + console.log("police dhorse", usersInRoom[data.room][data.guess]); + }); + + //coninue + + socket.on("send_message", (data) => { + var msg = data.username + ": " + data.message; + console.log(msg); + io.to(data.room).emit("receive_message", msg); + }); + + socket.on("berhoa", (data) => { + + usersInRoom[data.roomId] = usersInRoom[data.roomId].filter(user => user.id !== socket.id); + + io.to(data.roomId).emit("users_list", usersInRoom[data.roomId]); + console.log(usersInRoom[data.roomId]); + }); + + socket.on("disconnect", () => { - console.log("User Disconnected", socket.id); - }); + console.log("User Disconnected", socket.id); + }); }); diff --git a/FrontendTemplate/src/components/ChatModal.jsx b/FrontendTemplate/src/components/ChatModal.jsx index 0693856..8da24d0 100644 --- a/FrontendTemplate/src/components/ChatModal.jsx +++ b/FrontendTemplate/src/components/ChatModal.jsx @@ -3,7 +3,7 @@ import { useState } from "react"; const ChatModal = (props) => { - const { isModalOpen, setIsModalOpen } = props; + const { isModalOpen, setIsModalOpen, socket, username, room } = props; const [modalInput, setModalInput] = useState(""); const [modaTitle, setModalTitle] = useState("Enter your Message"); @@ -14,6 +14,10 @@ const ChatModal = (props) => { setModalTitle("Enter your Message"); }; + const sentMsg = () => { + socket.emit("send_message", {message: modalInput, username: username, room: room}); + } + return ( { onClick={() => { setModalInput(""); setIsModalOpen(false); + sentMsg(); }} > Send diff --git a/FrontendTemplate/src/components/GameBoard.jsx b/FrontendTemplate/src/components/GameBoard.jsx index 287223d..df5455d 100644 --- a/FrontendTemplate/src/components/GameBoard.jsx +++ b/FrontendTemplate/src/components/GameBoard.jsx @@ -3,8 +3,8 @@ import styled from "styled-components"; import Players from "./Players"; import ShakeHand from "./ShakeHand"; -const GameBoard = () => { - const playerName = "Rafi"; // Replace with the actual player name +const GameBoard = ({totalScore, scores, addScore, setScore, playerName}) => { + // Replace with the actual player name const playerImage = ""; return ( @@ -13,43 +13,45 @@ const GameBoard = () => {
-
-
- +
@@ -67,19 +69,22 @@ const Wrapper = styled.section` .player2n4 { display: flex; flex-grow: 1; - justify-content: space-between; } .player2 { - display: grid; - place-items: center; + display: flex; + align-items: center; + justify-content: center; } - #shake { - display: grid; - place-items: center; + #shake { + flex-grow: 1; + display: flex; + align-items: center; + justify-content: center; } #player4 { - display: grid; - place-items: center; + display: flex; + align-items: center; + justify-content: center; } .player1 { diff --git a/FrontendTemplate/src/components/GameBoardOnline.jsx b/FrontendTemplate/src/components/GameBoardOnline.jsx new file mode 100644 index 0000000..ea45a42 --- /dev/null +++ b/FrontendTemplate/src/components/GameBoardOnline.jsx @@ -0,0 +1,128 @@ +import React from "react"; +import styled from "styled-components"; +import Players from "./Players"; +import ShakeHandOnline from "./ShakeHandOnline"; + +const GameBoardOnline = ({ + totalScore, + scores, + addScore, + setScore, + playerName, + socket, + username, + room +}) => { + + const playerImage = ""; + + return ( + +
+
+
+ +
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+ +
+
+
+ ); +}; + +const Wrapper = styled.section` + .game-board { + display: flex; + flex-direction: column; + height: 100vh; + width: 75vw; + } + .player2n4 { + display: flex; + flex-grow: 1; + } + .player2 { + display: flex; + align-items: center; + justify-content: center; + } + #shake { + flex-grow: 1; + display: flex; + align-items: center; + justify-content: center; + } + #player4 { + display: flex; + align-items: center; + justify-content: center; + } + + .player1 { + display: flex; + align-items: center; + justify-content: center; + } + + @media (max-width: 768px) { + .game-board { + display: flex; + flex-direction: column; + width: 100%; + height: 75vh; + } + .player2n4 { + display: flex; + flex-grow: 1; + justify-content: space-between; + } + } +`; + +export default GameBoardOnline; diff --git a/FrontendTemplate/src/components/GutiButton.jsx b/FrontendTemplate/src/components/GutiButton.jsx index c79d04a..1caa921 100644 --- a/FrontendTemplate/src/components/GutiButton.jsx +++ b/FrontendTemplate/src/components/GutiButton.jsx @@ -1,28 +1,46 @@ -import React, { useState } from "react"; +import React, { useEffect, useState } from "react"; import styled from "styled-components"; import kagoj from "../assets/kagoj.png"; import babu from "../assets/babu.png"; import police from "../assets/police.png"; import chor from "../assets/chor.png"; import dakat from "../assets/dakat.png"; +import { Button } from "antd"; -const GutiButton = ({ shufArray }) => { +const GutiButton = ({ playerName, shufArray, restart, scores, addScore, setScore }) => { const [showButton, setShowButton] = useState(true); const [showImage, setShowImage] = useState(false); const [selectedButton, setSelectedButton] = useState(null); const [policeState, setPoliceState] = useState(false); + const [lastState, setLastState] = useState(false); const [selectedImage, setSelectedImage] = useState(null); + const [policeGuess, setPoliceGuess] = useState(-1); + const [isChor, setIsChor] = useState(true); const gotImage = [chor, dakat, police, babu]; + const bangla = ["চোর", "ডাকাত", "পুলিশ", "বাবু"]; + var curscore = [0, 0, 0, 0]; + var selectedIndex; const myguti = 0; - console.log(shufArray); + //console.log(shufArray); + + useEffect(() => { + setIsChor(scores[0].length % 2 == 0); + //console.log(isChor); + }, []); const buttonClicking = (index) => { - console.log(shufArray[index]); - selectedIndex = shufArray[index]; + //console.log("before " + shufArray); + //console.log("index : " + index); + const tmp = shufArray[index]; + shufArray[index] = shufArray[0]; + shufArray[0] = tmp; + //console.log("after" + shufArray); + setSelectedImage(shufArray[0]); + // TODO : DISTRIBUTE 3 to ai - // res: [0, 1, 3, 2] + // res: [0, 1, 3, 2] setShowButton(false); setShowImage(true); @@ -30,18 +48,149 @@ const GutiButton = ({ shufArray }) => { }; const imageClick = () => { - setShowImage(false); setPoliceState(true); // render new component // police_success = 0 / 1 + }; + + function getPolice(x) { + for (let i = 0; i < 4; i++) { + if (shufArray[i] == x) return playerName[i]; + } + } + + function getChorDakat(){ + var ans = []; + for(var i = 0; i < 4; i++){ + if(shufArray[i] < 2) ans.push(i); + } + return ans; } + function isPoliceCorrect(){ + if(isChor && shufArray[policeGuess] == 0) return true; +else if(!isChor && shufArray[policeGuess] == 1) return true; + else{ + const currentTimestamp = new Date().getTime(); + const randomValue = currentTimestamp % 2; + + if(randomValue==0){ + return true; + } + else return false; + } + return false; + } + + function getScore() { + const newScores = [0, 0, 0, 0]; // Create a new array to store the updated scores + + for (let i = 0; i < 4; i++) { + if (shufArray[i] === 3) newScores[i] = 100; + else if (shufArray[i] === 2 && isPoliceCorrect()) newScores[i] = 80; + else if (shufArray[i] === 1) { + if (isPoliceCorrect() && !isChor) { + // Do nothing, leave newScores[i] as 0 + } else newScores[i] = 60; + } else if (shufArray[i] === 0) { + if (isPoliceCorrect() && isChor) { + // Do nothing, leave newScores[i] as 0 + } else newScores[i] = 40; + } + } + + return newScores; + } + + return (
- {policeState && (
hello
)} + {lastState && ( +
+ {isPoliceCorrect() ? "পুলিশ সঠিক ধরেছেন" : "পুলিশ ভূল ধরেছেন"}
+ চোর {isChor && isPoliceCorrect() ? "+০" : "+৪০"}
+ ডাকাত {!isChor && isPoliceCorrect() ? "+০" : "+৬০"}
+ বাবু +১০০
+ পুলিশ {isPoliceCorrect() ? "+৮০" : "+০"}
+ +
+ )} + {policeState && ( +
+
+
+ +
+
+
+ আপনি পেয়েছেনঃ   {bangla[selectedImage]} +
+
+ {selectedImage != 2 && ( + + পুলিশ হলোঃ   {getPolice(2)} + + )} + {selectedImage == 2 && ( + + বাবু হলোঃ   {getPolice(3)} + + )} +
+
+
+
{isChor == true ? "চোর কে ধরুন" : "ডাকাত কে ধরুন" }
+
+ {selectedImage == 2 && ( +
+ + +
+ )} + {selectedImage != 2 && ( + + )} +
+
+ )}
{Array.from({ length: 2 }, (_, index) => (
@@ -54,9 +203,11 @@ const GutiButton = ({ shufArray }) => { Displayed Image {imageClick()}} + onClick={() => { + imageClick(); + }} /> )}
@@ -73,9 +224,11 @@ const GutiButton = ({ shufArray }) => { {showImage && selectedButton === index + 2 && ( Displayed Image {imageClick()}} + onClick={() => { + imageClick(); + }} /> )}
@@ -103,10 +256,61 @@ const Wrapper = styled.section` animation: shake 0.5s ease-in-out infinite; } + .last-card { + width: 300px; + font-size: 18px; + text-align: center; + } + + .police-state-top-left img { + height: 100px; + width: 100px; + object-fit: cover; + animation: none; + } + #shah { height: 100%; width: 100%; } + + .police-state { + } + + .police-state-top { + height: 200px; + width: 350px; + display: flex; + align-items: center; + justify-content: center; + } + + .police-state-top-left { + width: 50%; + } + + .police-state-top-left img { + width: 80% !important; + height: 100%; + } + + .police-state-top-right { + width: 50%; + } + + .jayga { + margin: 10px; + margin-left: 30px; + margin-right: 30px; + } + + .police-state-btm { + height: 70px; + display: flex; + justify-content: center; + align-items: center; + } + @media (max-width: 768px) { #shah { height: 200px; @@ -117,14 +321,32 @@ const Wrapper = styled.section` width: 80px; object-fit: cover; } + .police-state-top { + height: 80px; + width: 170px; + font-size: 10px; + } + .jayga { + margin: 10px; + } } @keyframes shake { - 0% { transform: translate(0); } - 25% { transform: translate(0,-5px); } - 50% { transform: translate(0, 5px); } - 75% { transform: translate(0, -5px); } - 100% { transform: translate(0); } -} + 0% { + transform: translate(0); + } + 25% { + transform: translate(0, -5px); + } + 50% { + transform: translate(0, 5px); + } + 75% { + transform: translate(0, -5px); + } + 100% { + transform: translate(0); + } + } `; export default GutiButton; diff --git a/FrontendTemplate/src/components/GutiButtonOnline.jsx b/FrontendTemplate/src/components/GutiButtonOnline.jsx new file mode 100644 index 0000000..1671517 --- /dev/null +++ b/FrontendTemplate/src/components/GutiButtonOnline.jsx @@ -0,0 +1,403 @@ +import React, { useEffect, useState } from "react"; +import styled from "styled-components"; +import kagoj from "../assets/kagoj.png"; +import babu from "../assets/babu.png"; +import police from "../assets/police.png"; +import chor from "../assets/chor.png"; +import dakat from "../assets/dakat.png"; +import { Button } from "antd"; + +const GutiButtonOnline = ({ + playerName, + shufArray, + restart, + scores, + addScore, + setScore, + socket, + username, + room, +}) => { + const [showButton, setShowButton] = useState(true); + const [showImage, setShowImage] = useState(false); + const [selectedButton, setSelectedButton] = useState(null); + const [policeState, setPoliceState] = useState(false); + const [lastState, setLastState] = useState(false); + const [selectedImage, setSelectedImage] = useState(null); + const [policeGuess, setPoliceGuess] = useState(-1); + const [isChor, setIsChor] = useState(true); + const [showContinue, setShowContinue] = useState(false); + const gotImage = [chor, dakat, police, babu]; + const bangla = ["চোর", "ডাকাত", "পুলিশ", "বাবু"]; + var curscore = [0, 0, 0, 0]; + + var selectedIndex; + + const myguti = 0; + console.log(shufArray); + + useEffect(() => { + setIsChor(scores[0].length % 2 == 0); + console.log(isChor); + }, []); + + function getIndex() { + if (scores[0][0] === username) return 0; + if (scores[1][0] === username) return 1; + if (scores[2][0] === username) return 2; + if (scores[3][0] === username) return 3; + return 0; + } + + useEffect(() => { + if (socket) { + socket.on("dhorse_ore", (indx) => { + // setLastState(true); + // setPoliceState(false); + setShowContinue(true); + setPoliceGuess(indx); + }); + } + return () => { + if (socket) { + socket.off("dhorse_ore"); + } + }; + }, [socket]); + + const buttonClicking = (index) => { + //console.log("before " + shufArray); + //console.log("index : " + index); + //const tmp = shufArray[index]; + //shufArray[index] = shufArray[0]; + //shufArray[0] = tmp; + //console.log("after" + shufArray); + setSelectedImage(shufArray[getIndex()]); + + // TODO : DISTRIBUTE 3 to ai + // res: [0, 1, 3, 2] + + setShowButton(false); + setShowImage(true); + setSelectedButton(index); + }; + + const imageClick = () => { + setShowImage(false); + setPoliceState(true); + // render new component + // police_success = 0 / 1 + }; + + function getPolice(x) { + for (let i = 0; i < 4; i++) { + if (shufArray[i] == x) return playerName[i]; + } + } + + function getChorDakat() { + var ans = []; + for (var i = 0; i < 4; i++) { + if (shufArray[i] < 2) ans.push(i); + } + return ans; + } + + function isPoliceCorrect() { + if (isChor && shufArray[policeGuess] == 0) return true; + else if (!isChor && shufArray[policeGuess] == 1) return true; + return false; + } + + function getScore() { + const newScores = [0, 0, 0, 0]; // Create a new array to store the updated scores + + for (let i = 0; i < 4; i++) { + if (shufArray[i] === 3) newScores[i] = 100; + else if (shufArray[i] === 2 && isPoliceCorrect()) newScores[i] = 80; + else if (shufArray[i] === 1) { + if (isPoliceCorrect() && !isChor) { + // Do nothing, leave newScores[i] as 0 + } else newScores[i] = 60; + } else if (shufArray[i] === 0) { + if (isPoliceCorrect() && isChor) { + // Do nothing, leave newScores[i] as 0 + } else newScores[i] = 40; + } + } + + return newScores; + } + + return ( + +
+
+ {lastState && ( +
+ {isPoliceCorrect() ? "পুলিশ সঠিক ধরেছেন" : "পুলিশ ভূল ধরেছেন"}{" "} +
+ চোর {isChor && isPoliceCorrect() ? "+০" : "+৪০"}{" "} +
+ ডাকাত + {!isChor && isPoliceCorrect() ? "+০" : "+৬০"} + {" "} +
+ বাবু +১০০
+ পুলিশ {isPoliceCorrect() ? "+৮০" : "+০"}
+ +
+ )} + {policeState && ( +
+
+
+ +
+
+
+ আপনি পেয়েছেনঃ   {bangla[selectedImage]} +
+
+ {selectedImage != 2 && ( + + পুলিশ হলোঃ   {getPolice(2)} + + )} + {selectedImage == 2 && ( + + বাবু হলোঃ   {getPolice(3)} + + )} +
+
+
+
+ {" "} +
+ {" "} + {isChor == true ? "চোর কে ধরুন" : "ডাকাত কে ধরুন"}{" "} +
{" "} +
+
+ {selectedImage == 2 && ( +
+ + +
+ )} + {selectedImage != 2 && showContinue && ( + + )} + {selectedImage != 2 && !showContinue && ( +

+ {getPolice(2)} {isChor == true ? "চোর" : "ডাকাত"} কে + ধরছেন...{" "} +

+ )} +
+
+ )} +
+ {Array.from({ length: 2 }, (_, index) => ( +
+ {showButton && ( + + )} + {showImage && selectedButton === index && ( + Displayed Image { + imageClick(); + }} + /> + )} +
+ ))} +
+
+ {Array.from({ length: 2 }, (_, index) => ( +
+ {showButton && ( + + )} + {showImage && selectedButton === index + 2 && ( + Displayed Image { + imageClick(); + }} + /> + )} +
+ ))} +
+
+
+
+ ); +}; + +const Wrapper = styled.section` + .guti-buttons { + width: 80%; + height: 80%; + } + .gutis { + display: flex; + } + + img { + height: 100px; + width: 100px; + object-fit: cover; + animation: shake 0.5s ease-in-out infinite; + } + + .last-card { + width: 300px; + font-size: 18px; + text-align: center; + } + + .police-state-top-left img { + height: 100px; + width: 100px; + object-fit: cover; + animation: none; + } + + #shah { + height: 100%; + width: 100%; + } + + .police-state { + } + + .police-state-top { + height: 200px; + width: 350px; + display: flex; + align-items: center; + justify-content: center; + } + + .police-state-top-left { + width: 50%; + } + + .police-state-top-left img { + width: 80% !important; + height: 100%; + } + + .police-state-top-right { + width: 50%; + } + + .jayga { + margin: 10px; + margin-left: 30px; + margin-right: 30px; + } + + .police-state-btm { + height: 70px; + display: flex; + justify-content: center; + align-items: center; + } + + @media (max-width: 768px) { + #shah { + height: 200px; + width: 200px; + } + img { + height: 80px; + width: 80px; + object-fit: cover; + } + .police-state-top { + height: 80px; + width: 170px; + font-size: 10px; + } + .jayga { + margin: 10px; + } + } + @keyframes shake { + 0% { + transform: translate(0); + } + 25% { + transform: translate(0, -5px); + } + 50% { + transform: translate(0, 5px); + } + 75% { + transform: translate(0, -5px); + } + 100% { + transform: translate(0); + } + } +`; + +export default GutiButtonOnline; diff --git a/FrontendTemplate/src/components/Players.jsx b/FrontendTemplate/src/components/Players.jsx index 4454379..b7ac6fd 100644 --- a/FrontendTemplate/src/components/Players.jsx +++ b/FrontendTemplate/src/components/Players.jsx @@ -2,7 +2,13 @@ import React from "react"; import styled from "styled-components"; import avatars from "../components/avatars"; -const Players = ({ playerName, playerImage, isTopBtm, playerScore }) => { +const Players = ({ + playerName, + playerImage, + isTopBtm, + playerScore, + username, +}) => { !playerImage ? (playerImage = avatars[0]) : {}; return ( @@ -14,7 +20,12 @@ const Players = ({ playerName, playerImage, isTopBtm, playerScore }) => { {" "}
-
{playerName}
+ {username === playerName && ( +
{playerName}
+ )} + {username !== playerName && ( +
{playerName}
+ )}
{playerScore}
@@ -25,7 +36,12 @@ const Players = ({ playerName, playerImage, isTopBtm, playerScore }) => { {" "}
-
{playerName}
+ {username === playerName && ( +
{playerName}
+ )} + {username !== playerName && ( +
{playerName}
+ )}
{playerScore}
@@ -45,21 +61,28 @@ const Wrapper = styled.section` justify-content: center; } - .image { + .image { max-width: 100%; max-height: 100%; } - .r8{ + .r8 { display: flex; flex-direction: column; align-items: center; justify-content: center; font-size: 20px; - padding: 20px; + padding: 20px; } .name { - font-size: 20px; + font-size: 20px; } + + .color-name { + font-size: 20px; + font-weight: bold; + color: #1500ff; + } + @media (max-width: 768px) { .player-container { display: flex; @@ -69,15 +92,15 @@ const Wrapper = styled.section` height: 275px; } .player-container .image { - margin-top: -20px; - max-height: 70%; + margin-top: -20px; + max-height: 70%; } .player-container .r8 { - margin-top: -80px; + margin-top: -80px; } - .r8{ - margin-top: -30px; - padding: 0px; + .r8 { + margin-top: -30px; + padding: 0px; } .image { max-width: 100%; diff --git a/FrontendTemplate/src/components/ScoreModal.jsx b/FrontendTemplate/src/components/ScoreModal.jsx new file mode 100644 index 0000000..5601b37 --- /dev/null +++ b/FrontendTemplate/src/components/ScoreModal.jsx @@ -0,0 +1,44 @@ +import { Modal, Button, Form, Input, message } from "antd"; +import { useState } from "react"; + + +const ScoreModal = (props) => { + const { isGameOver, setIsGameOver, scores , finalScore, rank} = props; + + const [modaTitle, setModalTitle] = useState("Game Over"); + + + + return ( + { + setIsGameOver(false); + + }} + > + Restart + } + > + {isGameOver ?
+ {/* Display the result */} +
    + {scores.map((player, index) => ( +
  • + {`${player[0]} got ${finalScore[index]} points. Rank: ${rank[index]}`} +
  • + ))} +
+
: +

Result pending

+ } + + +
+ ); +}; + +export default ScoreModal; diff --git a/FrontendTemplate/src/components/ShakeHand.jsx b/FrontendTemplate/src/components/ShakeHand.jsx index d839b42..a16fcf4 100644 --- a/FrontendTemplate/src/components/ShakeHand.jsx +++ b/FrontendTemplate/src/components/ShakeHand.jsx @@ -5,7 +5,7 @@ import GutiButton from './GutiButton'; -const ShakeHand = () => { +const ShakeHand = ({scores, addScore, setScore, playerName}) => { const [showButton, setShowButton] = useState(true); @@ -45,7 +45,7 @@ const [showButton, setShowButton] = useState(true); return ( -
+
{showButton && } {showImage && ( - - + {setShowButton(true); setGuti(false)}}/>
)}
@@ -90,6 +89,16 @@ const Wrapper = styled.section ` transition: background-color 0.3s, transform 0.3s; } + .shakee { + width: 100%; + height: 100%; + } + + .guti-button{ + width: 100%; + height: 100%; + } + .rounded-button1:hover { background-color: #2980b9; /* Hover background color */ } diff --git a/FrontendTemplate/src/components/ShakeHandOnline.jsx b/FrontendTemplate/src/components/ShakeHandOnline.jsx new file mode 100644 index 0000000..0e0dbeb --- /dev/null +++ b/FrontendTemplate/src/components/ShakeHandOnline.jsx @@ -0,0 +1,174 @@ +import React, { useState, useEffect } from "react"; +import styled from "styled-components"; +import shake from "../assets/shuffle.gif"; +import GutiButtonOnline from "./GutiButtonOnline"; +import { message } from "antd"; + +const ShakeHandOnline = ({ + scores, + addScore, + setScore, + playerName, + socket, + username, + room, +}) => { + const [showButton, setShowButton] = useState(false); + const [showImage, setShowImage] = useState(false); + const [showGuti, setGuti] = useState(false); + const [shuffledArray, setShuffledArray] = useState([0, 1, 2, 3]); + + const shuffleArray = (array) => { + let newArray = array.slice(); // Create a copy of the original array + for (let i = newArray.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * (i + 1)); + [newArray[i], newArray[j]] = [newArray[j], newArray[i]]; + } + return newArray; + }; + + useEffect(() => { + console.log(scores[scores[0].length % 4][0]); + if (username === scores[scores[0].length % 4][0]) { + setShowButton(true); + } + }, [scores]); + + useEffect(() => { + if (socket) { + socket.on("recieve_shuffle", (curShuff) => { + setShuffledArray(curShuff); + setShowButton(false); + setShowImage(true); + + setTimeout(() => { + setShowImage(false); + setGuti(true); + }, 4200); + }); + } + return () => { + if (socket) { + socket.off("recieve_shuffle"); + } + }; + }, [socket]); + + useEffect(() => { + if (socket) { + socket.on("receive_message", (msg) => { + message.info(msg); + console.log(msg); + }); + } + return () => { + if (socket) { + socket.off("receive_message"); + } + }; + }, [socket]); + + const handleButtonClick = () => { + socket.emit("guti_shake", { + room: room, + shuffleArray: shuffleArray(shuffledArray), + }); + + // setShowButton(false); + // setShowImage(true); + + // setTimeout(() => { + // setShowImage(false); + // setGuti(true); + // }, 4200); + }; + + // useEffect(() => { + // if (showGuti) { + + // console.log('4200ms passed. Now show another div or perform other actions.'); + // } + // }, [showGuti]); + + return ( + +
+ {showButton && ( + + )} + {showImage && Displayed Image} + + {showGuti && ( +
+ { + // console.log(scores[scores[0].length % 4][0] + " vs " + username ); + // if (username === scores[scores[0].length % 4][0]) { + // setShowButton(true); + // } else setShowButton(false); + setGuti(false); + }} + /> +
+ )} +
+
+ ); +}; + +const Wrapper = styled.section` + #shaking { + height: 500px; + } + .rounded-button1 { + font-size: 20px; + height: 40px; + width: 200px; + display: flex; + justify-content: center; + align-items: center; + padding: 10px 20px; + border: none; + border-radius: 20px; + background-color: #3498db; /* Default background color */ + color: #fff; /* Default text color */ + cursor: pointer; + transition: background-color 0.3s, transform 0.3s; + } + + .shakee { + width: 100%; + height: 100%; + } + + .guti-button { + width: 100%; + height: 100%; + } + + .rounded-button1:hover { + background-color: #2980b9; /* Hover background color */ + } + + .rounded-button1:active { + transform: scale(0.95); /* Active (click) effect */ + } + + @media (max-width: 768px) { + #shaking { + height: 250px; + } + } +`; + +export default ShakeHandOnline; diff --git a/FrontendTemplate/src/components/gameControllers.js b/FrontendTemplate/src/components/gameControllers.js index 0852659..4f922d9 100644 --- a/FrontendTemplate/src/components/gameControllers.js +++ b/FrontendTemplate/src/components/gameControllers.js @@ -1,10 +1,13 @@ export function addScore(round, scores) { - var update = scores; - for (let i = 0; i < update.length; i++) { - update[i].push(round[i]); + // Create a new array by mapping over the existing scores array + const updatedScores = scores.map((score, index) => { + // Create a new array with the updated score for each player + return [...score, round[index]]; + }); + + return updatedScores; // Return the new array } - return update; -} + export function getTotalScore(scores) { const totalScore = [0, 0, 0, 0]; diff --git a/FrontendTemplate/src/pages/ai_page/AIPage.jsx b/FrontendTemplate/src/pages/ai_page/AIPage.jsx index fa1cb24..fcccd76 100644 --- a/FrontendTemplate/src/pages/ai_page/AIPage.jsx +++ b/FrontendTemplate/src/pages/ai_page/AIPage.jsx @@ -7,49 +7,146 @@ import GameBoard from "../../components/GameBoard"; import { addScore, getTotalScore } from "../../components/gameControllers"; import { useLocation } from "react-router-dom"; - +import ScoreModal from "../../components/ScoreModal"; export default function AIPage() { - const [isModalOpen, setIsModalOpen] = useState(false); + const [isGameOver, setIsGameOver] = useState(false); + const [selectedNames, setSelectedNames] = useState([]); + const [finalScore, setFinalScore] = useState([]); + const [rank, setRank] = useState([]); + const userData = useLocation().state; var initiated = false; const [scores, setScore] = useState([ - ["Amit", 0, 100, 80, 60], - ["Mehraj", 0, 100, 80, 60], - ["Shawon", 0, 100, 80, 60], - ["Nafi", 0, 100, 80, 60], + ["Amit", 0, 0, 0, 0], + ["Mehraj", 0, 0, 0, 0], + ["Shawon", 0, 0, 0, 0], + ["Nafi", 0, 0, 0, 0], ]); + const peopleNames = [ + "John", + "Jane", + "Alex", + "Mark", + "Ella", + "Liam", + "Lucy", + "Finn", + "Kate", + "Ryan", + "Emma", + "Luke", + "Rose", + "Paul", + "Lisa", + "Jack", + "Anna", + "Eric", + "Mia", + "Jake", + ]; - const round = [100, 0, 60, 40]; + const round = [100, 0, 60, 40]; var totalScore = getTotalScore(scores); - console.log(totalScore); + // console.log(totalScore); + + useEffect(() => {}, [scores]); + + useEffect(() => { + console.log("Scoreee isss: "); + // console.log(scores[0][scores[0].length - 1]); + var maxScore = Math.max(...totalScore); + if (maxScore >= 140) { + setIsGameOver(true); + console.log(isGameOver); + console.log("yes i am true"); + rankingSet(); + setFinalScore(totalScore); - function nice() { - const newScore = addScore(round, scores); - setScore(newScore); + gameOverDetails(); + } + }, [totalScore]); + + function gameOverDetails() { + var resetScores = scores.map(([name]) => [name]); + + setScore(resetScores); + } + + function rankingSet() { + var newTotal = [...totalScore]; + + var count = 1; + + var indexArray = [0, 0, 0, 0]; + + while (newTotal.some((x) => x > 0)) { + var p = newTotal.indexOf(Math.max(...newTotal)); + + indexArray[p] = count; + + newTotal[p] = 0; + + count++; + } + + setRank(indexArray); + } + + function update(new_score) { + setScore(new_score); } function initiateGame() { - setScore([[userData.username],["bot-1"],["bot-2"],["bot-3"]]); + //setScore([[userData.username], ["bot-1"], ["bot-1"],["bot-1"], ]); + const currentTimestamp = new Date().getTime(); + const randomValue = currentTimestamp % 19; + const a = peopleNames[randomValue]; + const b = peopleNames[randomValue + 1]; + const c = peopleNames[randomValue + 2]; + + setSelectedNames([userData.username, a, b, c]); + + setScore([[userData.username], [a], [b], [c]]); + initiated = true; } useEffect(() => { - if(!initiated) initiateGame(); + if (!initiated) initiateGame(); }, []); return ( <> - + {isGameOver ? ( + + ) : ( + + )} + } - onClick={() => {setIsModalOpen(true); nice()}} + onClick={() => { + setIsModalOpen(true); + }} />
- +
LEADERBOARD
diff --git a/FrontendTemplate/src/pages/friends_page/Friend_page.jsx b/FrontendTemplate/src/pages/friends_page/Friend_page.jsx index e6a0a98..4b42556 100644 --- a/FrontendTemplate/src/pages/friends_page/Friend_page.jsx +++ b/FrontendTemplate/src/pages/friends_page/Friend_page.jsx @@ -2,6 +2,7 @@ import "./Friend_page.css"; import io from "socket.io-client"; import { useState } from "react"; import Chat from "./chat.jsx"; +import RoomLobby from "./RoomLobby.jsx"; const socket = io.connect("http://localhost:3001"); @@ -12,16 +13,24 @@ function Friend_page() { const joinRoom = () => { if (username !== "" && room !== "") { + const messageData = { + room: room, + username: username, + + }; // jekono api call er jonno ei socket id "socket" or api address ta lagbe. - socket.emit("join_room", room); // "join_room" api link er sathe value send korbe + socket.emit("join_room", messageData); // "join_room" api link er sathe value send korbe setShowChat(true); + + } }; + return (
- {!showChat ? ( -
+ +

Join A Chat

+ {!showChat ? ( +
) : ( - + )}
); diff --git a/FrontendTemplate/src/pages/friends_page/FriendsGame.css b/FrontendTemplate/src/pages/friends_page/FriendsGame.css new file mode 100644 index 0000000..872ff32 --- /dev/null +++ b/FrontendTemplate/src/pages/friends_page/FriendsGame.css @@ -0,0 +1,46 @@ +.ai-canvas { + width: 100vw; + height: 100vh; + display: flex; +} + +.ai-left { + width: 75vw; + height: 100%; +} + +.ai-right { + text-align: center; + width: 25vw; + background-color: rgb(209, 209, 209); +} + +.leaderboard-body { + width: 100%; + display: flex; +} + +.leaderboard-body::-webkit-scrollbar { + display: none; +} + +.leaderboard-col { + width: 25%; + height: 100%; + border: 1px solid black; +} + +@media (max-width: 768px) { + .ai-canvas{ + flex-direction: column; + } + + .ai-left{ + width: 100vw; + height: 75vh; + } + + .ai-right { + width: 100vw; + } +} \ No newline at end of file diff --git a/FrontendTemplate/src/pages/friends_page/FriendsGame.jsx b/FrontendTemplate/src/pages/friends_page/FriendsGame.jsx new file mode 100644 index 0000000..db8d9d7 --- /dev/null +++ b/FrontendTemplate/src/pages/friends_page/FriendsGame.jsx @@ -0,0 +1,144 @@ +import "../ai_page/AIPage.css"; +import { FloatButton } from "antd"; +import { CommentOutlined } from "@ant-design/icons"; +import ChatModal from "../../components/ChatModal"; +import { useEffect, useState } from "react"; +import GameBoardOnline from "../../components/GameBoardOnline"; +import ScrollToBottom from "react-scroll-to-bottom"; +import { addScore, getTotalScore } from "../../components/gameControllers"; +import { useLocation } from "react-router-dom"; +import ScoreModal from "../../components/ScoreModal"; + +export default function FriensGame({ usernames, socket, username, room }) { + const [isModalOpen, setIsModalOpen] = useState(false); + const [selectedNames, setSelectedNames] = useState([]); + const [isGameOver, setIsGameOver] = useState(false); + const [rank, setRank] = useState([]); + const [finalScore, setFinalScore] = useState([]); + const userData = useLocation().state; + userData.username = username; + userData.avatar = 1; + var initiated = false; + + const [scores, setScore] = useState([ + [usernames[0], 0, 0, 0, 0], + [usernames[1], 0, 0, 0, 0], + [usernames[2], 0, 0, 0, 0], + [usernames[3], 0, 0, 0, 0], + ]); + + var totalScore = getTotalScore(scores); + + function initiateGame() { + const newScore = [ + [usernames[0]], + [usernames[1]], + [usernames[2]], + [usernames[3]], + ]; + setScore(newScore); + console.log(usernames); + console.log(scores); + console.log(newScore); + + initiated = true; + } + + useEffect(() => { + if (!initiated) initiateGame(); + }, []); + + useEffect(() => { + console.log("Scoreee isss: "); + // console.log(scores[0][scores[0].length - 1]); + var maxScore = Math.max(...totalScore); + if (maxScore >= 140) { + setIsGameOver(true); + console.log(isGameOver); + console.log("yes i am true"); + rankingSet(); + setFinalScore(totalScore); + + gameOverDetails(); + } + }, [totalScore]); + + function gameOverDetails() { + var resetScores = scores.map(([name]) => [name]); + + setScore(resetScores); + } + + function rankingSet() { + var newTotal = [...totalScore]; + + var count = 1; + + var indexArray = [0, 0, 0, 0]; + + while (newTotal.some((x) => x > 0)) { + var p = newTotal.indexOf(Math.max(...newTotal)); + + indexArray[p] = count; + + newTotal[p] = 0; + + count++; + } + + setRank(indexArray); + } + + return ( + <> + {isGameOver ? ( + + ) : ( + + )} + } + onClick={() => { + setIsModalOpen(true); + }} + /> +
+
+ +
+
+
LEADERBOARD
+ +
+ {scores.map((score, index) => ( +
+ {score.map((point, idx) => ( + + {point} +
+
+ ))} +
+ ))} +
+
+
+
+ + ); +} diff --git a/FrontendTemplate/src/pages/friends_page/FriendsPage.jsx b/FrontendTemplate/src/pages/friends_page/FriendsPage.jsx new file mode 100644 index 0000000..8cd7be1 --- /dev/null +++ b/FrontendTemplate/src/pages/friends_page/FriendsPage.jsx @@ -0,0 +1,78 @@ +import io from "socket.io-client"; +import { useState } from "react"; +import appLogo from "../../assets/appLogo.png"; +import avatars from "../../components/avatars"; +import { Input, Button } from "antd"; +import { useLocation, useNavigate } from "react-router-dom"; +import RoomLobby from "./RoomLobby"; + +const socket = io.connect("http://localhost:3001"); + +function FriendsPage() { + // const [username, setUsername] = useState(""); + const [room, setRoom] = useState(""); + const [showChat, setShowChat] = useState(false); + const userData = useLocation().state; + const navigate = useNavigate(); + + const joinRoom = () => { + if (userData.username !== "" && room !== "") { + const messageData = { + room: room, + username: userData.username, + }; + // jekono api call er jonno ei socket id "socket" or api address ta lagbe. + socket.emit("join_room", messageData); // "join_room" api link er sathe value send korbe + setShowChat(true); + + + } + }; + + return ( + <> + {!showChat ? ( +
+
+ Chor Dakat Babu Police +
+
+
+ avatar +
+
+ {userData.username} +
+ setRoom(e.target.value)} + /> + +
+ +
+
+ ) : ( + + )} + + + + ); +} + +export default FriendsPage; diff --git a/FrontendTemplate/src/pages/friends_page/RoomLobby.jsx b/FrontendTemplate/src/pages/friends_page/RoomLobby.jsx new file mode 100644 index 0000000..5a0c80f --- /dev/null +++ b/FrontendTemplate/src/pages/friends_page/RoomLobby.jsx @@ -0,0 +1,112 @@ +import React, { useEffect, useState } from "react"; +import ScrollToBottom from "react-scroll-to-bottom"; +import styled from "styled-components"; +import "../multiplayer_page/Lobby.css"; +import avatars from "../../components/avatars"; +import { Button } from "antd"; +import { useLocation, useNavigate } from "react-router-dom"; +import FriensGame from "./FriendsGame"; + +const RoomLobby = ({ socket, username, room }) => { + const [currentMessage, setCurrentMessage] = useState(""); + const [messageList, setMessageList] = useState([]); + const [userval, setUserVal] = useState(false); + const [users, setUsers] = useState([]); + const [player2, setPlayer2] = useState("Player 2"); + const [player3, setPlayer3] = useState("Player 3"); + const [player4, setPlayer4] = useState("Player 4"); + const [gameStart, SetGameStart] = useState(false); + + const userData = useLocation().state; + var usernames; + const navigate = useNavigate(); + const [players, setPlayers] = useState([ + { avatar: 1, username: username, isHost: true }, + { avatar: 2, username: player2, isHost: false }, + { avatar: 3, username: player3, isHost: false }, + { avatar: 4, username: player4, isHost: false }, + ]); + const gameStarted = () => { + if (users.length < 4) { + alert("You need 4 players to start"); + return; + } + + usernames = users.map((user) => user.username); + console.log("notified!"); + socket.emit("notify_others_to_start", { room: room }); + SetGameStart(true); + // Navigate to another page and pass usernames as state + // user data contains room and username + }; + + const exitLobby = () => { + socket.emit("berhoa", { roomId: room }); + navigate("/home", { + state: { + username: userData.username, + }, + }); + }; + + useEffect(() => { + if (socket) { + socket.on("users_list", (users) => { + console.log(users.length); + + if (users.length <= 4) { + // setPlayer2( users[1].username); + // console.log(player2); + + setUsers(users); + } + }); + socket.on("start_game", (flag) => { + if (flag) SetGameStart(true); + }); + } + return () => { + if (socket) { + socket.off("users_list"); + } + }; + }, [socket]); + + return ( + <> + {gameStart && ( + user.username)} socket={socket} username={username} room = {room}/> + )} + {!gameStart && ( +
+ {" "} +
LOBBY CODE
+
{room}
+
+ {users.map((messageContent, index) => { + return ( +
+ + {messageContent.username} +
+ ); + })} +
+ {console.log(users)} + {users.length > 0 && users[0].username === userData.username && ( +
+ +
+ )} + {users.length > 0 && users[0].username !== userData.username && ( +
+ +
+ )} +
+ )} + + ); +}; + +export default RoomLobby; diff --git a/FrontendTemplate/src/pages/friends_page/chat.jsx b/FrontendTemplate/src/pages/friends_page/chat.jsx index 00b07e4..1c1d75d 100644 --- a/FrontendTemplate/src/pages/friends_page/chat.jsx +++ b/FrontendTemplate/src/pages/friends_page/chat.jsx @@ -27,14 +27,14 @@ function Chat({ socket, username, room }) { useEffect(() => { - socket.emit("my_room", { room, username }); + socket.on("receive_message", (data) => { setMessageList((list) => [...list, data]); }); return () => socket.removeListener('receive_message') - }, [socket, room, username]); + }, [socket]); return ( diff --git a/FrontendTemplate/src/pages/multiplayer_page/DummyLobby.jsx b/FrontendTemplate/src/pages/multiplayer_page/DummyLobby.jsx new file mode 100644 index 0000000..964fc8a --- /dev/null +++ b/FrontendTemplate/src/pages/multiplayer_page/DummyLobby.jsx @@ -0,0 +1,47 @@ +import React from 'react'; +import io from "socket.io-client"; +import { useState } from "react"; +const socket = io.connect("http://localhost:3001"); + +const DummyLobby = () => { + + const [username, setUsername] = useState(""); + const [room, setRoom] = useState(""); + const [showChat, setShowChat] = useState(false); + + const joinRoom = () => { + if (username !== "" && room !== "") { + + socket.emit("join_room", room); + setShowChat(true); + } + }; + + + return ( +
+

Join A Game Lobby

+ { + setUsername(event.target.value); + }} + /> + { + setRoom(event.target.value); + }} + /> + + + {!ShowChat ?
Hello
:
Nice
+ + } +
+ ) +} + +export default DummyLobby; \ No newline at end of file diff --git a/FrontendTemplate/src/pages/multiplayer_page/Lobby.css b/FrontendTemplate/src/pages/multiplayer_page/Lobby.css new file mode 100644 index 0000000..604fba2 --- /dev/null +++ b/FrontendTemplate/src/pages/multiplayer_page/Lobby.css @@ -0,0 +1,37 @@ +.lobby-container{ + display: flex; + justify-content: space-evenly; + align-items: center; + flex-wrap: wrap; + +} + +.lobby-card{ + width: 20vw; + height: 75vh; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} + +.lobby-card img { + width: 100%; +} + +.lobby-card span { + margin-top: -40px; + font-size: 20px; +} + +.lobby-code { + font-size: 25px; +} + +@media screen and (max-width: 768px) { + .lobby-card{ + width: 40vw; + height: 40vh; + margin: 10px; + } +} \ No newline at end of file diff --git a/FrontendTemplate/src/pages/multiplayer_page/Lobby.jsx b/FrontendTemplate/src/pages/multiplayer_page/Lobby.jsx new file mode 100644 index 0000000..3dea167 --- /dev/null +++ b/FrontendTemplate/src/pages/multiplayer_page/Lobby.jsx @@ -0,0 +1,43 @@ +import "./Lobby.css"; +import avatars from "../../components/avatars"; +import { Button } from "antd"; +import { useLocation, useNavigate } from "react-router-dom"; +import { useState, useEffect } from "react"; + +const Lobby = ({ socket, username, room }) => { + + const userData = useLocation().state; + const navigate = useNavigate(); + const [users, setUsers] = useState([]); + + const [players , setPlayers] = useState([ + + {avatar: 1, username: username, isHost: true}, + {avatar: 2, username: "amit", isHost: false}, + {avatar: 3, username: "sakib", isHost: false}, + {avatar: 4, username: "akib", isHost: false}, + + ]); + + return ( + <> +
LOBBY CODE
+
{room}
+
+ {players.map((player) => { + return
{player.username} + {!player.isHost && () }
; + })} +
+
+ + ) + +} + +export default Lobby \ No newline at end of file diff --git a/FrontendTemplate/src/pages/multiplayer_page/Multiplayer.css b/FrontendTemplate/src/pages/multiplayer_page/Multiplayer.css new file mode 100644 index 0000000..e69de29 diff --git a/FrontendTemplate/src/pages/multiplayer_page/Multiplayer.jsx b/FrontendTemplate/src/pages/multiplayer_page/Multiplayer.jsx new file mode 100644 index 0000000..824fb25 --- /dev/null +++ b/FrontendTemplate/src/pages/multiplayer_page/Multiplayer.jsx @@ -0,0 +1,71 @@ +import "./Multiplayer.css"; +import { FloatButton } from "antd"; +import { CommentOutlined } from "@ant-design/icons"; +import ChatModal from "../../components/ChatModal"; +import { useEffect, useState } from "react"; +import GameBoard from "../../components/GameBoard"; + +import { addScore, getTotalScore } from "../../components/gameControllers"; +import { useLocation } from "react-router-dom"; + +export default function Multiplayer() { + const [isModalOpen, setIsModalOpen] = useState(false); + const userData = useLocation().state; + var initiated = false; + + const [scores, setScore] = useState([ + ["Player 1", 0, 100, 80, 60], + ["Player 2", 0, 100, 80, 60], + ["Shawon", 0, 100, 80, 60], + ["Nafi", 0, 100, 80, 60], + ]); + + const round = [100, 0, 60, 40]; + var totalScore = getTotalScore(scores); + console.log(totalScore); + + useEffect(()=>{ + console.log("rerender"); + }, [scores]); + + function initiateGame() { + setScore([[userData.username], ["bot-1"], ["bot-2"], ["bot-3"]]); + initiated = true; + } + + useEffect(() => { + if (!initiated) initiateGame(); + }, []); + + return ( + <> + + } + onClick={() => { + setIsModalOpen(true); + }} + /> +
+
+ +
+
+
LEADERBOARD
+
+ {scores.map((score, index) => ( +
+ {score.map((point, idx) => ( + + {point} +
+
+ ))} +
+ ))} +
+
+
+ + ); +} diff --git a/FrontendTemplate/src/routes/routesLib.jsx b/FrontendTemplate/src/routes/routesLib.jsx index c394c83..663c350 100644 --- a/FrontendTemplate/src/routes/routesLib.jsx +++ b/FrontendTemplate/src/routes/routesLib.jsx @@ -4,6 +4,10 @@ import LandingPage from "../pages/landing_page/LandingPage"; import HomePage from "../pages/home_page/HomePage"; import AIPage from "../pages/ai_page/AIPage"; import Friend_page from "../pages/friends_page/Friend_page"; +import FriendsPage from "../pages/friends_page/FriendsPage"; +import Multiplayer from "../pages/multiplayer_page/Multiplayer"; +import Lobby from "../pages/multiplayer_page/Lobby"; +import FriensGame from "../pages/friends_page/FriendsGame"; function RoutesLib() { return ( @@ -13,7 +17,9 @@ function RoutesLib() { } /> } /> } /> - } /> + } /> + } /> + } /> diff --git a/README.md b/README.md index 1e968ca..98d5c9b 100644 --- a/README.md +++ b/README.md @@ -1 +1,3 @@ -# ChorPolice +# Chor Dakat Babu Police + +Chor Dakat Babu Police is a game which is created using Express, Socket IO and React. pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy