Skip to content

Instantly share code, notes, and snippets.

@ChristopherHButler
Created October 5, 2020 21:15
Show Gist options
  • Save ChristopherHButler/9ce6a6f851baf41e40e5a308037e3ac7 to your computer and use it in GitHub Desktop.
Save ChristopherHButler/9ce6a6f851baf41e40e5a308037e3ac7 to your computer and use it in GitHub Desktop.
React Tic Tac Toe

React Tic Tac Toe

This Gist was generated by Contrived.

Do not modify the metadata file if you want to open in Contrived again. Otherwise, it is safe to delete.

Happy Hacking!

{"user":"5f0c542a4a2ce5e528e01fdf","templateVersion":"1","templateId":"reactjs","resources":["<meta charset=\"UTF-8\" />","<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, shrink-to-fit=no\">"],"dependencies":[{"name":"react","version":"16.13.1","type":"js","url":"https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"},{"name":"react-dom","version":"16.13.1","type":"js","url":"https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"}],"files":[{"id":1,"parentId":0,"name":"public","path":"/public","type":"folder","isRoot":true,"selected":false,"expanded":false,"children":[{"id":2,"name":"index.html"}]},{"id":2,"parentId":1,"name":"index.html","path":"/src/index.html","type":"file","mimeType":"html","isRoot":false,"open":true,"selected":false,"content":""},{"id":3,"parentId":0,"name":"src","path":"/src","type":"folder","isRoot":true,"selected":false,"expanded":true,"children":[{"id":4,"name":"index.js"},{"id":5,"name":"styles.css"}]},{"id":4,"parentId":3,"name":"index.js","path":"/src/index.js","type":"file","mimeType":"es6","isRoot":false,"open":true,"selected":true,"content":""},{"id":5,"parentId":3,"name":"style.css","path":"/src/style.css","type":"file","mimeType":"css","isRoot":false,"open":true,"selected":false,"content":""}],"experimentId":"5f7b87e15556113114e18d8d"}
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.square {
background: white;
border: 1px solid gray;
float: left;
margin-right: -1px;
margin-top: -1px;
padding: 0;
width: 80px;
height: 80px;
text-align: center;
font-size: 40px;
font-weight: bold;
line-Height: 80px;
}
.square:focus {
outline: none;
}
.boarder-row:after {
clear: both;
content: '';
display: table;
}
.game {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: flex;
flex-direction: row;
margin: 0 auto;
margin-top: 150px;
}
ul {
padding-left: 20px;
}
.game-info {
margin-left: 20px;
}
.status {
margin-bottom: 10px;
}
<div id="root"></div>
const { Component } = React;
const Square = ({ value, onClick }) => {
return (
<button className="square" onClick={onClick}>
{value}
</button>
)
}
const Board = ({ squares, onClick }) => {
const renderSquare = (i) => {
return (
<Square value={squares[i]} onClick={() => onClick(i)} />
);
}
return (
<div>
<div className="border-row">
{renderSquare(0)}
{renderSquare(1)}
{renderSquare(2)}
</div>
<div className="border-row">
{renderSquare(3)}
{renderSquare(4)}
{renderSquare(5)}
</div>
<div className="border-row">
{renderSquare(6)}
{renderSquare(7)}
{renderSquare(8)}
</div>
</div>
);
};
class App extends Component {
constructor(props) {
super(props);
this.state = {
xIsNext: true,
stepNumber: 0,
history: [
{ squares: Array(9).fill(null) }
]
};
}
handleClick(i) {
const history = this.state.history.slice(0, this.state.stepNumber + 1);
const current = history[history.length - 1];
const squares = current.squares.slice();
const winner = calculateWinner(squares);
if (winner || squares[i]) {
return;
}
squares[i] = this.state.xIsNext ? 'X' : 'O';
this.setState({
history: history.concat({ squares }),
xIsNext: !this.state.xIsNext,
stepNumber: history.length,
});
}
jumpTo(step) {
this.setState({
stepNumber: step,
xIsNext: (step % 2) === 0,
});
}
render() {
const history = this.state.history;
const current = history[this.state.stepNumber];
const winner = calculateWinner(current.squares);
const moves = history.map((step, move) => {
const desc = move ? 'Go to #' + move : 'Start the Game';
return (
<li key={move}>
<button onClick={() => {this.jumpTo(move)}}>
{desc}
</button>
</li>
);
});
let status;
if (winner) {
status = 'Winner is ' + winner;
} else {
status = 'Next player is ' + (this.state.xIsNext ? 'X' : 'O');
}
return (
<div className="game">
<div className="game-board">
<Board squares={current.squares} onClick={(i) => this.handleClick(i)} />
</div>
<div className="game-info">
<div>{status}</div>
<ul>{moves}</ul>
</div>
</div>
)
}
}
function calculateWinner(squares) {
const lines = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6],
];
for (let i = 0; i < lines.length; i++) {
const [a,b,c] = lines[i];
if (squares[a] && squares[a] === squares[b] && squares[b] === squares[c]) {
return squares[a];
}
}
return null;
}
ReactDOM.render(<App/>, document.getElementById('root'));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment