add tic tac toe game
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
This commit is contained in:
parent
0e47ca2572
commit
38f9c8d7e3
@ -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 (
|
||||
<Box component={'article'}>
|
||||
<Container component={'article'}>
|
||||
<Typography variant='h2'>{post.title}</Typography>
|
||||
<Typography variant='body2'>{post.date}</Typography>
|
||||
<Box dangerouslySetInnerHTML={{ __html: post.contentHtml }} />
|
||||
</Box>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
@ -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 (
|
||||
<Box>
|
||||
<Container>
|
||||
<Typography variant='h1' >My Blog</Typography>
|
||||
<List>
|
||||
{posts.map(post => (
|
||||
@ -20,6 +20,6 @@ export default function Home() {
|
||||
</ListItem>
|
||||
))}
|
||||
</List>
|
||||
</Box >
|
||||
</Container >
|
||||
);
|
||||
}
|
||||
@ -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 (
|
||||
<Box>
|
||||
<Typography variant={'h1'}>Welcome to the den</Typography>
|
||||
<Typography variant="body1">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</Typography>
|
||||
</Box>
|
||||
<Container>
|
||||
|
||||
<Xo />
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
@ -47,14 +47,13 @@ export default function Header() {
|
||||
<Toolbar>
|
||||
<IconButton
|
||||
size='large'
|
||||
sx={{ color: 'background.paper' }}
|
||||
aria-label="open drawer"
|
||||
edge="start"
|
||||
onClick={handleDrawerToggle}
|
||||
>
|
||||
<MenuIcon />
|
||||
</IconButton>
|
||||
<Typography variant="h6" padding={2} color='background.paper'>
|
||||
<Typography variant="h4" padding={2}>
|
||||
TCG
|
||||
</Typography>
|
||||
<Box sx={{ flexGrow: 1 }} />
|
||||
|
||||
121
src/components/Xo/Xo.tsx
Normal file
121
src/components/Xo/Xo.tsx
Normal file
@ -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<Cell[]>([...emptyBoard]);
|
||||
const [isPlayerTurn, setIsPlayerTurn] = useState(true);
|
||||
const [winner, setWinner] = useState<Player | 'Draw' | null>(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 (
|
||||
<Container maxWidth="sm" sx={{ mt: 5 }}>
|
||||
<Typography variant="h4" align="center" gutterBottom>
|
||||
Tic Tac Toe
|
||||
</Typography>
|
||||
<Grid container spacing={1} >
|
||||
{board.map((cell, idx) => (
|
||||
<Grid key={idx} size={4}>
|
||||
<Paper
|
||||
elevation={3}
|
||||
sx={{
|
||||
height: 100,
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
fontSize: '2rem',
|
||||
cursor: cell || winner || !isPlayerTurn ? 'default' : 'pointer',
|
||||
backgroundColor: 'background.paper',
|
||||
}}
|
||||
onClick={() => handleClick(idx)}
|
||||
>
|
||||
{cell}
|
||||
</Paper>
|
||||
</Grid>
|
||||
))}
|
||||
</Grid>
|
||||
{winner && (
|
||||
<Box mt={4} textAlign="center">
|
||||
<Typography variant="h5" gutterBottom>
|
||||
{winner === 'Draw' ? "It's a draw!" : `${winner} wins!`}
|
||||
</Typography>
|
||||
<Button variant="contained" onClick={resetGame}>
|
||||
Play Again
|
||||
</Button>
|
||||
</Box>
|
||||
)}
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
1
src/components/Xo/index.ts
Normal file
1
src/components/Xo/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './Xo';
|
||||
Loading…
x
Reference in New Issue
Block a user