From 38f9c8d7e311e60a10e579d813a15bc36a51ee86 Mon Sep 17 00:00:00 2001 From: apatil Date: Tue, 6 May 2025 00:01:01 +0100 Subject: [PATCH] add tic tac toe game --- src/app/blog/[slug]/page.tsx | 6 +- src/app/blog/page.tsx | 6 +- src/app/page.tsx | 11 +-- src/components/Header/Header.tsx | 3 +- src/components/Xo/Xo.tsx | 121 +++++++++++++++++++++++++++++++ src/components/Xo/index.ts | 1 + 6 files changed, 135 insertions(+), 13 deletions(-) create mode 100644 src/components/Xo/Xo.tsx create mode 100644 src/components/Xo/index.ts diff --git a/src/app/blog/[slug]/page.tsx b/src/app/blog/[slug]/page.tsx index f0a04bc..29a335e 100644 --- a/src/app/blog/[slug]/page.tsx +++ b/src/app/blog/[slug]/page.tsx @@ -1,4 +1,4 @@ -import { Box, Typography } from '@mui/material'; +import { Box, Container, Typography } from '@mui/material'; import { getPostBySlug, getAllSlugs } from '../../../lib/posts'; import { notFound } from 'next/navigation'; @@ -13,10 +13,10 @@ export default async function BlogPost({ params }: Props) { const post = await getPostBySlug(slug); if (!post) return notFound(); return ( - + {post.title} {post.date} - + ); } \ No newline at end of file diff --git a/src/app/blog/page.tsx b/src/app/blog/page.tsx index 9588469..c38e1a5 100644 --- a/src/app/blog/page.tsx +++ b/src/app/blog/page.tsx @@ -1,10 +1,10 @@ import { getAllPosts } from '../../lib/posts'; import ArticleIcon from '@mui/icons-material/Article'; -import { Avatar, Box, Link, List, ListItem, ListItemAvatar, ListItemButton, ListItemText, Typography } from '@mui/material'; +import { Avatar, Container, Link, List, ListItem, ListItemAvatar, ListItemButton, ListItemText, Typography } from '@mui/material'; export default function Home() { const posts = getAllPosts(); return ( - + My Blog {posts.map(post => ( @@ -20,6 +20,6 @@ export default function Home() { ))} - + ); } \ No newline at end of file diff --git a/src/app/page.tsx b/src/app/page.tsx index e003c87..637a1c0 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,11 +1,12 @@ -import { Box, Typography } from "@mui/material"; +import Xo from "@/components/Xo/Xo"; +import { Container } from "@mui/material"; export default function Home() { return ( - - Welcome to the den - Here lives the geek bear who is hungry for bits and bytes. Ravaging through the internet dumpster finding the finest 0s and 1s. He looks for speed and performance - + + + + ); } diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx index 020b0a3..41cf3a6 100644 --- a/src/components/Header/Header.tsx +++ b/src/components/Header/Header.tsx @@ -47,14 +47,13 @@ export default function Header() { - + TCG diff --git a/src/components/Xo/Xo.tsx b/src/components/Xo/Xo.tsx new file mode 100644 index 0000000..33ebcd5 --- /dev/null +++ b/src/components/Xo/Xo.tsx @@ -0,0 +1,121 @@ +'use client' +import { useEffect, useState } from 'react'; +import { + Container, + Typography, + Grid, + Paper, + Button, + Box, +} from '@mui/material'; +type Player = 'X' | 'O'; +type Cell = Player | null; +const emptyBoard: Cell[] = Array(9).fill(null); +const winningCombos = [ + [0, 1, 2], [3, 4, 5], [6, 7, 8], + [0, 3, 6], [1, 4, 7], [2, 5, 8], + [0, 4, 8], [2, 4, 6], +]; +function checkWinner(board: Cell[]): Player | 'Draw' | null { + for (const [a, b, c] of winningCombos) { + if (board[a] && board[a] === board[b] && board[a] === board[c]) { + return board[a]; + } + } + return board.includes(null) ? null : 'Draw'; +} +function minimax(board: Cell[], isMaximizing: boolean): { score: number; index: number } { + const winner = checkWinner(board); + if (winner === 'O') return { score: 1, index: -1 }; + if (winner === 'X') return { score: -1, index: -1 }; + if (winner === 'Draw') return { score: 0, index: -1 }; + let bestMove = -1; + let bestScore = isMaximizing ? -Infinity : Infinity; + for (let i = 0; i < board.length; i++) { + if (board[i] === null) { + board[i] = isMaximizing ? 'O' : 'X'; + const result = minimax(board, !isMaximizing); + board[i] = null; + if (isMaximizing) { + if (result.score > bestScore) { + bestScore = result.score; + bestMove = i; + } + } else { + if (result.score < bestScore) { + bestScore = result.score; + bestMove = i; + } + } + } + } + return { score: bestScore, index: bestMove }; +} +export default function XOGame() { + const [board, setBoard] = useState([...emptyBoard]); + const [isPlayerTurn, setIsPlayerTurn] = useState(true); + const [winner, setWinner] = useState(null); + useEffect(() => { + if (!isPlayerTurn && !winner) { + const move = minimax([...board], true).index; + if (move !== -1) { + const newBoard = [...board]; + newBoard[move] = 'O'; + setBoard(newBoard); + setWinner(checkWinner(newBoard)); + setIsPlayerTurn(true); + } + } + }, [isPlayerTurn, board, winner]); + const handleClick = (index: number) => { + if (board[index] || winner || !isPlayerTurn) return; + const newBoard = [...board]; + newBoard[index] = 'X'; + setBoard(newBoard); + setWinner(checkWinner(newBoard)); + setIsPlayerTurn(false); + }; + const resetGame = () => { + setBoard([...emptyBoard]); + setWinner(null); + setIsPlayerTurn(true); + }; + return ( + + + Tic Tac Toe + + + {board.map((cell, idx) => ( + + handleClick(idx)} + > + {cell} + + + ))} + + {winner && ( + + + {winner === 'Draw' ? "It's a draw!" : `${winner} wins!`} + + + + )} + + ); +} diff --git a/src/components/Xo/index.ts b/src/components/Xo/index.ts new file mode 100644 index 0000000..bb55ac8 --- /dev/null +++ b/src/components/Xo/index.ts @@ -0,0 +1 @@ +export * from './Xo';