diff --git a/website/pages/index.js b/website/pages/index.js index 19f3a8d681..2d89400073 100644 --- a/website/pages/index.js +++ b/website/pages/index.js @@ -1,4 +1,5 @@ import React from 'react'; +import TicTacToe from './tictactoe'; import {Link} from 'react-router-dom'; export default class Home extends React.Component { @@ -11,7 +12,10 @@ export default class Home extends React.Component { )); return (
- +

Available Urls

+ +

Play some TicTacToe

+
); } diff --git a/website/pages/tictactoe.js b/website/pages/tictactoe.js new file mode 100644 index 0000000000..b5af6ad4e0 --- /dev/null +++ b/website/pages/tictactoe.js @@ -0,0 +1,165 @@ +import React from 'react'; + +const square = { + background: '#fff', + border: '1px solid #999', + float: 'left', + fontSize: '24px', + fontWeight: 'bold', + lineHeight: '34px', + height: '34px', + marginright: '-1px', + marginTop: '-1px', + padding: '0', + textAlign: 'center', + width: '34px' +}; + +const boardRow = { + clear: 'both', + content: '', + display: 'table' +}; + +const game = { + display: 'flex', + flexDirection: 'row' +}; + +function Square(props) { + return ( + + ); +} + +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[a] === squares[c]) { + return squares[a]; + } + } + return null; +} + +class Board extends React.Component { + renderSquare(i) { + return ( + this.props.onClick(i)} + /> + ); + } + + render() { + return ( +
+
+ {this.renderSquare(0)} + {this.renderSquare(1)} + {this.renderSquare(2)} +
+
+ {this.renderSquare(3)} + {this.renderSquare(4)} + {this.renderSquare(5)} +
+
+ {this.renderSquare(6)} + {this.renderSquare(7)} + {this.renderSquare(8)} +
+
+ ); + } +} + +class Game extends React.Component { + constructor(props) { + super(props); + this.state = { + history: [ + { + squares: Array(9).fill(null) + } + ], + stepNumber: 0, + xIsNext: true + }; + } + + handleClick(i) { + const history = this.state.history.slice(0, this.state.stepNumber + 1); + const current = history[history.length - 1]; + const squares = current.squares.slice(); + if (calculateWinner(squares) || squares[i]) { + return; + } + squares[i] = this.state.xIsNext ? 'X' : 'O'; + this.setState({ + history: history.concat([ + { + squares: squares + } + ]), + stepNumber: history.length, + xIsNext: !this.state.xIsNext + }); + } + + 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 #' + move : 'Go to game start'; + return ( +
  • + +
  • + ); + }); + + let status; + if (winner) { + status = 'Winner: ' + winner; + } else { + status = 'Next player: ' + (this.state.xIsNext ? 'X' : 'O'); + } + + return ( +
    +
    + this.handleClick(i)} /> +
    +
    +
    {status}
    +
      {moves}
    +
    +
    + ); + } +} + +export default Game;