npx create-react-app <your-game> && cd <your-game>
npm install ethers
npm start
rm src/App.js && nano src/App.js
import React, { useState, useEffect } from 'react';
import './App.css';
const BOARD_SIZE = 3;
function App() {
const [squares, setSquares] = useState(Array(BOARD_SIZE * BOARD_SIZE).fill(null));
const [xIsNext, setXIsNext] = useState(true); // true = Player's turn
const winner = calculateWinner(squares);
// Khi d?n lu?t máy, t? d?ng choi
useEffect(() => {
if (!xIsNext && !winner) {
const timer = setTimeout(() => {
makeRandomMove();
}, 500); // Delay nh? cho t? nhiên
return () => clearTimeout(timer);
}
}, [xIsNext, squares, winner]);
const handleClick = (index) => {
if (squares[index] || winner || !xIsNext) return;
const nextSquares = squares.slice();
nextSquares[index] = 'X';
setSquares(nextSquares);
setXIsNext(false);
};
const makeRandomMove = () => {
const emptyIndices = squares
.map((val, idx) => (val === null ? idx : null))
.filter((val) => val !== null);
if (emptyIndices.length === 0) return;
const randomIndex = emptyIndices[Math.floor(Math.random() * emptyIndices.length)];
const nextSquares = squares.slice();
nextSquares[randomIndex] = 'O';
setSquares(nextSquares);
setXIsNext(true);
};
const renderSquare = (index) => (
<div
key={index}
className={`square ${squares[index] === 'X' ? 'x' : squares[index] === 'O' ? 'o' : ''}`}
onClick={() => handleClick(index)}
>
{squares[index]}
</div>
);
const renderBoard = () => {
const board = [];
for (let row = 0; row < BOARD_SIZE; row++) {
const cols = [];
for (let col = 0; col < BOARD_SIZE; col++) {
const index = row * BOARD_SIZE + col;
cols.push(renderSquare(index));
}
board.push(
<div className="board-row" key={row}>
{cols}
</div>
);
}
return board;
};
const handleReset = () => {
setSquares(Array(BOARD_SIZE * BOARD_SIZE).fill(null));
setXIsNext(true);
};
return (
<div className="game">
<div className="status">
{winner
? `Winner: ${winner}`
: squares.every((s) => s !== null)
? 'Draw!'
: `Turn: ${xIsNext ? 'You (X)' : 'Computer (O)'}`}
</div>
{renderBoard()}
<button className="reset" onClick={handleReset}>Reset Game</button>
</div>
);
}
// Function to check for a winner
function calculateWinner(squares) {
const lines = [
[0, 1, 2], // rows
[3, 4, 5],
[6, 7, 8],
[0, 3, 6], // columns
[1, 4, 7],
[2, 5, 8],
[0, 4, 8], // diagonals
[2, 4, 6],
];
for (let [a, b, c] of lines) {
if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
return squares[a];
}
}
return null;
}
export default App;
rm src/App.css && nano src/App.css
.game {
display: flex;
flex-direction: column;
align-items: center;
margin-top: 50px;
font-family: sans-serif;
}
.board-row {
display: flex;
}
.square {
width: 60px;
height: 60px;
font-size: 30px;
background-color: #fff;
border: 1px solid #ddd;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
}
.x {
color: red;
}
.o {
color: green;
}
.status {
margin-bottom: 10px;
font-size: 18px;
font-weight: bold;
}
.reset {
margin-top: 20px;
padding: 10px 20px;
background-color: #ddd;
border: none;
cursor: pointer;
font-size: 16px;
}
Creat with name caro-on-fleek
git init
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/USERNAME/caro-on-fleek.git
git branch
If you see master, use this:
git branch -m master main
git push -u origin main
git remote set-url origin https://GITHUB_USERNAME:[email protected]/GITHUB_USERNAME/caro-on-fleek.git
git push -u origin main
npm install -g @fleek-platform/cli
fleek version
fleek login
Confirm on your Fleek account !
✅ Success! You are now logged in to the Fleek Platform.
My app: https://github.com/ToanBm/caro-on-fleek
git clone https://github.com/YOUR-GITHUB-USER/caro-on-fleek.git
cd caro-on-fleek
npm i
npm run build