-
Notifications
You must be signed in to change notification settings - Fork 80
Rae and Mac Tic Tac Toe #65
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
10a4104
fcef362
ec8d836
e22ef17
640db06
b2f6f81
ac33c8d
7a0113b
ca612b4
37c59de
52a342e
176b9bd
9a98228
c8f05b4
8cf2acb
59e4606
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
theme: jekyll-theme-cayman |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,12 @@ | ||
import React, { useState } from 'react'; | ||
import './App.css'; | ||
|
||
import Board from './components/Board'; | ||
import matthew from './img/matthewface.png'; | ||
import junior from './img/juniorface.jpg'; | ||
Comment on lines
+4
to
+5
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💜 |
||
|
||
const PLAYER_1 = 'X'; | ||
const PLAYER_2 = 'O'; | ||
const PLAYER_1 = <img src={matthew} alt="X" />; | ||
const PLAYER_2 = <img src={junior} alt="O" />; | ||
Comment on lines
+7
to
+8
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the future, consider having further separation between data and presentation. Keeping the variables as |
||
let totalMoves = 0; | ||
|
||
const generateSquares = () => { | ||
const squares = []; | ||
|
@@ -26,40 +28,81 @@ const generateSquares = () => { | |
}; | ||
|
||
const App = () => { | ||
// This starts state off as a 2D array of JS objects with | ||
// empty value and unique ids. | ||
const resetCombos = () => { | ||
return { | ||
c048: [], | ||
c012: [], | ||
c345: [], | ||
c678: [], | ||
c036: [], | ||
c147: [], | ||
c258: [], | ||
c642: [], | ||
}; | ||
}; | ||
Comment on lines
+32
to
+42
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Very interesting method of tracking combos! In the future, consider adding a comment to explain how unconventional data structures like this are meant to be used so the code is easier to read. |
||
|
||
const [squares, setSquares] = useState(generateSquares()); | ||
const [player, setPlayer] = useState(true); | ||
const [winner, setWinner] = useState(null); | ||
const [trackCombos, setTrackCombos] = useState(resetCombos()); | ||
|
||
const updateSquares = (id) => { | ||
totalMoves++; | ||
const updatedSquareData = squares.map((row) => { | ||
return row.map((square) => { | ||
if (square.id === id) { | ||
if (player) { | ||
square.value = PLAYER_1; | ||
checkForWinner(square.id, square.value); | ||
} else { | ||
square.value = PLAYER_2; | ||
checkForWinner(square.id, square.value); | ||
} | ||
} | ||
return square; | ||
}); | ||
}); | ||
Comment on lines
+51
to
+64
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice use of nested maps |
||
|
||
setSquares(updatedSquareData); | ||
setPlayer(!player); | ||
}; | ||
|
||
// 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 checkForWinner = (id, value) => { | ||
for (let key in trackCombos) { | ||
if (key.includes(id)) { | ||
trackCombos[key].push(value); | ||
|
||
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. | ||
if (trackCombos[key].length === 3) { | ||
if (new Set(trackCombos[key]).size === 1) { | ||
setWinner(value); | ||
} | ||
} | ||
if (totalMoves === 9) { | ||
setWinner('Tie!'); | ||
} | ||
} | ||
} | ||
}; | ||
|
||
const resetGame = () => { | ||
// Complete in Wave 4 | ||
setSquares(generateSquares()); | ||
setTrackCombos(resetCombos); | ||
totalMoves = 0; | ||
setPlayer(true); | ||
setWinner(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> | ||
<h1>Tic Tac Toebeans</h1> | ||
<h2>The winner is ... {winner}</h2> | ||
<button className="button" onClick={resetGame}> | ||
Start Over | ||
</button> | ||
</header> | ||
<main> | ||
<Board squares={squares} /> | ||
<Board squares={squares} updateSquares={updateSquares} /> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice job passing down callback |
||
</main> | ||
</div> | ||
); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,12 @@ | ||
div.grid { | ||
width: 600px; | ||
height: 600px; | ||
margin: 0 auto; | ||
background-color: #34495e; | ||
color: #fff; | ||
border: 6px solid #2c3e50; | ||
border-radius: 10px; | ||
display: grid; | ||
grid-template: repeat(3, 1fr) / repeat(3, 1fr); | ||
width: 500px; | ||
height: 500px; | ||
margin: 0 auto; | ||
background-color: transparent; | ||
color: #000000; | ||
|
||
border: 3px solid #000000; | ||
border-radius: 10px; | ||
display: grid; | ||
grid-template: repeat(3, 1fr) / repeat(3, 1fr); | ||
Comment on lines
+10
to
+11
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 😻 |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,33 +3,44 @@ import './Board.css'; | |
import Square from './Square'; | ||
import PropTypes from 'prop-types'; | ||
|
||
const generateSquareComponents = (squares, updateSquares) => { | ||
const singleArray = []; | ||
|
||
const generateSquareComponents = (squares, onClickCallback) => { | ||
// Complete this for Wave 1 | ||
// squares is a 2D Array, but | ||
// you need to return a 1D array | ||
// of square components | ||
for (let subArray = 0; subArray < squares.length; subArray++) { | ||
squares[subArray].forEach((square) => { | ||
singleArray.push(square); | ||
}); | ||
} | ||
|
||
} | ||
const squaresArray = singleArray.map((square) => { | ||
return ( | ||
<Square | ||
key={square.id} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good job remembering |
||
id={square.id} | ||
value={square.value} | ||
updateSquares={updateSquares} | ||
></Square> | ||
); | ||
}); | ||
return squaresArray; | ||
}; | ||
|
||
const Board = ({ squares, updateSquares }) => { | ||
const squareList = generateSquareComponents(squares, updateSquares); | ||
|
||
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.any.isRequired, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good job updating prop types! A more specific type you may have considered here is |
||
}) | ||
) | ||
), | ||
onClickCallback: PropTypes.func.isRequired, | ||
updateSquares: PropTypes.func.isRequired, | ||
}; | ||
|
||
export default Board; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,14 @@ | ||
.square | ||
{ | ||
border: 4px solid #2c3e50; | ||
border-radius: 2px; | ||
font-family: Helvetica; | ||
@import url('https://fonts.googleapis.com/css2?family=Rock+3D&display=swap'); | ||
|
||
.square { | ||
background-color: transparent; | ||
border: 3px solid #000000; | ||
border-radius: 4px; | ||
font-family: 'Rock 3D'; | ||
font-weight: bold; | ||
font-size: 8em; | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
margin: 2px; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,27 @@ | ||
import React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import './Square.css'; | ||
|
||
import './Square.css' | ||
|
||
const Square = (props) => { | ||
// For Wave 1 enable this | ||
// Component to alert a parent | ||
const Square = ({ id, value, updateSquares }) => { | ||
// For Wave 1 enable this | ||
// Component to alert a parent | ||
// component when it's clicked on. | ||
|
||
return <button | ||
className="square" | ||
> | ||
{props.value} | ||
</button> | ||
} | ||
return ( | ||
<button | ||
className="square" | ||
onClick={() => { | ||
updateSquares(id); | ||
}} | ||
Comment on lines
+13
to
+15
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice use of anonymous function. |
||
> | ||
{value} | ||
</button> | ||
); | ||
}; | ||
|
||
Square.propTypes = { | ||
value: PropTypes.string.isRequired, | ||
onClickCallback: PropTypes.func.isRequired, | ||
value: PropTypes.any.isRequired, | ||
updateSquares: PropTypes.func.isRequired, | ||
id: PropTypes.number.isRequired, | ||
}; | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider using named colors if the RGB vals exactly match one. For example,
rgb(0, 0, 0)
is the same asblack
.