diff --git a/bun.lockb b/bun.lockb index ba3c7a3..ca330bd 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index 058ce8c..c2c82cb 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,9 @@ }, "dependencies": { "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-dom": "^18.2.0", + "react-icons": "^5.0.1", + "recoil": "^0.7.7" }, "devDependencies": { "@types/react": "^18.2.66", @@ -19,9 +21,12 @@ "@typescript-eslint/eslint-plugin": "^7.2.0", "@typescript-eslint/parser": "^7.2.0", "@vitejs/plugin-react-swc": "^3.5.0", + "autoprefixer": "^10.4.19", "eslint": "^8.57.0", "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-refresh": "^0.4.6", + "postcss": "^8.4.38", + "tailwindcss": "^3.4.3", "typescript": "^5.2.2", "vite": "^5.2.0" } diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..2e7af2b --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,6 @@ +export default { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} diff --git a/src/App.css b/src/App.css index b9d355d..e69de29 100644 --- a/src/App.css +++ b/src/App.css @@ -1,42 +0,0 @@ -#root { - max-width: 1280px; - margin: 0 auto; - padding: 2rem; - text-align: center; -} - -.logo { - height: 6em; - padding: 1.5em; - will-change: filter; - transition: filter 300ms; -} -.logo:hover { - filter: drop-shadow(0 0 2em #646cffaa); -} -.logo.react:hover { - filter: drop-shadow(0 0 2em #61dafbaa); -} - -@keyframes logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } -} - -@media (prefers-reduced-motion: no-preference) { - a:nth-of-type(2) .logo { - animation: logo-spin infinite 20s linear; - } -} - -.card { - padding: 2em; -} - -.read-the-docs { - color: #888; -} diff --git a/src/App.tsx b/src/App.tsx index afe48ac..e2b60e6 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,35 +1,24 @@ -import { useState } from 'react' -import reactLogo from './assets/react.svg' -import viteLogo from '/vite.svg' -import './App.css' +import { useState } from "react"; +import PlayerInfo from "./Components/PlayerInfo"; +import Board from "./Components/Board"; +import Dice from "./Components/Dice"; function App() { - const [count, setCount] = useState(0) - return ( <> -
- - Vite logo - - - React logo - -
-

Vite + React

-
- -

- Edit src/App.tsx and save to test HMR -

+
+
+ +
+
+ +
+
+ +
-

- Click on the Vite and React logos to learn more -

- ) + ); } -export default App +export default App; diff --git a/src/Components/Board.tsx b/src/Components/Board.tsx new file mode 100644 index 0000000..d0861d5 --- /dev/null +++ b/src/Components/Board.tsx @@ -0,0 +1,7 @@ +import React from "react"; + +const Board = () => { + return
Board
; +}; + +export default Board; diff --git a/src/Components/Dice.tsx b/src/Components/Dice.tsx new file mode 100644 index 0000000..58c7b3b --- /dev/null +++ b/src/Components/Dice.tsx @@ -0,0 +1,67 @@ +import React from "react"; +import { useRecoilState } from "recoil"; +import { diceValue } from "../states/DiceStates"; +import { diceRoll, DiceValToIconMap } from "../Utils"; +import { + currentPlayer, + gameLogs, + gameState, + playerPositions, +} from "../states/BoardStates"; + +const Dice = () => { + const [diceVal, setDiceVal] = useRecoilState(diceValue); + const [gameLog, setGameLog] = useRecoilState(gameLogs); + const [currPlayer, setCurrPlayer] = useRecoilState(currentPlayer); + const [playerPos, setPlayerPos] = useRecoilState(playerPositions); + const [gState, setGState] = useRecoilState(gameState); + + const rollDice = () => { + const newVal = diceRoll(); + const newPlayer = currPlayer === 1 ? 2 : 1; + const isPlayerFree = newVal === 6; + setDiceVal(newVal); + setGameLog([ + ...gameLog, + `Player ${currPlayer} Rolled Dice to ${newVal}`, + ...(isPlayerFree ? [`Player ${currPlayer} is Free to Move`] : []), + `Player ${newPlayer}'s Turn`, + ]); + setCurrPlayer(newPlayer); + setPlayerPos({ + player1: + currPlayer === 1 && isPlayerFree && !gState["player1"].move + ? newVal + : gState["player1"].move && currPlayer === 1 + ? playerPos.player1 + newVal + : playerPos.player1, + player2: + currPlayer === 2 && isPlayerFree && !gState["player2"].move + ? newVal + : gState["player2"].move && currPlayer === 2 + ? playerPos.player2 + newVal + : playerPos.player2, + }); + if (isPlayerFree) { + setGState({ ...gState, [`player${currPlayer}`]: { move: true } }); + } else { + setGState({ ...gState, global: "started" }); + } + console.log("Game states", gState); + }; + + return ( +
+
+
+ {DiceValToIconMap[diceVal]} +
+
+
+ Click to Roll Dice +
+
+ ); +}; + +export default Dice; diff --git a/src/Components/PlayerInfo.tsx b/src/Components/PlayerInfo.tsx new file mode 100644 index 0000000..fbf656d --- /dev/null +++ b/src/Components/PlayerInfo.tsx @@ -0,0 +1,23 @@ +import React from "react"; +import { useRecoilState, useRecoilValue } from "recoil"; +import { gameLogs, playerPositions } from "../states/BoardStates"; + +const PlayerInfo = () => { + const [playerPos, setPlayerPos] = useRecoilState(playerPositions); + const gLogs = useRecoilValue(gameLogs); + return ( +
+

Game Logs

+
+ {gLogs?.map((log) => ( +

{log}

+ ))} +
+

Player Positions

+

Player 1 :- {playerPos.player1}

+

Player 2 :- {playerPos.player2}

+
+ ); +}; + +export default PlayerInfo; diff --git a/src/Utils/index.tsx b/src/Utils/index.tsx new file mode 100644 index 0000000..66f2b07 --- /dev/null +++ b/src/Utils/index.tsx @@ -0,0 +1,21 @@ +import { IoDice } from "react-icons/io5"; +import { FaDiceOne } from "react-icons/fa6"; +import { FaDiceTwo } from "react-icons/fa6"; +import { FaDiceThree } from "react-icons/fa6"; +import { FaDiceFour } from "react-icons/fa"; +import { FaDiceFive } from "react-icons/fa"; +import { FaDiceSix } from "react-icons/fa6"; + +export const DiceValToIconMap = { + 0: , + 1: , + 2: , + 3: , + 4: , + 5: , + 6: , +}; + +export const diceRoll = () => { + return Math.trunc(Math.random() * 6 + 1); +}; diff --git a/src/index.css b/src/index.css index 6119ad9..bd6213e 100644 --- a/src/index.css +++ b/src/index.css @@ -1,68 +1,3 @@ -:root { - font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; - line-height: 1.5; - font-weight: 400; - - color-scheme: light dark; - color: rgba(255, 255, 255, 0.87); - background-color: #242424; - - font-synthesis: none; - text-rendering: optimizeLegibility; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -a { - font-weight: 500; - color: #646cff; - text-decoration: inherit; -} -a:hover { - color: #535bf2; -} - -body { - margin: 0; - display: flex; - place-items: center; - min-width: 320px; - min-height: 100vh; -} - -h1 { - font-size: 3.2em; - line-height: 1.1; -} - -button { - border-radius: 8px; - border: 1px solid transparent; - padding: 0.6em 1.2em; - font-size: 1em; - font-weight: 500; - font-family: inherit; - background-color: #1a1a1a; - cursor: pointer; - transition: border-color 0.25s; -} -button:hover { - border-color: #646cff; -} -button:focus, -button:focus-visible { - outline: 4px auto -webkit-focus-ring-color; -} - -@media (prefers-color-scheme: light) { - :root { - color: #213547; - background-color: #ffffff; - } - a:hover { - color: #747bff; - } - button { - background-color: #f9f9f9; - } -} +@tailwind base; +@tailwind components; +@tailwind utilities; \ No newline at end of file diff --git a/src/main.tsx b/src/main.tsx index 3d7150d..f9017a8 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,10 +1,13 @@ -import React from 'react' -import ReactDOM from 'react-dom/client' -import App from './App.tsx' -import './index.css' +import React from "react"; +import ReactDOM from "react-dom/client"; +import App from "./App.tsx"; +import "./index.css"; +import { RecoilRoot } from "recoil"; -ReactDOM.createRoot(document.getElementById('root')!).render( +ReactDOM.createRoot(document.getElementById("root")!).render( - - , -) + + + + +); diff --git a/src/states/BoardStates.ts b/src/states/BoardStates.ts new file mode 100644 index 0000000..64406a1 --- /dev/null +++ b/src/states/BoardStates.ts @@ -0,0 +1,32 @@ +import { atom } from "recoil"; + +export const playerPositions = atom({ + key: "playerPositions", + default: { + player1: 0, + player2: 0, + }, +}); + +export const gameLogs = atom({ + key: "gameLogs", + default: ["Player 1 Click Dice to Start Game"], +}); + +export const currentPlayer = atom({ + key: "currentPlayer", + default: 1, +}); + +export const gameState = atom({ + key: "gameState", + default: { + global: "notStarted", // notStarted || started || over + player1: { + move: false, + }, + player2: { + move: false, + }, + }, +}); diff --git a/src/states/DiceStates.ts b/src/states/DiceStates.ts new file mode 100644 index 0000000..9504c12 --- /dev/null +++ b/src/states/DiceStates.ts @@ -0,0 +1,6 @@ +import { atom } from "recoil"; + +export const diceValue = atom({ + key: "diceValue", + default: 0, +}); diff --git a/tailwind.config.js b/tailwind.config.js new file mode 100644 index 0000000..614c86b --- /dev/null +++ b/tailwind.config.js @@ -0,0 +1,8 @@ +/** @type {import('tailwindcss').Config} */ +export default { + content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"], + theme: { + extend: {}, + }, + plugins: [], +};