Skip to content

Instantly share code, notes, and snippets.

@yao3060
Created October 17, 2022 11:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yao3060/02caaca63d9854a572d211cd7e0033b4 to your computer and use it in GitHub Desktop.
Save yao3060/02caaca63d9854a572d211cd7e0033b4 to your computer and use it in GitHub Desktop.
Simple Tic Tac Toe Game By React
import React, { useState, useContext, createContext } from 'react';
import ReactDOM from 'react-dom';
function log(...str){
console.log(...str)
}
const rowStyle = {
display: 'flex'
}
const squareStyle = {
'width':'60px',
'height':'60px',
'backgroundColor': '#ddd',
'margin': '4px',
'display': 'flex',
'justifyContent': 'center',
'alignItems': 'center',
'fontSize': '40px',
'color': 'white',
'cursor': 'pointer'
}
const boardStyle = {
'backgroundColor': '#eee',
'width': '208px',
'alignItems': 'center',
'justifyContent': 'center',
'display': 'flex',
'flexDirection': 'column',
'border': '3px #eee solid'
}
const containerStyle = {
'display': 'flex',
'alignItems': 'center',
'flexDirection': 'column'
}
const instructionsStyle = {
'marginTop': '5px',
'marginBottom': '5px',
'fontWeight': 'bold',
'fontSize': '16px',
}
const buttonStyle = {
'marginTop': '15px',
'marginBottom': '16px',
'width': '80px',
'height': '40px',
'backgroundColor': '#8acaca',
'color': 'white',
'fontSize': '16px',
}
const GameContext = createContext()
function Square({handelClick, row, col, whom}) {
const {gameOver, user, setUser, boardGrids, setBoardGrids, getWinner} = useContext(GameContext)
return (
<div
className="square"
onClick={() => {
if(gameOver) {
alert('Game Over')
} else {
setUser(user === 'X' ? 'O' : 'X')
boardGrids[row][col] = user
setBoardGrids(boardGrids)
getWinner()
}
}}
style={squareStyle}>
{whom !== 0 ? whom : ''}
</div>
);
}
function Board() {
const {user, winner, boardGrids, reset} = useContext(GameContext)
return (
<div style={containerStyle} className="gameBoard">
<h1>Tic Tac Toe</h1>
<div id="statusArea" className="status" style={instructionsStyle}>Next player: <span>{user.toUpperCase()}</span></div>
<div id="winnerArea" className="winner" style={instructionsStyle}>Winner: <span>{winner}</span></div>
<button style={buttonStyle} onClick={() => reset()}>Reset</button>
<div style={boardStyle}>
{boardGrids.map((grids, row) => <div className="board-row" style={rowStyle} key={row}>
{grids.map((grid, col) => <Square key={`${row}-${col}`} row={row} col={col} whom={boardGrids[row][col]} /> )}
</div>)}
</div>
</div>
);
}
function Game() {
const initGrids = [
[0, 0, 0],
[0, 0, 0],
[0, 0, 0],
];
const [gameOver, setGameOver] = useState(false)
const [user, setUser] = useState('X')
const [winner, setWinner] = useState("None")
const [boardGrids, setBoardGrids] = useState(initGrids);
const getWinner = () => {
//find winner
checkRows(boardGrids)
checkCols()
checkX()
}
const checkRows = (arr) => {
arr.forEach(row => {
const unique = [...new Set(row)]
if(unique.length === 1 && unique[0] !== 0) {
setWinner(unique[0])
setGameOver(true)
}
})
}
const checkCols = () => {
const temp = []
boardGrids.forEach((row, x) => {
let newRow = []
row.forEach((col, y) => {
newRow.push(boardGrids[y][x])
})
temp.push(newRow)
})
checkRows(temp)
}
const checkX = () => {
log('checkX')
let rows = boardGrids.length
const temp1 = []
const temp2 = []
for(let x=0; x < rows; x++) {
temp1.push(boardGrids[x][x])
temp2.push(boardGrids[rows-1][rows-1])
}
checkRows( [temp1, temp2])
}
const reset = () => {
setUser('X');
setGameOver(false)
setWinner("None");
setBoardGrids(initGrids)
}
return (
<GameContext.Provider value={{user, setUser, boardGrids, setBoardGrids, winner, getWinner, reset, gameOver}}>
<div className="game">
<div className="game-board">
<Board />
</div>
</div>
</GameContext.Provider>
);
}
ReactDOM.render(
<Game />,
document.getElementById('root')
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment