Skip to content

Instantly share code, notes, and snippets.

@davidkayce
Last active February 1, 2022 07:56
Show Gist options
  • Save davidkayce/b1095965294d003e4a667ebc4e1d976b to your computer and use it in GitHub Desktop.
Save davidkayce/b1095965294d003e4a667ebc4e1d976b to your computer and use it in GitHub Desktop.
This is a sample tic tac toe application. Based on a coderbyte test
import React, { useState, useEffect } from 'react';
import ReactDOM from 'react-dom';
const squareStyle = {
'width': '60px',
'height': '60px',
'backgroundColor': 'white',
'margin': '4px',
'display': 'flex',
'justifyContent': 'center',
'alignItems': 'center',
'fontSize': '20px',
'color': 'red',
'fontWeight': 400
}
const boardStyle = {
'borderRadius': '10px',
'backgroundColor': '#eee',
'width': '208px',
'alignItems': 'center',
'justifyContent': 'center',
'display': 'flex',
'flexWrap': 'wrap',
'border': '3px #eee solid'
}
const containerStyle = {
'display': 'flex',
'alignItems': 'center',
'flexDirection': 'column'
}
const instructionsStyle = {
'marginTop': '5px',
'marginBottom': '5px',
'fontWeight': 'bold',
'fontSize': '16px',
}
const buttonStyle = {
'marginTop': '15px',
'marginBottom': '16px',
'width': '80px',
'height': '40px',
'backgroundColor': '#8acaca',
'color': 'white',
'fontSize': '16px',
}
const Square = ({ input, id, handleInput }) => {
return (
<div
className="square"
onClick={() => handleInput(id)}
style={squareStyle}>
{input}
</div>
);
}
const Board = ({
board,
isXNext,
resetBoard,
winner,
gameOver,
handleInput
}) => {
return (
<div style={containerStyle} className="gameBoard">
{gameOver && <div id="winnerArea" className={winner ? `winner` : `game-over`} style={instructionsStyle}>{winner ? `Winner: ${winner}` : `Game Over`}</div>}
{!gameOver && <div id="statusArea" className="status" style={instructionsStyle}>Next player: <span>{isXNext ? 'X' : 'O'}</span></div>}
<button style={buttonStyle} onClick={resetBoard}>Reset</button>
<section style={boardStyle}>
{board.map((playerInput, index) => (
<Square
key={index}
id={index}
input={playerInput}
handleInput={handleInput}
/>
))}
</section>
</div>
);
}
// Possible combination of the squares that result in a win
const cellCombinations = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6]
];
const Game = () => {
const [board, setBoard] = useState(Array(9).fill(null));
const [isXNext, setIsXNext] = useState(true); // X always starts
const [isGameEnded, setGameEnded] = useState(false);
const [winner, setWinner] = useState(null);
useEffect(() => {
const findWinner = cellCombinations.some((combo) => {
const [first, second, third] = combo;
const marksPlacement = [board[first], board[second], board[third]];
const [inputType] = marksPlacement;
const isCorrect = inputType && marksPlacement.every(mark => mark === inputType);
if (isCorrect) {
setWinner(inputType)
return true
}
return false;
})
setGameEnded(findWinner || board.every(mark => !!mark))
}, [board]);
const handleSquareInput = (id) => {
const buffer = [...board];
// if there is already an existing mark in the space or the game is ended, ignore
if (winner || buffer[id]) return;
buffer[id] = isXNext ? 'X' : 'O';
setBoard(buffer);
setIsXNext(!isXNext);
}
const resetBoard = () => {
setBoard(Array(9).fill(null));
setIsXNext(true);
setGameEnded(false);
setWinner(null);
}
return (
<div className="game">
<div className="game-board">
<Board
board={board}
isXNext={isXNext}
winner={winner}
gameOver={isGameEnded}
handleInput={handleSquareInput}
resetBoard={resetBoard}
/>
</div>
</div>
);
}
ReactDOM.render(
<Game />,
document.getElementById('root')
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment