From b54bdec07f496d5dd1012f5b75b0c69992e7e930 Mon Sep 17 00:00:00 2001 From: charlotte adams Date: Thu, 16 Apr 2020 17:27:57 -0700 Subject: [PATCH 1/8] complete Wave 1 --- src/components/Board.js | 26 ++++++++++++++++++++++---- src/components/Square.js | 10 +++++++--- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/components/Board.js b/src/components/Board.js index 484198fe..9b5c8f54 100644 --- a/src/components/Board.js +++ b/src/components/Board.js @@ -5,17 +5,35 @@ import PropTypes from 'prop-types'; const generateSquareComponents = (squares, onClickCallback) => { - // Complete this for Wave 1 -} + const flattenSquares = squares.flat(); + const squareComponents = flattenSquares.map((square) => { + + return ( + + + + ); + }); + return squareComponents; +}; + + const Board = ({ squares, onClickCallback }) => { const squareList = generateSquareComponents(squares, onClickCallback); console.log(squareList); - return
+ return
{squareList}
-} + +}; Board.propTypes = { squares: PropTypes.arrayOf( diff --git a/src/components/Square.js b/src/components/Square.js index 71f46b8c..5a766370 100644 --- a/src/components/Square.js +++ b/src/components/Square.js @@ -4,9 +4,13 @@ import PropTypes from 'prop-types'; import './Square.css' const Square = (props) => { - // For Wave 1 enable this - // Component to alert a parent - // component when it's clicked on. + const onSquareClick = () => { + const updatedSquare = { + id: props.id, + value: props.value, + } + props.onUpdatedSquare(updatedSquare); + } return
- + +
); diff --git a/src/components/Board.js b/src/components/Board.js index 9b5c8f54..79285580 100644 --- a/src/components/Board.js +++ b/src/components/Board.js @@ -4,17 +4,17 @@ import Square from './Square'; import PropTypes from 'prop-types'; -const generateSquareComponents = (squares, onClickCallback) => { +// we de-structured here, so using squares.whatever instead of props.whatever +const SquareComponents = ( {squares, onClickCallback}) => { - const flattenSquares = squares.flat(); - const squareComponents = flattenSquares.map((square) => { + const squareComponents = squares.flat().map((square) => { return ( @@ -25,12 +25,10 @@ const generateSquareComponents = (squares, onClickCallback) => { }; - +// this is destructoring - takes the place of props (props.whatever) const Board = ({ squares, onClickCallback }) => { - const squareList = generateSquareComponents(squares, onClickCallback); - console.log(squareList); return
- {squareList} +
}; diff --git a/src/components/Square.js b/src/components/Square.js index 5a766370..061e02a4 100644 --- a/src/components/Square.js +++ b/src/components/Square.js @@ -4,17 +4,22 @@ import PropTypes from 'prop-types'; import './Square.css' const Square = (props) => { - const onSquareClick = () => { - const updatedSquare = { - id: props.id, - value: props.value, - } - props.onUpdatedSquare(updatedSquare); - } + // Wave e enable this Component to alert a parent +// component when it's clicked. + // const onSquareClick = () => { + // const updatedSquare = { + // id: props.id, + // value: props.value, + // } + // props.onUpdatedSquare(updatedSquare); + // } return } From 242b92951ed0aa0e09918c635670ced4829d1526 Mon Sep 17 00:00:00 2001 From: charlotte adams Date: Sat, 18 Apr 2020 17:19:22 -0700 Subject: [PATCH 3/8] create checkForWinner method --- src/App.js | 134 +++++++++++++++++++++++++-------------- src/components/Board.js | 4 +- src/components/Square.js | 17 +++-- 3 files changed, 95 insertions(+), 60 deletions(-) diff --git a/src/App.js b/src/App.js index eb80b5ff..e79399f5 100644 --- a/src/App.js +++ b/src/App.js @@ -1,10 +1,10 @@ -import React, { useState } from 'react'; -import './App.css'; +import React, { useState } from "react"; +import "./App.css"; -import Board from './components/Board'; +import Board from "./components/Board"; -const PLAYER_1 = 'X'; -const PLAYER_2 = 'O'; +const PLAYER_1 = "X"; +const PLAYER_2 = "O"; const generateSquares = () => { const squares = []; @@ -16,89 +16,125 @@ const generateSquares = () => { for (let col = 0; col < 3; col += 1) { squares[row].push({ id: currentId, - value: '', + value: "", }); currentId += 1; } } -// returns 2D array of objects -// an array of array of objects + // returns 2D array of objects + // an array of array of objects return squares; -} +}; const App = () => { - // useState(generateSquares) becomes the variable squares // useState is setting the initial state of the App component - // this is a 2D array of objects - // setSquares() is a function to update squares - use setSquares to reset game const [squares, setSquares] = useState(generateSquares()); + const [turn, setTurn] = useState(PLAYER_1); console.log(squares); let newSquares = []; const onClickCallback = (id) => { - for(let row = 0; row < squares.length; row++) { - newSquares.push([]) - for(let column = 0; column < squares.length; column++) { - let currentSquare = squares[row][column] - if(currentSquare.id === id) { - currentSquare.value = PLAYER_1; - }; + for (let row = 0; row < squares.length; row++) { + newSquares.push([]); + for (let column = 0; column < squares.length; column++) { + let currentSquare = squares[row][column]; + // find square by id + // update square value if square is empty + // set sqares to new squares + // use State to keep track of 'turns' and update square accordingly + if (currentSquare.id === id && currentSquare.value === "") { + currentSquare.value = turn; + if (turn === PLAYER_2) { + setTurn(PLAYER_1); + } else if (turn === PLAYER_1) { + setTurn(PLAYER_2); + } + } newSquares[row].push(currentSquare); + } + } - }; - }; - - // find square by id - // update value to Player 1 - // set sqares to new updated squares - - - - - - - // define 2D array to represent the new game state - // this is an example but it's not 'right' line 40 - // do not worry about taking turns just yet. - // set this up using Player 1 first. every click is Player 1. - // const newSquares = []; setSquares(newSquares); - console.log('clicking', id); + console.log("clicking", id); }; - + // const onClickCallback = (event) => { // setSquares(event.target.value); // }; - // Wave 2 - // You will need to create a method to change the square - // When it is clicked on. - // Then pass it into the squares as a callback + const checkRow = () => { + console.log("this is inside checkRow") + for (let row = 0; row < squares.length; row++) { + let counter = 0; + for (let column = 0; column < squares.length; column++) { + if (squares[row][column].value === turn) { + counter++; + } + } + if (counter === 3) { + return true; + }; + }; + }; + + const checkDiagonals = () => { + const winnerL = squares[0][0].value; + const winnerR = squares[0][2].value; + if(squares[0][0].value === squares[1][1].value && squares[0][0].value === squares[2][2].value && squares[0][0].value !== ' ') { + return winnerL; + + }else if(squares[0][2].value === squares[1][1].value && squares[0][2].value === squares[2][2].value && squares[0][2] !== '' ) { + return winnerR; + + }; + }; + + const checkColumn = () => { + for(let row = 0; row < squares.length; row++) { + let counter = 0; + for( let column = 0; column < squares.length; column++) { + if(squares[column][row].value === turn) { + counter++; + } + } + if (counter === 3) { + return true; + } + } + }; const checkForWinner = () => { + // pass in a ->"turn" on line 77 + // check row - // Complete in Wave 3 + if (checkRow(turn === PLAYER_1)) { + return turn; + }; + checkDiagonals(); + }; + console.log(checkForWinner()); - } - const resetGame = () => { - // Complete in Wave 4 - } + // const resetGame = () => { + // // Complete in Wave 4 + // // setSquares() is a function to update squares - use setSquares to reset game + + // }; return (

React Tic Tac Toe

The winner is ... -- Fill in for wave 3

- {/* this button needs an onClick */} + {/* this button needs an onClick */}
-
); -} +}; export default App; diff --git a/src/components/Board.js b/src/components/Board.js index 79285580..d3b6b7db 100644 --- a/src/components/Board.js +++ b/src/components/Board.js @@ -7,7 +7,7 @@ import PropTypes from 'prop-types'; // we de-structured here, so using squares.whatever instead of props.whatever const SquareComponents = ( {squares, onClickCallback}) => { - const squareComponents = squares.flat().map((square) => { + const generateSquareComponents = squares.flat().map((square) => { return ( { ); }); - return squareComponents; + return generateSquareComponents; }; diff --git a/src/components/Square.js b/src/components/Square.js index 061e02a4..56534d0b 100644 --- a/src/components/Square.js +++ b/src/components/Square.js @@ -4,15 +4,14 @@ import PropTypes from 'prop-types'; import './Square.css' const Square = (props) => { - // Wave e enable this Component to alert a parent -// component when it's clicked. - // const onSquareClick = () => { - // const updatedSquare = { - // id: props.id, - // value: props.value, - // } - // props.onUpdatedSquare(updatedSquare); - // } + + const onSquareClick = () => { + const updatedSquare = { + id: props.id, + value: props.value, + } + props.onUpdatedSquare(updatedSquare); + } return diff --git a/src/components/Square.js b/src/components/Square.js index 56534d0b..e1a3f036 100644 --- a/src/components/Square.js +++ b/src/components/Square.js @@ -5,13 +5,13 @@ import './Square.css' const Square = (props) => { - const onSquareClick = () => { - const updatedSquare = { - id: props.id, - value: props.value, - } - props.onUpdatedSquare(updatedSquare); - } + // const onSquareClick = () => { + // const updatedSquare = { + // id: props.id, + // value: props.value, + // } + // props.onUpdatedSquare(updatedSquare); + // } return +
From 400e64429c6cb8bd599976034bc770171ad6507b Mon Sep 17 00:00:00 2001 From: charlotte adams Date: Sun, 19 Apr 2020 13:46:53 -0700 Subject: [PATCH 6/8] fix resetGame bug by passing PLAYER_1 into setTurn in resetGame and configure elsint --- .eslintrc.js | 26 ++++++++++++++ package-lock.json | 20 +++++------ package.json | 2 ++ src/App.js | 92 ++++++++++++++--------------------------------- 4 files changed, 65 insertions(+), 75 deletions(-) create mode 100644 .eslintrc.js diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 00000000..5df66924 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,26 @@ +module.exports = { + "env": { + "browser": true, + "es6": true + }, + "extends": [ + "eslint:recommended", + "plugin:react/recommended" + ], + "globals": { + "Atomics": "readonly", + "SharedArrayBuffer": "readonly" + }, + "parserOptions": { + "ecmaFeatures": { + "jsx": true + }, + "ecmaVersion": 2018, + "sourceType": "module" + }, + "plugins": [ + "react" + ], + "rules": { + } +}; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index d48a310f..8f4f8f97 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5024,9 +5024,9 @@ } }, "resolve": { - "version": "1.15.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", - "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.16.1.tgz", + "integrity": "sha512-rmAglCSqWWMrrBv/XM6sW0NuRFiKViw/W4d9EbC4pt+49H8JwHy+mcGmALTEg504AUDcLTvb1T2q3E9AnmY+ig==", "requires": { "path-parse": "^1.0.6" } @@ -5076,17 +5076,17 @@ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" }, "esquery": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.0.tgz", - "integrity": "sha512-/5qB+Mb0m2bh86tjGbA8pB0qBfdmCIK6ZNPjcw4/TtEH0+tTf0wLA5HK4KMTweSMwLGHwBDWCBV+6+2+EuHmgg==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", + "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", "requires": { - "estraverse": "^5.0.0" + "estraverse": "^5.1.0" }, "dependencies": { "estraverse": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.0.0.tgz", - "integrity": "sha512-j3acdrMzqrxmJTNj5dbr1YbjacrYgAxVMeF0gK16E3j494mOe7xygM/ZLIguEQ0ETwAg2hlJCtHRGav+y0Ny5A==" + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.1.0.tgz", + "integrity": "sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw==" } } }, diff --git a/package.json b/package.json index 92da3af2..f67eddc3 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,8 @@ ] }, "devDependencies": { + "eslint": "^6.8.0", + "eslint-plugin-react": "^7.19.0", "gh-pages": "^2.2.0" } } diff --git a/src/App.js b/src/App.js index 3ca100c8..3c689716 100644 --- a/src/App.js +++ b/src/App.js @@ -10,7 +10,7 @@ const generateSquares = () => { const squares = []; let currentId = 0; - +console.log("generate squares"); for (let row = 0; row < 3; row += 1) { squares.push([]); for (let col = 0; col < 3; col += 1) { @@ -23,6 +23,8 @@ const generateSquares = () => { } // returns 2D array of objects // an array of array of objects + console.log("squares"); + console.log(squares); return squares; }; @@ -35,7 +37,7 @@ const App = () => { let newSquares = []; const onClickCallback = (id) => { - if(winner) { return }; + if(winner) { return } for (let row = 0; row < squares.length; row++) { newSquares.push([]); for (let column = 0; column < squares.length; column++) { @@ -55,29 +57,9 @@ const App = () => { newSquares[row].push(currentSquare); } } - setSquares(newSquares); }; - - // const onClickCallback = (event) => { - // setSquares(event.target.value); - // }; - - - // const checkRow = () => { - // console.log("this is inside checkRow") - // for (let row = 0; row < squares.length; row++) { - // let counter = 0; - // for (let column = 0; column < squares.length; column++) { - // if (squares[row][column].value === turn) { - // counter++; - // } - // } - // if (counter === 3) { - // return true; - // }; - // }; - // }; + const checkForWinner = () => { // Complete in Wave 3 checkRowsandColumns(); @@ -85,23 +67,22 @@ const App = () => { checkForTie(); }; - useEffect(() => { - checkForWinner(); - }); - - const checkForTie = () => { - if(winner) { return }; - for(let i = 0; i < squares.length; i++){ - for(let j = 0; j < squares.length; j++){ - if(squares[i][j].value === '') { - return; - }; - }; - }; - setWinner('...There is no winner! It\'s a Tie!'); - }; - + useEffect(() => { + checkForWinner(); + }); + const checkForTie = () => { + if(winner) { return } + for(let i = 0; i < squares.length; i++){ + for(let j = 0; j < squares.length; j++){ + if(squares[i][j].value === '') { + return; + } + } + } + setWinner('...There is no winner! It\'s a Tie!'); + }; + const checkDiagonals = () => { if(squares[0][0].value === squares[1][1].value && squares[0][0].value === squares[2][2].value && squares[0][0].value !== '') { @@ -110,10 +91,9 @@ const App = () => { }else if(squares[0][2].value === squares[1][1].value && squares[0][2].value === squares[2][0].value && squares[0][2].value !== '') { setWinner(squares[0][2].value); - }; + } }; - - + const checkRowsandColumns = () => { for(let i = 0; i < squares.length; i++){ for(let j = 0; j < squares.length; j++){ @@ -122,36 +102,18 @@ const App = () => { setWinner(squares[i][0].value); }else if(squares[0][j].value === squares[1][j].value && squares[0][j].value === squares[2][j].value && squares[0][j].value !== '') setWinner(squares[0][j].value); - }; - }; + } + } }; - - // const checkColumn = () => { - // for(let row = 0; row < squares.length; row++) { - // let counter = 0; - // for( let column = 0; column < squares.length; column++) { - // if(squares[column][row].value === turn) { - // counter++; - // } - // } - // if (counter === 3) { - // return true; - // } - // } - // }; - - - - // let winner = checkforWinner(); - - + const resetGame = () => { // Complete in Wave 4 setSquares(generateSquares()); - setTurn(); + setTurn(PLAYER_1); setWinner(); }; + return (
From 1ae7c39825133cea83762957da9e7d81d6897b6a Mon Sep 17 00:00:00 2001 From: charlotte adams Date: Sun, 19 Apr 2020 17:50:47 -0700 Subject: [PATCH 7/8] remove comments, clean file --- src/App.js | 16 ++++------------ src/components/Board.js | 9 +++------ src/components/Square.js | 14 +++----------- 3 files changed, 10 insertions(+), 29 deletions(-) diff --git a/src/App.js b/src/App.js index 3c689716..e9b294c9 100644 --- a/src/App.js +++ b/src/App.js @@ -10,7 +10,6 @@ const generateSquares = () => { const squares = []; let currentId = 0; -console.log("generate squares"); for (let row = 0; row < 3; row += 1) { squares.push([]); for (let col = 0; col < 3; col += 1) { @@ -21,16 +20,10 @@ console.log("generate squares"); currentId += 1; } } - // returns 2D array of objects - // an array of array of objects - console.log("squares"); - console.log(squares); return squares; }; const App = () => { - // useState(generateSquares) becomes the variable squares - // useState is setting the initial state of the App component const [squares, setSquares] = useState(generateSquares()); const [turn, setTurn] = useState(PLAYER_1); const [winner, setWinner] = useState(); @@ -42,10 +35,6 @@ const App = () => { newSquares.push([]); for (let column = 0; column < squares.length; column++) { let currentSquare = squares[row][column]; - // find square by id - // update square value if square is empty - // set sqares to new squares - // use State to keep track of 'turns' and update square accordingly if (currentSquare.id === id && currentSquare.value === "") { currentSquare.value = turn; if (turn === PLAYER_2) { @@ -66,7 +55,10 @@ const App = () => { checkDiagonals(); checkForTie(); }; - + // https://reactjs.org/docs/hooks-effect.html + // JavaScript was completing b/4 React could update the DOM. + // Implementing useEffect allows the program to + // perform our effects after React has updated the DOM. useEffect(() => { checkForWinner(); }); diff --git a/src/components/Board.js b/src/components/Board.js index d3b6b7db..59572372 100644 --- a/src/components/Board.js +++ b/src/components/Board.js @@ -4,7 +4,7 @@ import Square from './Square'; import PropTypes from 'prop-types'; -// we de-structured here, so using squares.whatever instead of props.whatever +// We de-structured here, so using squares.whatever instead of props.whatever const SquareComponents = ( {squares, onClickCallback}) => { const generateSquareComponents = squares.flat().map((square) => { @@ -15,17 +15,14 @@ const SquareComponents = ( {squares, onClickCallback}) => { value={square.value} key={square.id} onClickCallback={onClickCallback} - - /> - + /> ); }); return generateSquareComponents; }; - -// this is destructoring - takes the place of props (props.whatever) +// This is destructoring - takes the place of props.whatever const Board = ({ squares, onClickCallback }) => { return
diff --git a/src/components/Square.js b/src/components/Square.js index e1a3f036..f2bd5d9d 100644 --- a/src/components/Square.js +++ b/src/components/Square.js @@ -5,19 +5,11 @@ import './Square.css' const Square = (props) => { - // const onSquareClick = () => { - // const updatedSquare = { - // id: props.id, - // value: props.value, - // } - // props.onUpdatedSquare(updatedSquare); - // } - return From 6b23da9693c3789c0d34559b0d38ea4562295587 Mon Sep 17 00:00:00 2001 From: charlotte adams Date: Sun, 19 Apr 2020 18:33:17 -0700 Subject: [PATCH 8/8] a final clean --- src/components/Board.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Board.js b/src/components/Board.js index 59572372..4f0fde50 100644 --- a/src/components/Board.js +++ b/src/components/Board.js @@ -4,7 +4,7 @@ import Square from './Square'; import PropTypes from 'prop-types'; -// We de-structured here, so using squares.whatever instead of props.whatever +// Destructuring here, so using squares.whatever instead of props.whatever const SquareComponents = ( {squares, onClickCallback}) => { const generateSquareComponents = squares.flat().map((square) => { @@ -22,7 +22,7 @@ const SquareComponents = ( {squares, onClickCallback}) => { return generateSquareComponents; }; -// This is destructoring - takes the place of props.whatever +// Destructuring here - takes the place of props.whatever const Board = ({ squares, onClickCallback }) => { return