Skip to content

Instantly share code, notes, and snippets.

@gustavonovaes
Created August 6, 2019 22:52
Show Gist options
  • Save gustavonovaes/eced4656da59bbbd8b666641609b8be3 to your computer and use it in GitHub Desktop.
Save gustavonovaes/eced4656da59bbbd8b666641609b8be3 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello World</title>
<script src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
<script
src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
<!-- Don't use this in production: -->
<script src="https://unpkg.com/[email protected]/babel.min.js"></script>
<style>
@import url('https://fonts.googleapis.com/css?family=Montserrat&display=swap');
html,
body,
#root {
height: 100%;
}
body {
font-family: 'Montserrat', sans-serif;
margin: 0;
padding: 0;
}
#root {
display: flex;
justify-content: center;
align-items: center;
text-align: center;
}
.status {
margin: 1em 0;
}
.square {
padding: 0;
width: 50px;
height: 50px;
margin: 5px;
border: 1px solid #aaa;
background: #f2f2f2;
display: inline-block;
vertical-align: middle;
text-align: center;
font-size: 30px;
line-height: 50px;
transition: transform 1s;
}
.square:hover {
border: 1px solid #666;
cursor: pointer;
}
.square.highlight {
font-weight: bold;
color: #45B555;
border: 1px solid #45B555;
transform: scale(1.1);
}
</style>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
const calculateWinner = (squares) => {
const winMoves = [
[0, 1, 2], [0, 3, 6], [0, 4, 8],
[1, 4, 7], [2, 5, 8], [3, 4, 5],
[6, 7, 8]
]
const winnerMove = winMoves.find(([a, b, c]) =>
squares[a] && (squares[a] === squares[b]) && (squares[b] === squares[c])
)
if (!winnerMove) {
return [false, []];
}
const player = squares[winnerMove[0]]
return [player, winnerMove]
}
const reducer = (state, nextState) => ({
...state,
...nextState
})
const Game = () => {
const [state, setState] = React.useReducer(reducer, {
isX: true,
winner: false,
winnerMove: [],
squares: Array(9).fill(null)
})
const handleClick = pos => {
if (state.squares[pos] || state.winner) {
return
}
const player = state.isX ? 'X' : 'O'
const squares = state.squares.concat()
squares[pos] = player
const [winner, winnerMove] = calculateWinner(squares)
setState({
isX: !state.isX,
squares,
winner,
winnerMove
})
}
const showStatus = () => {
if (state.winner) {
return <span>{state.winner} venceu!</span>
}
if (state.squares.every(x => x)) {
return <span>Empate!</span>
}
const nextPlayer = state.isX ? 'X': 'O';
return <span>Proximo jogador: {nextPlayer}</span>
}
return <div>
<h1>Jogo da Velha</h1>
<div className="status">
{showStatus()}
</div>
<Board winnerMove={state.winnerMove} squares={state.squares} onClick={handleClick} />
</div>
}
const Board = ({ winnerMove, squares, onClick }) => {
const renderSquares = () => {
return <div>
<div>
{[0,1,2].map(pos =>
<Square
key={pos}
highlight={winnerMove.includes(pos)}
pos={pos}
value={squares[pos]}
onClick={onClick}
/>
)}
</div>
<div>
{[3,4,5].map(pos =>
<Square
key={pos}
highlight={winnerMove.includes(pos)}
pos={pos}
value={squares[pos]}
onClick={onClick}
/>
)}
</div>
<div>
{[6,7,8].map(pos =>
<Square
key={pos}
highlight={winnerMove.includes(pos)}
pos={pos}
value={squares[pos]}
onClick={onClick}
/>
)}
</div>
</div>
}
return <div className="board">
{renderSquares()}
</div>
}
const Square = ({ highlight, pos, value, onClick }) => {
const handleClick = e => {
e.preventDefault();
onClick(pos)
}
let className = "square"
if (highlight) {
className += " highlight"
}
return <div className={className} onClick={handleClick}>{value}</div>
}
ReactDOM.render(
<Game />,
document.getElementById('root')
);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment