Skip to content

Instantly share code, notes, and snippets.

@TravisL12
Created September 13, 2024 21:43
Show Gist options
  • Select an option

  • Save TravisL12/fd2032d839090239110f3cac6c4d4152 to your computer and use it in GitHub Desktop.

Select an option

Save TravisL12/fd2032d839090239110f3cac6c4d4152 to your computer and use it in GitHub Desktop.
Tic Tac Toe React
const PLAYER_MARKS = ["X", "O"];
const EMPTY = "";
const checkWinner = (moves, player) =>
moves.every((c) => c === PLAYER_MARKS[player]);
const Board = ({ size }) => {
const [tiles, setTiles] = React.useState(new Array(size ** 2).fill(EMPTY));
const [playerIdx, setPlayerIdx] = React.useState(1);
const [isWinner, setIsWinner] = React.useState(false);
const checkRows = () => {
for (let i = 0; i < size; i++) {
const row = tiles.slice(i * size, i * size + size);
if (checkWinner(row, playerIdx)) return true;
}
return false;
};
const checkColumns = () => {
for (let i = 0; i < size; i++) {
const column = tiles.filter((_, idx) => idx % size === i);
if (checkWinner(column, playerIdx)) return true;
}
return false;
};
const checkDiagonals = () => {
const diag = tiles.filter((_, idx) => idx % (size + 1) === 0);
if (checkWinner(diag, playerIdx)) return true;
const revDiag = tiles.filter(
(_, idx) => idx > 0 && idx < tiles.length - 1 && idx % (size - 1) === 0
);
if (checkWinner(revDiag, playerIdx)) return true;
return false;
};
const makeMove = (tileIdx) => {
if (isWinner) {
return;
}
const newTiles = [...tiles];
const tile = newTiles[tileIdx];
if (!tile) {
newTiles[tileIdx] = PLAYER_MARKS[playerIdx];
setTiles(newTiles);
}
};
React.useEffect(() => {
const isGameOver = checkRows() || checkColumns() || checkDiagonals();
if (isGameOver) {
setIsWinner(true);
} else {
setPlayerIdx(playerIdx === 0 ? 1 : 0);
}
}, [tiles]);
return (
<React.Fragment>
<div
className="board"
style={{
gridTemplateColumns: `repeat(${size}, 50px)`,
gridTemplateRows: `repeat(${size}, 50px)`,
}}
>
{tiles.map((tile, idx) => (
<div
key={idx}
className="tile"
onClick={() => {
makeMove(idx);
}}
>
{tile}
</div>
))}
</div>
{isWinner && <div>Player {playerIdx + 1} wins!</div>}
</React.Fragment>
);
};
ReactDOM.render(<Board size={3} />, document.getElementById("root"));
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.11.0/umd/react-dom.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.js"></script>
<style>
body {
background-color: white;
}
.board {
display: inline-grid;
background: black;
gap: 1px;
width: auto;
}
.tile {
width: 100%;
height: 100%;
background: white;
display: flex;
justify-content: center;
align-items: center;
}
</style>
</head>
<body>
<div id="root"></div>
</body>
<script type="text/jsx" src="app.js"></script>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment