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
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
"@testing-library/user-event": "^12.5.0",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-scripts": "4.0.3"
"react-scripts": "4.0.3",
"requirements": "^1.4.1"
},
"homepage": "http://adagold.github.io/react-tic-tac-toe",
"scripts": {
Expand Down
109 changes: 88 additions & 21 deletions src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import React, { useState } from 'react';
import './App.css';

import Board from './components/Board';
import Square from './components/Square';

const PLAYER_1 = 'X';
const PLAYER_2 = 'O';
const PLAYER_1 = 'x';
const PLAYER_2 = 'o';

const generateSquares = () => {
const squares = [];
Expand All @@ -28,38 +29,104 @@ const generateSquares = () => {
const App = () => {
// This starts state off as a 2D array of JS objects with
// empty value and unique ids.
const [squares, setSquares] = useState(generateSquares());
const [squares, updateSquares] = useState(generateSquares());
// keeping track of players
const [currentPlayer, setCurrentPlayer] = useState(PLAYER_1);
// find winner
const [winner, setWinner] = useState(null);

// 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 checkSquare = (id) => {
for (let row of squares) {

Choose a reason for hiding this comment

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

Since you don't have a check to see if there is a winner here users can continue to fill in squares after the game has ended.

for (let square of row) {
if (square.id === id && square.value === '') {
if (currentPlayer === PLAYER_1) {
square.value = PLAYER_1;
} else if (currentPlayer === PLAYER_2) {
square.value = PLAYER_2;
}
if (currentPlayer === PLAYER_1) {
setCurrentPlayer(PLAYER_2);
} else {
setCurrentPlayer(PLAYER_1);
}
console.log({ squareId: id });
}
}
}
const squareCopy = [...squares];
updateSquares(squareCopy);
setWinner(checkForWinner());
return id;
};

const checkForWinner = () => {
// Complete in Wave 3
// You will need to:
// 1. Go accross each row to see if
// 3 squares in the same row match
// i.e. same value
// 2. Go down each column to see if
// 3 squares in each column match
// 3. Go across each diagonal to see if
// all three squares have the same value.
};
let i = 0;
// Check all the rows and columns for a winner
while (i < 3) {
if (
squares[i][0].value === squares[i][1].value &&
squares[i][2].value === squares[i][1].value &&
squares[i][0].value !== ''
) {
return squares[i][0].value;
} else if (
squares[0][i].value === squares[1][i].value &&
squares[2][i].value === squares[1][i].value &&
squares[0][i].value !== ''
) {
return squares[0][i].value;
}
i += 1;
}
if (
squares[0][0].value === squares[1][1].value &&
squares[2][2].value === squares[1][1].value &&
squares[1][1].value !== ''
) {
return squares[0][0].value;
}

const resetGame = () => {
// Complete in Wave 4
if (
squares[0][2].value === squares[1][1].value &&
squares[2][0].value === squares[1][1].value &&
squares[1][1].value !== ''
) {
return squares[0][2].value;
}
//check for Tie
const playsCheck = { PLAYER_1: 0, PLAYER_2: 0 };
for (let row of squares) {
for (let play of row) {
playsCheck[play]++;
}
if (playsCheck[PLAYER_1] === 5 || playsCheck[PLAYER_2] === 5) {
return 'tie';
}
}
return null;
};

// Complete in Wave 3
// You will need to:
// 1. Go accross each row to see if
// 3 squares in the same row match
// i.e. same value
// 2. Go down each column to see if
// 3 squares in each column match
// 3. Go across each diagonal to see if
// all three squares have the same value.



return (
<div className="App">
<header className="App-header">
<h1>React Tic Tac Toe</h1>
<h2>The winner is ... -- Fill in for wave 3 </h2>
<h2>Winner is {winner} </h2>
<button>Reset Game</button>
</header>
<main>
<Board squares={squares} />
<Board squares={squares} onClickCallback={checkSquare} />
</main>
</div>
);
Expand Down
29 changes: 21 additions & 8 deletions src/components/Board.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,42 @@ import './Board.css';
import Square from './Square';
import PropTypes from 'prop-types';


const generateSquareComponents = (squares, onClickCallback) => {
// Complete this for Wave 1
// squares is a 2D Array, but
// squares is a 2D Array, but
// you need to return a 1D array
// of square components
// itterate over 2D array and return 1D
const squareComponents = [];
for (let innerSquares of squares) {
for (let square of innerSquares) {
squareComponents.push(
<Square
key={square.id}
value={square.value}
id={square.id}
onClickCallback={onClickCallback}
/>
);
}
}
return squareComponents;
};


}

const Board = ({ squares, onClickCallback }) => {
const squareList = generateSquareComponents(squares, onClickCallback);
console.log(squareList);
return <div className="grid" >
{squareList}
</div>
}
return <div className="grid">{squareList}</div>;
};

Board.propTypes = {
squares: PropTypes.arrayOf(
PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.number.isRequired,
value: PropTypes.string.isRequired
value: PropTypes.string.isRequired,
})
)
),
Expand Down
29 changes: 23 additions & 6 deletions src/components/Square.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,33 @@ 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 checkSquareButton = () => {
// const updatedSquare = {
// id: props.id,
// value: props.value,
// }; props.onClickCallback(props.id)
// }
// return <button onClick= {checkSquareButton}
// className="square"
// >
// {props.value}
// </button>
// };
//make the function that calls the event handler defined in app and give it props
const clickSquareButton = () => {
props.onClickCallback(props.id);
};

return <button
className="square"
>
{props.value}
</button>
}
//this is a button...
//Our square IS the button styled by the CSS corresponding to our class name
//props.value being sent is telling us to render x, o, or nothing on click
//step 4: create the event listener onClick and set it equal to the function that handles it
return <button className="square" onClick={clickSquareButton}>{props.value}</button>;
};

Square.propTypes = {
value: PropTypes.string.isRequired,
Expand Down
Loading