-
Notifications
You must be signed in to change notification settings - Fork 80
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
Cedar - Kit/Laurel #59
base: main
Are you sure you want to change the base?
Changes from all commits
683ac4d
3fe20c1
8ec51d9
7551f8c
e40aebd
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 |
---|---|---|
|
@@ -3,8 +3,8 @@ import './App.css'; | |
|
||
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 = []; | ||
|
@@ -26,40 +26,114 @@ 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()); | ||
|
||
// 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 [squares, setSquares] = useState(generateSquares()); | ||
const[winner, setWinner] = useState(null); | ||
const [currentPlayer, setCurrentPlayer] = useState(PLAYER_1); | ||
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; | ||
while (i < 3) { | ||
Comment on lines
+34
to
+35
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. Consider using a |
||
// Check all the rows and columns for a winner | ||
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; | ||
} | ||
// Check Top-Left to bottom-right diagonal | ||
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; | ||
} | ||
|
||
// Check Top-right to bottom-left diagonal | ||
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; | ||
} | ||
|
||
return null; | ||
}; | ||
|
||
const onClickCallback = (id) => { | ||
setSquares((squares) => { | ||
console.log(`squares in callback: ${squares}`) | ||
let newBoard = squares.map((square)=>{ | ||
for (let property of square){ | ||
if (property.id === id && property.value === ''){ | ||
if (currentPlayer === PLAYER_1){ | ||
property.value = PLAYER_1; | ||
|
||
} else if (currentPlayer === PLAYER_2){ | ||
property.value = PLAYER_2; | ||
} | ||
} | ||
} | ||
return square; | ||
}); | ||
Comment on lines
+76
to
+88
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 map! |
||
|
||
//CHECK FOR WINNER HERE | ||
setWinner(checkForWinner()); | ||
|
||
return newBoard; | ||
}); | ||
//CHANGE PLAYER | ||
if (currentPlayer === PLAYER_1) { | ||
setCurrentPlayer(PLAYER_2); | ||
}else { | ||
setCurrentPlayer(PLAYER_1) | ||
} | ||
|
||
}; | ||
|
||
|
||
|
||
const resetGame = () => { | ||
// Complete in Wave 4 | ||
setSquares(generateSquares()); | ||
setWinner(null); | ||
setCurrentPlayer(PLAYER_1); | ||
}; | ||
|
||
|
||
let header; | ||
let boardCallback; | ||
// let finalWinner; | ||
if (winner != null) { | ||
// if (winner === PLAYER_1) { | ||
// finalWinner = 'Player 1'; | ||
// } else { | ||
// finalWinner = 'Player 2'; | ||
// } | ||
header = <h2>Winner is {winner}</h2>; | ||
} else { | ||
header = <h2>The Current Player is {currentPlayer}</h2>; | ||
boardCallback = onClickCallback; | ||
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. Because this callback is only set if there's not a winner weird bugs can arise. For example, if someone wins the game, and then a square is clicked again, your whole React app will crash (not even the reset button will work anymore). Consider ways you can resolve this by always passing a callback but having it do different things if the game is won or not. |
||
} | ||
|
||
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> | ||
{header} | ||
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 state! |
||
<button onClick = {resetGame} >Reset Game</button> | ||
</header> | ||
<main> | ||
<Board squares={squares} /> | ||
<Board squares={squares} onClickCallback={boardCallback}/> | ||
</main> | ||
</div> | ||
); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,20 +5,26 @@ import PropTypes from 'prop-types'; | |
|
||
|
||
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 | ||
|
||
} | ||
|
||
const singleSquares = [].concat(...squares); | ||
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. This can be done slightly simpler with |
||
return ( | ||
singleSquares.map((square) => { | ||
return ( | ||
<Square value={square.value} | ||
id={square.id} | ||
onClickCallback={onClickCallback} | ||
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 to use |
||
/> | ||
); | ||
})); | ||
}; | ||
|
||
const Board = ({ squares, onClickCallback }) => { | ||
const squareList = generateSquareComponents(squares, onClickCallback); | ||
console.log(squareList); | ||
return <div className="grid" > | ||
{squareList} | ||
</div> | ||
} | ||
</div>; | ||
}; | ||
|
||
Board.propTypes = { | ||
squares: PropTypes.arrayOf( | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,16 +4,17 @@ 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 hardestButtonToButton = () => { | ||
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. Fun function name 😛 |
||
props.onClickCallback(props.id) | ||
}; | ||
return <button | ||
className="square" | ||
onClick ={hardestButtonToButton} | ||
> | ||
{props.value} | ||
</button> | ||
} | ||
</button>; | ||
}; | ||
|
||
Square.propTypes = { | ||
value: PropTypes.string.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.
Nice use of state!