-
Notifications
You must be signed in to change notification settings - Fork 10
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
Completed crude tic-tac-toe game #5
base: master
Are you sure you want to change the base?
Changes from all commits
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,15 @@ | ||
const container = document.querySelector('.container') | ||
|
||
|
||
|
||
const App = () => { | ||
return ( | ||
<div> | ||
<div>A tic-tac-toe game</div> | ||
<Board /> | ||
</div> | ||
) | ||
} | ||
|
||
|
||
ReactDOM.render(<App />, container); |
This file was deleted.
Original file line number | Diff line number | Diff line change | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,72 @@ | ||||||||||||||||||
const container = document.querySelector('.container') | ||||||||||||||||||
const game = new Game() | ||||||||||||||||||
|
||||||||||||||||||
const Board = () => { | ||||||||||||||||||
const [box1, setBox1] = React.useState("") | ||||||||||||||||||
const [box2, setBox2] = React.useState("") | ||||||||||||||||||
const [box3, setBox3] = React.useState("") | ||||||||||||||||||
const [box4, setBox4] = React.useState("") | ||||||||||||||||||
const [box5, setBox5] = React.useState("") | ||||||||||||||||||
const [box6, setBox6] = React.useState("") | ||||||||||||||||||
const [box7, setBox7] = React.useState("") | ||||||||||||||||||
const [box8, setBox8] = React.useState("") | ||||||||||||||||||
const [box9, setBox9] = React.useState("") | ||||||||||||||||||
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. Setting state to an empty string nine times for each box is a valid approach. To make your code more even easier to reason about, consider refactoring so that the state of all boxes is set to an array. 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. Oddly enough...I had no idea I could do that. Thank you! |
||||||||||||||||||
|
||||||||||||||||||
const move = (e) => { | ||||||||||||||||||
|
||||||||||||||||||
const boxStates = { | ||||||||||||||||||
box1: setBox1, | ||||||||||||||||||
box2: setBox2, | ||||||||||||||||||
box3: setBox3, | ||||||||||||||||||
box4: setBox4, | ||||||||||||||||||
box5: setBox5, | ||||||||||||||||||
box6: setBox6, | ||||||||||||||||||
box7: setBox7, | ||||||||||||||||||
box8: setBox8, | ||||||||||||||||||
box9: setBox9, | ||||||||||||||||||
} | ||||||||||||||||||
const box = e.target.id | ||||||||||||||||||
if(game.turn % 2 !== 0){ | ||||||||||||||||||
boxStates[box](<PlayerOne/>) | ||||||||||||||||||
document.getElementById(box).removeAttribute("onClick"); | ||||||||||||||||||
console.log(box) | ||||||||||||||||||
game.playerOne.makeMove(parseInt(box[3]) - 1) | ||||||||||||||||||
console.log(game.board) | ||||||||||||||||||
game.checkBoard(game.turn) | ||||||||||||||||||
|
||||||||||||||||||
game.turn += 1 | ||||||||||||||||||
return game.turn | ||||||||||||||||||
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. The if statements are nearly identical. It appears that the difference is only which box state is set. In that case, this can be refactored into something like:
Suggested change
|
||||||||||||||||||
} | ||||||||||||||||||
if(game.turn % 2 === 0){ | ||||||||||||||||||
boxStates[box](<PlayerTwo/>) | ||||||||||||||||||
document.getElementById(box).removeAttribute("onClick"); | ||||||||||||||||||
console.log(box) | ||||||||||||||||||
game.playerTwo.makeMove(parseInt(box[3]) - 1) | ||||||||||||||||||
console.log(game.board) | ||||||||||||||||||
game.checkBoard(game.turn) | ||||||||||||||||||
game.turn += 1 | ||||||||||||||||||
return game.turn | ||||||||||||||||||
} | ||||||||||||||||||
} | ||||||||||||||||||
return ( | ||||||||||||||||||
<div> | ||||||||||||||||||
<section className="row"> | ||||||||||||||||||
<div onClick={(e) => move(e)} className="box" id="box1">{box1}</div> | ||||||||||||||||||
<div onClick={(e) => move(e)} className="box" id="box2">{box2}</div> | ||||||||||||||||||
<div onClick={(e) => move(e)} className="box" id="box3">{box3}</div> | ||||||||||||||||||
</section> | ||||||||||||||||||
<section className="row"> | ||||||||||||||||||
<div onClick={(e) => move(e)} className="box" id="box4">{box4}</div> | ||||||||||||||||||
<div onClick={(e) => move(e)} className="box" id="box5">{box5}</div> | ||||||||||||||||||
<div onClick={(e) => move(e)} className="box" id="box6">{box6}</div> | ||||||||||||||||||
</section> | ||||||||||||||||||
<section className="row"> | ||||||||||||||||||
<div onClick={(e) => move(e)} className="box" id="box7">{box7}</div> | ||||||||||||||||||
<div onClick={(e) => move(e)} className="box" id="box8">{box8}</div> | ||||||||||||||||||
<div onClick={(e) => move(e)} className="box" id="box9">{box9}</div> | ||||||||||||||||||
Comment on lines
+54
to
+66
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. If there were a refactor to use an array as a default state, then there would be an added benefit of being able to map through the boxes in order to render the board. 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. Definitely a change I'll be making |
||||||||||||||||||
</section> | ||||||||||||||||||
</div> | ||||||||||||||||||
) | ||||||||||||||||||
} | ||||||||||||||||||
|
||||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
const PlayerOne = () => { | ||
return ( | ||
<div className="x-icon">X</div> | ||
) | ||
} | ||
|
||
const PlayerTwo = () => { | ||
return ( | ||
<div className="o-icon">O</div> | ||
) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
class Game{ | ||
constructor(){ | ||
this.playerOne = new Player() | ||
this.playerTwo = new Player() | ||
this.playerOne.move = 'X' | ||
this.playerTwo.move = 'O' | ||
this.board = ['', '', '', '', '', '', '', '', ''] | ||
this.posTracker = {} | ||
this.turn = 1 | ||
this.winner = null | ||
} | ||
|
||
checkBoard(candidate){ | ||
|
||
for(let position in this.board){ | ||
this.posTracker[position] = this.board[position] | ||
} | ||
//Checks each row to see if a player won | ||
if(this.posTracker['0'] === this.posTracker['1'] && this.posTracker['0'] === this.posTracker['2'] && this.posTracker['0'] !== ''){ | ||
candidate % 2 === 0 ? game.playerOne.score += 1 : game.playerTwo.score += 1 | ||
this.gameOver() | ||
} | ||
Comment on lines
+19
to
+22
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. Each of the if statements are essentially the same except for the 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. I'll work on this! |
||
if(this.posTracker['3'] === this.posTracker['4'] && this.posTracker['3'] === this.posTracker['5'] && this.posTracker['3'] !== ''){ | ||
candidate % 2 === 0 ? game.playerOne.score += 1 : game.playerTwo.score += 1 | ||
this.gameOver() | ||
} | ||
if(this.posTracker['6'] === this.posTracker['7'] && this.posTracker['6'] === this.posTracker['8'] && this.posTracker['6'] !== ''){ | ||
candidate % 2 === 0 ? game.playerOne.score += 1 : game.playerTwo.score += 1 | ||
this.gameOver() | ||
} | ||
//Checks each diagonal row to see if a player won | ||
if(this.posTracker['0'] === this.posTracker['4'] && this.posTracker['0'] === this.posTracker['8'] && this.posTracker['0'] !== ''){ | ||
candidate % 2 === 0 ? game.playerOne.score += 1 : game.playerTwo.score += 1 | ||
this.gameOver() | ||
} | ||
if(this.posTracker['2'] === this.posTracker['4'] && this.posTracker['2'] === this.posTracker['6'] && this.posTracker['2'] !== ''){ | ||
candidate % 2 === 0 ? game.playerOne.score += 1 : game.playerTwo.score += 1 | ||
this.gameOver() | ||
} | ||
//Checks each column to see if a player won | ||
if(this.posTracker['0'] === this.posTracker['3'] && this.posTracker['0'] === this.posTracker['6'] && this.posTracker['0'] !== ''){ | ||
candidate % 2 === 0 ? game.playerOne.score += 1 : game.playerTwo.score += 1 | ||
this.gameOver() | ||
} | ||
if(this.posTracker['1'] === this.posTracker['4'] && this.posTracker['1'] === this.posTracker['7'] && this.posTracker['1'] !== ''){ | ||
candidate % 2 === 0 ? game.playerOne.score += 1 : game.playerTwo.score += 1 | ||
this.gameOver() | ||
} | ||
if(this.posTracker['2'] === this.posTracker['5'] && this.posTracker['2'] === this.posTracker['8'] && this.posTracker['2'] !== ''){ | ||
candidate % 2 === 0 ? game.playerOne.score += 1 : game.playerTwo.score += 1 | ||
this.gameOver() | ||
} | ||
//Checks to see if there is a draw | ||
if(candidate >= 9){ | ||
console.log('Draw game') | ||
alert('Draw Game') | ||
location.reload() | ||
} | ||
|
||
} | ||
|
||
gameOver(){ | ||
this.board = ['', '', '', '', '', '', '', '', ''] | ||
if(game.turn % 2 !== 0){ | ||
alert('Player One Wins') | ||
location.reload() | ||
Devonte202 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return 1 | ||
} | ||
alert('Player Two Wins') | ||
location.reload() | ||
return 2 | ||
} | ||
|
||
} | ||
|
||
class Player{ | ||
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. I'd recommend keeping the 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. That makes perfect sense actually, I'll make that change |
||
constructor(){ | ||
this.score = 0 | ||
} | ||
makeMove(index){ | ||
game.board.splice(index, 1, this.move) | ||
} | ||
} |
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.
Within
board.jsx
, this code base uses hooks and within thegame.js
module, the code base uses class components. There may be times when developers are updating apps from classes or hooks. Or there may be times when there is a specific tradeoff/benefit for switching between using hooks and class components in the same app.Given that this code base was newly created by one developer, I'd recommend choosing one paradigm (hooks or classes) and sticking with it. Alternatively, in the Pull Request Summary, a developer could briefly highlight reasoning for switching between React "formats" so that other developers can better understand the decision.