import React, { useState, useEffect, useCallback, useContext } from 'react'; import { Link } from 'react-router-dom'; import { ArrowLeftIcon, ArrowCounterClockwiseIcon, CircleIcon, TrophyIcon, UsersIcon, GridNineIcon, } from '@phosphor-icons/react'; import { motion, AnimatePresence } from 'framer-motion'; import { ToastContext } from '../../context/ToastContext'; import Seo from '../../components/Seo'; import GenerativeArt from '../../components/GenerativeArt'; import BreadcrumbTitle from '../../components/BreadcrumbTitle'; const ConnectFourPage = () => { const appName = 'Connect Four'; const { addToast } = useContext(ToastContext); const [board, setBoard] = useState(() => Array(6) .fill(null) .map(() => Array(7).fill(0)), ); // 6 rows, 7 columns const [currentPlayer, setCurrentPlayer] = useState(1); // 1 for Player 1 (Emerald), 2 for Player 2 (White) const [winner, setWinner] = useState(null); // null, 1, 2, or 'Draw' const [winningCells, setWinningCells] = useState([]); const initializeBoard = useCallback(() => { const newBoard = Array(6) .fill(null) .map(() => Array(7).fill(0)); setBoard(newBoard); setCurrentPlayer(1); setWinner(null); setWinningCells([]); }, []); useEffect(() => { initializeBoard(); }, [initializeBoard]); const checkWin = (currentBoard, row, col, player) => { const directions = [ [0, 1], // horizontal [1, 0], // vertical [1, 1], // diagonal down-right [1, -1], // diagonal down-left ]; for (const [dr, dc] of directions) { let count = 1; let cells = [[row, col]]; // Check one direction for (let i = 1; i < 4; i++) { const r = row + dr * i; const c = col + dc * i; if ( r >= 0 && r < 6 && c >= 0 && c < 7 && currentBoard[r][c] === player ) { count++; cells.push([r, c]); } else { break; } } // Check opposite direction for (let i = 1; i < 4; i++) { const r = row - dr * i; const c = col - dc * i; if ( r >= 0 && r < 6 && c >= 0 && c < 7 && currentBoard[r][c] === player ) { count++; cells.push([r, c]); } else { break; } } if (count >= 4) { return cells; } } return null; }; const handleColumnClick = (colIndex) => { if (winner) return; const newBoard = board.map((row) => [...row]); let rowIndex = -1; for (let r = 5; r >= 0; r--) { if (newBoard[r][colIndex] === 0) { newBoard[r][colIndex] = currentPlayer; rowIndex = r; break; } } if (rowIndex === -1) { addToast({ message: 'Column is full.', type: 'error', }); return; } setBoard(newBoard); const winResult = checkWin(newBoard, rowIndex, colIndex, currentPlayer); if (winResult) { setWinner(currentPlayer); setWinningCells(winResult); addToast({ message: `PLAYER_${currentPlayer === 1 ? 'EMERALD' : 'WHITE'} WINS!`, type: 'success', }); } else if (newBoard.every((row) => row.every((cell) => cell !== 0))) { setWinner('Draw'); addToast({ message: "IT'S A DRAW!", type: 'warning' }); } else { setCurrentPlayer(currentPlayer === 1 ? 2 : 1); } }; return (
{/* Header Section */}
Applications

Classic strategy board game. Align four segments to{' '} dominate.

Active_Player {currentPlayer === 1 ? 'EMERALD' : 'WHITE'}
Game_Status {winner ? winner === 'Draw' ? 'DRAW' : 'GAME_OVER' : 'PLAYING'}
{/* Controls Column */}

Player_Info

Player 01
EMERALD_CORP
Player 02
WHITE_NULL
{winner && (
{winner === 'Draw' ? 'Match Draw' : `Winner: Player ${winner === 1 ? '01' : '02'}`}
)}

Game_Tactics

  • 01 Connect four pieces in any direction.
  • 02 Block your opponent's progression.
  • 03 Gravity applies: pieces fall to the lowest spot.
{/* Board Column */}

Tactical_Grid_Overlay

{board[0].map((_, colIdx) => ( ))} {board.map((row, rowIndex) => row.map((cell, colIndex) => { const isWinningCell = winningCells.some( ([r, c]) => r === rowIndex && c === colIndex, ); return (
{cell !== 0 && ( )}
); }), )}
); }; export default ConnectFourPage;