From 0f447ad545a178f8e102f456822788b9442b1605 Mon Sep 17 00:00:00 2001 From: Hadeed Ahmad Date: Mon, 3 Jun 2024 19:52:17 +0400 Subject: [PATCH] bg of winning tiles --- src/game.jsx | 100 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 69 insertions(+), 31 deletions(-) diff --git a/src/game.jsx b/src/game.jsx index 16b1d16..7069fde 100644 --- a/src/game.jsx +++ b/src/game.jsx @@ -1,5 +1,5 @@ import { useImmer } from "use-immer"; -import { useState } from "react"; +import { useState, useEffect } from "react"; import Cross from "../assets/icon-x.svg?react"; import CrossOutline from "../assets/icon-x-outline.svg?react"; @@ -11,7 +11,7 @@ import restart from "../assets/icon-restart.svg"; import { restartGame } from "./store"; import Modal from "./modal"; -const getWinner = (grid) => { +const getWinningCombo = (grid) => { const combos = [ [0, 1, 2], [3, 4, 5], @@ -29,51 +29,89 @@ const getWinner = (grid) => { return symbols.every((symbol) => symbol == symbols[0] && symbol != ""); }; - const winningCombo = combos.find(wins); - - if (winningCombo) { - return grid[winningCombo[0]]; - } - - return ""; + return combos.find(wins) || []; }; -export default ({ players: _players }) => { +export default ({ players }) => { const [score, updateScore] = useImmer({ X: 0, O: 0, ties: 0 }); - const [grid, updateGrid] = useImmer(Array(9).fill("")); - const [modal, setModal] = useState(false); + + const [restartModal, setRestartModal] = useState(false); + const [roundModal, setRoundModal] = useState(false); const turn = grid.filter((s) => s == "").length % 2 != 0 ? "X" : "O"; const TurnOutline = turn == "X" ? CrossOutline : OvalOutline; const TurnIndicator = turn == "X" ? Cross : Oval; - const winner = getWinner(grid); - if (winner) { - updateScore((score) => { - score[winner]++; - }); + const winningCombo = getWinningCombo(grid); + const winner = winningCombo.length > 0 ? grid[winningCombo[0]] : null; - updateGrid(() => Array(9).fill("")); - } + const cpuTurn = players[turn] == "CPU"; - const renderSymbol = (symbol) => { + useEffect(() => { + if (winner) { + const timeoutId = setTimeout(() => { + updateScore((score) => { + score[winner]++; + }); + + updateGrid(() => Array(9).fill("")); + }, 1000); + + return () => clearTimeout(timeoutId); + } + }, [winner]); + + useEffect(() => { + if (cpuTurn && !winner && grid.filter((s) => s == "").length > 0) { + const timeoutId = setTimeout(() => { + updateGrid((grid) => { + const free = Array.from({ length: 9 }, (_, i) => i).filter( + (i) => grid[i] == "", + ); + + const choice = free[Math.floor(Math.random() * free.length)]; + grid[choice] = turn; + }); + }, 750); + + return () => clearTimeout(timeoutId); + } + }, [cpuTurn]); + + const renderSymbol = (symbol, index) => { if (symbol == "") { - let colorClass = turn == "X" ? "text-blue-700" : "text-yellow-700"; + const colorClass = turn == "X" ? "text-blue-700" : "text-yellow-700"; return ( ); } - let Symbol = symbol == "X" ? Cross : Oval; + const Symbol = symbol == "X" ? Cross : Oval; let colorClass = symbol == "X" ? "text-blue-700" : "text-yellow-700"; + if (winner && winningCombo.includes(index)) { + colorClass = "text-navy-400"; + } + return ; }; + const boxBackground = (index) => { + if (winner && winningCombo.includes(index)) { + if (winner == "X") { + return "bg-blue-400 inner-shadow-2-blue-900"; + } else { + return "bg-yellow-400 inner-shadow-2-yellow-900"; + } + } + + return "bg-navy-400 inner-shadow-2-navy-900"; + }; + return ( <>
@@ -89,7 +127,7 @@ export default ({ players: _players }) => {
))}
-

X ({_players.X})

+

X ({players.X})

{score.X}

@@ -124,16 +162,16 @@ export default ({ players: _players }) => {

{score.ties}

-

O ({_players.O})

+

O ({players.O})

{score.O}

{ - setModal(false); + setRestartModal(false); }} >

Restart game?