Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# React Tic Tac Toe

deployed: https://katemyer.github.io/react-tic-tac-toe/
## At A Glance

- Individual [Stage 2 project](https://github.com/Ada-Developers-Academy/pedagogy/blob/master/classroom/rule-of-three.md#stage-2)
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"react-dom": "^16.13.1",
"react-scripts": "3.4.1"
},
"homepage": "http://adagold.github.io/react-tic-tac-toe",
"homepage": "http://katemyer.github.io/react-tic-tac-toe",
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
Expand Down
124 changes: 118 additions & 6 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,33 +26,145 @@ const generateSquares = () => {
}

const App = () => {

//useState here when need to impact the UI and to re-render
//https://github.com/Ada-Developers-Academy/textbook-curriculum/blob/master/React/events.md
const [squares, setSquares] = useState(generateSquares());
const [currentPlayer, setCurrentPlayer] = useState(PLAYER_1);
const [currentWinner, setCurrentWinner] = useState(null);
Comment on lines 31 to +33

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍


// 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 onClickCallback = (id) => {
//check if a winner is set
if (currentWinner !== null){
//if there is a winner, break therefore do not update squares
return;
}
// id is the id of the square that is being updated
// find the id in squares
//id = 8 = squares[2][2].id
//console.log(id)
// https://stackoverflow.com/questions/42037369/how-to-edit-an-item-in-a-state-array
const copySquares = squares.slice()
for (let row = 0; row < copySquares.length; row += 1) {
for (let col = 0; col < copySquares[0].length; col += 1) {
let currentId=copySquares[row][col].id
//check if ids match
if (id === currentId) {
//check if value is not empty, prevent being overriden
if (copySquares[row][col].value !== '') return;
// update the value of the square to currentPlayer
copySquares[row][col].value = currentPlayer
// update squares = set and refresh page
setSquares(copySquares)
// after updating board, check for win
console.log(checkForWinner())
//then check is board is filled
console.log(`is filled ${isSquaresFilled()}`)
// set to next player
if (currentPlayer===PLAYER_1) {
setCurrentPlayer(PLAYER_2)
}
else {
setCurrentPlayer(PLAYER_1)
}
Comment on lines +68 to +73

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a suggestion

Suggested change
if (currentPlayer===PLAYER_1) {
setCurrentPlayer(PLAYER_2)
}
else {
setCurrentPlayer(PLAYER_1)
}
const next_player = currentPlayer === PLAYER_1 ? PLAYER_2: Player_1
setCurrentPlayer(next_player)

return;
}
}
}
};

const checkForWinner = () => {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

// Complete in Wave 3
//check for row winners, example = 'ooo'
//loop through each row
let winner = null
for (let row = 0; row < squares.length; row += 1){
//check if each column in this row equals one another
if (squares[row][0].value === squares[row][1].value && squares[row][0].value === squares[row][2].value && squares[row][0].value !== ''){
//if true, winner based on value, ex: x
winner = squares[row][2].value;
//update squares = set and refresh page and checking for winner
setCurrentWinner(winner)
//stop evaluating other combinations, return winner
return winner
}
}
//check column winners
for (let col = 0; col < 3; col += 1) {
//check if each row in this colum equals one another
if(squares[0][col].value === squares[1][col].value && squares[0][col].value === squares[2][col].value && squares[0][col].value !== ''){
//if true, winner based on value
winner = squares[0][col].value;
//update squares to set and refresh page to check for winner
setCurrentWinner(winner)
return winner
}
}
//check diagonal winner
if (squares[0][0].value === squares[1][1].value
&& squares[2][2].value === squares[0][0].value
&& squares[0][0].value !== ''){
winner = squares[0][0].value;
setCurrentWinner(winner)
return winner
}
else if (squares[2][0].value === squares[1][1].value
&& squares[0][2].value === squares[2][0].value
&& squares[2][0].value !== ''){
winner = squares[2][0].value;
setCurrentWinner(winner)
return winner
}
//check ties
//if all squares are filled, there are no winners
if (isSquaresFilled() && winner === null) {
setCurrentWinner('no winner, tied')
}
return winner
}


const isSquaresFilled = () => {
let isFilled = true;
//turn squares array from 2d to 1d:https://stackoverflow.com/questions/14824283/convert-a-2d-javascript-array-to-a-1d-array
let squaresflat = [].concat(...squares);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can also do:

Suggested change
let squaresflat = [].concat(...squares);
let squaresflat = squares.flat()

//loop through squares
for (let i in squaresflat) {
let square = squaresflat[i];
//check if value is ''
if (square.value === ''){
//if true, there is a value
return false;
}
}
return isFilled
}

const resetGame = () => {
// Complete in Wave 4

const onClickResetGame = () => {
// Complete in Wave 4: resetting all states
// reset setSquares to default generateSquares());
setSquares(generateSquares())
//reset setcurrentPlayer to default PLAYER_1
setCurrentPlayer(PLAYER_1)
//reset currentWinner
setCurrentWinner(null)
}

return (
<div className="App">
<header className="App-header">
<h1>React Tic Tac Toe</h1>
<h2>The winner is ... -- Fill in for wave 3 </h2>
<button>Reset Game</button>
<h2>The winner is {currentWinner} </h2>
<h3> Current Player {currentPlayer} </h3>
<button onClick={onClickResetGame}>Reset Game</button>
</header>
<main>
<Board squares={squares} />
<Board squares={squares} onClickCallback={onClickCallback} />
</main>
</div>
);
Expand Down
23 changes: 22 additions & 1 deletion src/components/Board.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,31 @@ import './Board.css';
import Square from './Square';
import PropTypes from 'prop-types';


// description: generate list of Square Components
// param squares : 2d array
// param onClickCallback : callback function
// returns listofsquares : list of Square Components
const generateSquareComponents = (squares, onClickCallback) => {
// Complete this for Wave 1
//squares is a 2D array
//create an array
let listofsquares = []
//populate rows by looping through rows based on squares.length
for (let row = 0; row < squares.length; row += 1) {
//populate colums by looping through columns based on squares
for (let col = 0; col < squares[0].length; col += 1) {
//push Square component coming from Square.js into listofsquares array
//Square comp needs id, value, and onClickCallback
//set Square components .proptypes bc Square.js requires this
let id=squares[row][col].id
let value=squares[row][col].value
listofsquares.push(<Square id={id} value={value} onClickCallback={onClickCallback}/>)
}
}


//return
return listofsquares
}

const Board = ({ squares, onClickCallback }) => {
Expand Down
12 changes: 7 additions & 5 deletions src/components/Square.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
import React from 'react';
import PropTypes from 'prop-types';
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.


return <button
className="square"
>
return <button onClick={() => {props.onClickCallback(props.id)}} className="square">
{props.value}
</button>
}



Square.propTypes = {
value: PropTypes.string.isRequired,
onClickCallback: PropTypes.func.isRequired,
id: PropTypes.number.isRequired,
};

export default Square
export default Square