diff --git a/paras/public/favicon.ico b/paras/public/favicon.ico deleted file mode 100644 index a11777c..0000000 Binary files a/paras/public/favicon.ico and /dev/null differ diff --git a/paras/src/App.css b/paras/src/App.css index 334c2de..85edc5b 100644 --- a/paras/src/App.css +++ b/paras/src/App.css @@ -74,6 +74,12 @@ background-color: #f2f2f2; padding: 10px; text-align: center; + color: black; +} + +.dark .footer { + background-color: #444; + color: white; } .dark { diff --git a/paras/src/App.js b/paras/src/App.js index 7c07716..cf7e2ef 100644 --- a/paras/src/App.js +++ b/paras/src/App.js @@ -8,80 +8,125 @@ const App = () => { const [currentPlayer, setCurrentPlayer] = useState('X'); const [winner, setWinner] = useState(null); const [isDarkMode, setIsDarkMode] = useState(false); - + const [isDraw, setIsDraw] = useState(false); + const [moveHistory, setMoveHistory] = useState([]); + const [scores, setScores] = useState({ X: 0, O: 0 }); + const [winningCombination, setWinningCombination] = useState([]); + const handleCellClick = (index) => { if (board[index] || winner) return; + const newBoard = [...board]; newBoard[index] = currentPlayer; setBoard(newBoard); - checkWinner(newBoard, currentPlayer); - setCurrentPlayer(currentPlayer === 'X' ? 'O' : 'X'); + setMoveHistory([...moveHistory, { player: currentPlayer, move: index }]); + + if (!checkWinner(newBoard, currentPlayer)) { + if (newBoard.every((cell) => cell !== null)) { + setIsDraw(true); + } else { + setCurrentPlayer(currentPlayer === 'X' ? 'O' : 'X'); + } + } }; const checkWinner = (board, player) => { const winningCombinations = [ [0, 1, 2], [3, 4, 5], [6, 7, 8], // rows [0, 3, 6], [1, 4, 7], [2, 5, 8], // columns - [0, 4, 8], [2, 4, 6] // diagonals + [0, 4, 8], [2, 4, 6], // diagonals ]; for (let combination of winningCombinations) { const [a, b, c] = combination; if (board[a] === player && board[b] === player && board[c] === player) { setWinner(player); - return; + setWinningCombination(combination); + setScores((prevScores) => ({ ...prevScores, [player]: prevScores[player] + 1 })); + return true; } } + return false; }; const resetGame = () => { - setBoard(initialBoard); - setCurrentPlayer('X'); - setWinner(null); + if (window.confirm('Are you sure you want to restart the game?')) { + setBoard(initialBoard); + setCurrentPlayer('X'); + setWinner(null); + setIsDraw(false); + setMoveHistory([]); + setWinningCombination([]); + } + }; + + const toggleTheme = () => { + setIsDarkMode((prevMode) => !prevMode); }; const renderCell = (index) => { const value = board[index]; + const isWinningCell = winningCombination.includes(index); + return ( -
handleCellClick(index)}> - {value} +
handleCellClick(index) } + role="button" + tabIndex={ 0 } + aria-label={ `cell-${index}` } + onKeyDown={ (e) => e.key === 'Enter' && handleCellClick(index) } + > + { value }
); }; - const toggleTheme = () =>{ - setIsDarkMode(prevMode => !prevMode); - }; - return ( -
+

Tic Tac Toe

+
+ +
+
- +
+

Player X: { scores.X } Wins

+

Player O: { scores.O } Wins

- {board.map((cell, index) => ( -
handleCellClick(index)} - > - {cell} -
- ))} + { board.map((_, index) => renderCell(index)) }
- - {winner && ( + + { winner && ( +
+

Player { winner } wins!

+ +
+ ) } + + { isDraw && !winner && (
-

Player {winner} wins!

- +

It's a draw!

+
- )} + ) } + +
+

Move History

+
    + { moveHistory.map((move, index) => ( +
  • + Player { move.player } moved to position { move.move + 1 } +
  • + )) } +
+

Rules

    @@ -91,7 +136,7 @@ const App = () => {
-

© 2023 TIC TAC TOE . All rights reserved.

+

© 2024 TIC TAC TOE. All rights reserved.

); diff --git a/paras/src/logo.svg b/paras/src/logo.svg deleted file mode 100644 index 9dfc1c0..0000000 --- a/paras/src/logo.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file