Skip to content
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

Tic Tac Toe Game #208

Merged
merged 12 commits into from
May 24, 2022
15 changes: 15 additions & 0 deletions src/meta/play-meta.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ QuoteGenerator,
PasswordGenerator,
WhyTypescript,
NetlifyCardGame,
TicTacToeGame,
Calendar,
FunQuiz,
//import play here
Expand Down Expand Up @@ -243,6 +244,20 @@ export const plays = [
language: 'js',
featured: true,
}, {
id: 'pl-tic-tac-toe-game',
name: 'Tic Tac Toe Game',
description: 'This game is coded in ReactJS and VanillaCSS',
component: () => {return <TicTacToeGame />},
path: '/plays/tic-tac-toe-game',
level: 'Beginner',
tags: 'Hooks,JSX,Functions,ResetState,CSS',
github: 'tejinder-sharma',
cover: '',
blog: '',
video: '',
tejinder-sharma marked this conversation as resolved.
Show resolved Hide resolved
language: 'js',
},
{
id: 'pl-calendar',
name: 'Calendar',
description: 'Simple calendar app to manage events',
Expand Down
4 changes: 4 additions & 0 deletions src/plays/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ export { default as AnalogClock } from 'plays/analog-clock/AnalogClock';
export { default as PasswordGenerator } from 'plays/password-generator/PasswordGenerator';
export { default as WhyTypescript } from 'plays/why-typescript/WhyTypescript';
export { default as NetlifyCardGame } from 'plays/memory-game/NetlifyCardGame';

export { default as TicTacToeGame } from 'plays/tic-tac-toe-game/TicTacToeGame';

export { default as Calendar } from 'plays/calendar/Calendar';
export { default as FunQuiz } from 'plays/fun-quiz/FunQuiz';

//add export here
17 changes: 17 additions & 0 deletions src/plays/tic-tac-toe-game/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Tic Tac Toe Game

It is a Tic Tac Toe Game to made with React.


## What will you learn?

- Functional Components
- Event handling for user interaction.
- Update of states.
- How to reuse the components.(e.g we reused our game square button many times).
- How to reset the states.


The file `TicTacToeGAme` is the main file along with the css.

If you want to implement your learnings about states and useEffect hooks try implementing it on your own!
32 changes: 32 additions & 0 deletions src/plays/tic-tac-toe-game/TicTacToeGame.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { getPlayById } from 'meta/play-meta-util';

import PlayHeader from 'common/playlists/PlayHeader';

import React from "react";

import Game from "./components/Game.jsx"

import "./styles/tic-tac-toe-tj.css";

function TicTacToeGame(props) {
// Do not remove the below lines.
// The following code is to fetch the current play from the URL
const { id } = props;
const play = getPlayById(id);

// Your Code Start below.
return (
<>
<div className="play-details">
tejinder-sharma marked this conversation as resolved.
Show resolved Hide resolved
<PlayHeader play={play} />
<div className="play-details-body tic-tac-toe-tj">
{/* Your Code Starts Here */}
<Game />
{/* Your Code Ends Here */}
</div>
</div>
</>
);
}

export default TicTacToeGame;
120 changes: 120 additions & 0 deletions src/plays/tic-tac-toe-game/components/Game.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import React, { useState } from "react";

function Square({ index, value, onClick, winningSquare}) {
return (
<button className={`squareButton ${winningSquare?.includes(index) && "bg-yellow-500"}`} onClick={onClick}>
{value}
</button>
);
}
function Restart({ onClick }) {
return (
<button className="jumpButton" onClick={onClick}>
Play again
</button>
);
}

function Game() {
const [squares, setSquares] = useState(Array(9).fill(null));
const [isXNext, setIsXNext] = useState(true);

const nextSymbol = isXNext ? "X" : "O";

const winner = calculateWinner(squares);


function renderSquare(i) {
return (
<Square
key={i}
index={i}
winningSquare={winner ? winner.line : null}
value={squares[i]}
onClick={() => {
const nextSquares = squares.slice();
if (squares[i] != null || winner != null) {
return;
}
nextSquares[i] = nextSymbol;
setSquares(nextSquares);
setIsXNext(!isXNext);
}}
/>
);
}
function getStatus() {
if (winner) {
return `Winner: ${winner.player}`;
} else if (isBoardFull(squares)) {
return "Draw!";
} else {
return `Next player: ${nextSymbol}`;
}
}
function renderRestartButton() {
return (
<Restart
onClick={() => {
setSquares(Array(9).fill(null));
setIsXNext(true);
}}
/>
);
}
function renderSquares(n) {
let squares = [];
for (let i = n; i < n + 3; i++) {
squares.push(renderSquare(i));
}
return squares;
}

function renderRow(i) {
return <div className="row ">{renderSquares(i)}</div>;
}

return (
<div className="container">
<header className="header">Tic Tac Toe Game</header>
<div className="boardMain">
{renderRow(0)}
{renderRow(3)}
{renderRow(6)}
</div>
<div className="status">{getStatus()}</div>
<div>{renderRestartButton()}</div>
</div>
);
}

function calculateWinner(squares) {
const possibleLines = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8],
[0, 3, 6],
[1, 4, 7],
[2, 5, 8],
[0, 4, 8],
[2, 4, 6],
];
for (let i = 0; i < possibleLines.length; i++) {
const [a, b, c] = possibleLines[i];
if (squares[a] && squares[a] === squares[b] && squares[a] === squares[c]) {
return {player:squares[a], line:[a, b, c]};
}
}
return null;
}

function isBoardFull(squares) {
for (let i = 0; i < squares.length; i++) {
if (squares[i] == null) {
return false;
}
}
return true;
}

export default Game;
Binary file added src/plays/tic-tac-toe-game/cover.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
67 changes: 67 additions & 0 deletions src/plays/tic-tac-toe-game/styles/tic-tac-toe-tj.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
.tic-tac-toe-tj .squareButton{
width: 5rem;
height: 5rem;
margin: 1px;
background-color: #EC4899;

display: inline-flex;
justify-content: center;
align-items: center;

border: none;
font: bold;
font-size: 32px;
color: white;
}
.tic-tac-toe-tj .squareButton:hover{
background-color: #10B981;
}
.tic-tac-toe-tj .row{
display: flex;
}
.tic-tac-toe-tj .jumpButton{
padding: 0.5rem 1rem;
background-color: #10B981;

display: inline-flex;
justify-content: center;
align-items: center;

border: none;
color: white;
font-size: 18px;
border-radius: 4px;
margin-top: 1rem;
}
.tic-tac-toe-tj .bg-yellow-500{
background-color: #f59e0b;
}
.tic-tac-toe-tj .jumpButton:hover{
background-color: #EC4899;
}
.tic-tac-toe-tj .list{
margin-top: 1rem;
}
.tic-tac-toe-tj .status{
margin-top: 1rem;
font-size: 24px;
}
.tic-tac-toe-tj .header{
width: 100%;
padding: 16px 8px;
color: white;
font-size: 24px;

display: grid;
place-content: center;

background-color: #010326;
margin-bottom: 2rem;
}
.tic-tac-toe-tj .container{
text-align: center;
}
.tic-tac-toe-tj .boardMain{
display: grid;
place-content: center;
}