From b106042971440af4330c3560914c3a550b4a03a2 Mon Sep 17 00:00:00 2001 From: Thuan Bui Date: Mon, 23 Aug 2021 10:18:21 +0700 Subject: [PATCH] Initial commit --- .codesandbox/workspace.json | 20 ++++++++++++ package.json | 28 ++++++++++++++++ public/index.html | 43 +++++++++++++++++++++++++ src/App.js | 11 +++++++ src/Board.js | 64 +++++++++++++++++++++++++++++++++++++ src/Game.js | 20 ++++++++++++ src/Square.js | 20 ++++++++++++ src/index.js | 12 +++++++ src/styles.css | 55 +++++++++++++++++++++++++++++++ 9 files changed, 273 insertions(+) create mode 100644 .codesandbox/workspace.json create mode 100644 package.json create mode 100644 public/index.html create mode 100644 src/App.js create mode 100644 src/Board.js create mode 100644 src/Game.js create mode 100644 src/Square.js create mode 100644 src/index.js create mode 100644 src/styles.css diff --git a/.codesandbox/workspace.json b/.codesandbox/workspace.json new file mode 100644 index 0000000..e7d06a2 --- /dev/null +++ b/.codesandbox/workspace.json @@ -0,0 +1,20 @@ +{ + "responsive-preview": { + "Mobile": [ + 320, + 675 + ], + "Tablet": [ + 1024, + 765 + ], + "Desktop": [ + 1400, + 800 + ], + "Desktop HD": [ + 1920, + 1080 + ] + } +} \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..4d6fa0b --- /dev/null +++ b/package.json @@ -0,0 +1,28 @@ +{ + "name": "tic-tac-toe", + "version": "1.0.0", + "description": "", + "keywords": [], + "main": "src/index.js", + "dependencies": { + "react": "17.0.2", + "react-dom": "17.0.2", + "react-scripts": "4.0.0" + }, + "devDependencies": { + "@babel/runtime": "7.13.8", + "typescript": "4.1.3" + }, + "scripts": { + "start": "react-scripts start", + "build": "react-scripts build", + "test": "react-scripts test --env=jsdom", + "eject": "react-scripts eject" + }, + "browserslist": [ + ">0.2%", + "not dead", + "not ie <= 11", + "not op_mini all" + ] +} \ No newline at end of file diff --git a/public/index.html b/public/index.html new file mode 100644 index 0000000..42ae2d2 --- /dev/null +++ b/public/index.html @@ -0,0 +1,43 @@ + + + + + + + + + + + + React App + + + + +
+ + + + \ No newline at end of file diff --git a/src/App.js b/src/App.js new file mode 100644 index 0000000..49635ef --- /dev/null +++ b/src/App.js @@ -0,0 +1,11 @@ +import "./styles.css"; +import Game from "./Game"; + +export default function App() { + return ( +
+

Tic Tac Toe game

+ +
+ ); +} diff --git a/src/Board.js b/src/Board.js new file mode 100644 index 0000000..607a38c --- /dev/null +++ b/src/Board.js @@ -0,0 +1,64 @@ +import React from "react"; +import Square from "./Square"; + +class Board extends React.Component { + constructor(props) { + super(props); + this.state = { + squares: Array(9).fill(null), + slot: true + }; + this.clickHandler = this.clickHandler.bind(this); + this.handleClick = this.handleClick.bind(this); + } + + clickHandler() { + console.log("Click"); + this.setState({ value: "O" }); + } + handleClick(props) { + let square = this.state.squares.slice(); + console.log(square); + this.state.slot === true ? (square[props] = "X") : (square[props] = "O"); + this.setState({ + squares: square, + slot: !this.state.slot + }); + } + + renderSquare(props) { + return ( + this.handleClick(props)} + /> + ); + } + + render() { + const status = "Next player: X"; + + return ( +
+
{status}
+
+ {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)} +
+
+ ); + } +} + +export default Board; diff --git a/src/Game.js b/src/Game.js new file mode 100644 index 0000000..d5123a0 --- /dev/null +++ b/src/Game.js @@ -0,0 +1,20 @@ +import React from "react"; +import Board from "./Board"; + +class Game extends React.Component { + render() { + return ( +
+
+ +
+
+
{/* status */}
+
    {/* TODO */}
+
+
+ ); + } +} + +export default Game; diff --git a/src/Square.js b/src/Square.js new file mode 100644 index 0000000..f489195 --- /dev/null +++ b/src/Square.js @@ -0,0 +1,20 @@ +import React from "react"; + +class Square extends React.Component { + constructor(props) { + super(props); + this.state = { + value: null + }; + } + + render() { + return ( + + ); + } +} + +export default Square; diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..d65892e --- /dev/null +++ b/src/index.js @@ -0,0 +1,12 @@ +import { StrictMode } from "react"; +import ReactDOM from "react-dom"; + +import App from "./App"; + +const rootElement = document.getElementById("root"); +ReactDOM.render( + + + , + rootElement +); diff --git a/src/styles.css b/src/styles.css new file mode 100644 index 0000000..cebe7a3 --- /dev/null +++ b/src/styles.css @@ -0,0 +1,55 @@ +.App { + font-family: sans-serif; + text-align: center; +} +body { + font: 14px "Century Gothic", Futura, sans-serif; + margin: 20px; +} + +ol, +ul { + padding-left: 30px; +} + +.board-row:after { + clear: both; + content: ""; + display: table; +} + +.status { + margin-bottom: 10px; +} + +.square { + background: #fff; + border: 1px solid black; + float: left; + font-size: 24px; + font-weight: bold; + line-height: 34px; + height: 34px; + margin-right: -1px; + margin-top: -1px; + padding: 0; + text-align: center; + width: 34px; +} + +.square:focus { + outline: none; +} + +.kbd-navigation .square:focus { + background: #ddd; +} + +.game { + display: flex; + flex-direction: row; +} + +.game-info { + margin-left: 20px; +}