-
Notifications
You must be signed in to change notification settings - Fork 14.2k
Memory game #1500
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
Merged
+6,481
−0
Merged
Memory game #1500
Changes from all commits
Commits
Show all changes
26 commits
Select commit
Hold shift + click to select a range
979a096
feat: initial commit
prathoseraaj 62eb682
feat: memory game
prathoseraaj cd442e1
Update memory-game/components/MemoryGame.jsx
leestott 0faef13
Update memory-game/components/MemoryGame.jsx
leestott 825ba0d
Update memory-game/components/MemoryGame.jsx
leestott 06789f8
Update memory-game/components/MemoryGame.jsx
leestott 06ee2b8
Update memory-game/components/MemoryGame.jsx
prathoseraaj 18c3b4c
Update memory-game/components/MemoryGame.jsx
prathoseraaj 163c9f8
Update memory-game/components/MemoryGame.jsx
prathoseraaj dadef52
fix: copilot issues
prathoseraaj 9c2d4c3
Update memory-game/app/layout.js
prathoseraaj 44de199
fix: copilot issues
prathoseraaj 3e35c3a
Update memory-game/components/MemoryGame.jsx
prathoseraaj 2ec0937
Update memory-game/components/MemoryGame.jsx
prathoseraaj 40fe9e3
fix: copilot issues
prathoseraaj fceb739
Update memory-game/components/MemoryGame.jsx
prathoseraaj 045314e
fix: grid issues
prathoseraaj 6f6d683
Update memory-game/components/MemoryGame.jsx
prathoseraaj 193925f
Update memory-game/app/page.js
prathoseraaj dc741d1
Update memory-game/components/MemoryGame.jsx
prathoseraaj 6a240ae
fix: grid issues
prathoseraaj 1ec5b53
fix: odd grid issues
prathoseraaj e8d31a9
Update memory-game/components/MemoryGame.jsx
prathoseraaj 7abeac2
Update memory-game/components/MemoryGame.jsx
prathoseraaj ef66bde
Update memory-game/components/MemoryGame.jsx
prathoseraaj 44fabcb
fix
prathoseraaj File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. | ||
|
||
# dependencies | ||
/node_modules | ||
/.pnp | ||
.pnp.* | ||
.yarn/* | ||
!.yarn/patches | ||
!.yarn/plugins | ||
!.yarn/releases | ||
!.yarn/versions | ||
|
||
# testing | ||
/coverage | ||
|
||
# next.js | ||
/.next/ | ||
/out/ | ||
|
||
# production | ||
/build | ||
|
||
# misc | ||
.DS_Store | ||
*.pem | ||
|
||
# debug | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
.pnpm-debug.log* | ||
|
||
# env files (can opt-in for committing if needed) | ||
.env* | ||
|
||
# vercel | ||
.vercel | ||
|
||
# typescript | ||
*.tsbuildinfo | ||
next-env.d.ts |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). | ||
|
||
## Getting Started | ||
|
||
First, run the development server: | ||
|
||
```bash | ||
npm run dev | ||
# or | ||
yarn dev | ||
# or | ||
pnpm dev | ||
# or | ||
bun dev | ||
``` | ||
|
||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. | ||
|
||
You can start editing the page by modifying `app/page.js`. The page auto-updates as you edit the file. | ||
|
||
This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. | ||
|
||
## Learn More | ||
|
||
To learn more about Next.js, take a look at the following resources: | ||
|
||
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. | ||
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. | ||
|
||
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome! | ||
|
||
## Deploy on Vercel | ||
|
||
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. | ||
|
||
Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details. |
Binary file not shown.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
@import "tailwindcss"; | ||
|
||
:root { | ||
--background: #ffffff; | ||
--foreground: #171717; | ||
} | ||
|
||
@theme inline { | ||
--color-background: var(--background); | ||
--color-foreground: var(--foreground); | ||
--font-sans: var(--font-geist-sans); | ||
--font-mono: var(--font-geist-mono); | ||
} | ||
|
||
@media (prefers-color-scheme: dark) { | ||
:root { | ||
--background: #0a0a0a; | ||
--foreground: #ededed; | ||
} | ||
} | ||
|
||
body { | ||
background: var(--background); | ||
color: var(--foreground); | ||
font-family: Arial, Helvetica, sans-serif; | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { Geist, Geist_Mono } from "next/font/google"; | ||
import "./globals.css"; | ||
|
||
const geistSans = Geist({ | ||
variable: "--font-geist-sans", | ||
subsets: ["latin"], | ||
}); | ||
|
||
const geistMono = Geist_Mono({ | ||
variable: "--font-geist-mono", | ||
subsets: ["latin"], | ||
}); | ||
|
||
export const metadata = { | ||
title: "Memory Game", | ||
description: "A fun and challenging memory game built with Next.js.", | ||
}; | ||
|
||
export default function RootLayout({ children }) { | ||
return ( | ||
<html lang="en"> | ||
<body | ||
className={`${geistSans.variable} ${geistMono.variable} antialiased`} | ||
> | ||
{children} | ||
</body> | ||
</html> | ||
); | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import MemoryGame from '@/components/MemoryGame' | ||
import React from 'react' | ||
|
||
const page = () => { | ||
return ( | ||
<div> | ||
<MemoryGame /> | ||
</div> | ||
) | ||
} | ||
|
||
export default page |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
"use client"; | ||
|
||
import React, { useEffect, useState, useCallback } from "react"; | ||
|
||
// Fisher-Yates shuffle for unbiased randomization | ||
function fisherYatesShuffle(array) { | ||
const arr = array.slice(); | ||
for (let i = arr.length - 1; i > 0; i--) { | ||
const j = Math.floor(Math.random() * (i + 1)); | ||
[arr[i], arr[j]] = [arr[j], arr[i]]; | ||
} | ||
return arr; | ||
} | ||
|
||
const MemoryGame = () => { | ||
const [gridSize, setGridSize] = useState(2); | ||
|
||
const [array, setArray] = useState([]); | ||
const [flipped, setFlipped] = useState([]); | ||
const [selectedPairs, setSelectedPairs] = useState([]); | ||
const [disabled, setDisabled] = useState(false); | ||
const [error, setError] = useState(""); | ||
|
||
const [won, setWon] = useState(false); | ||
|
||
const handleGridSize = (e) => { | ||
const size = parseInt(e.target.value); | ||
if (2 <= size && size <= 10 && (size % 2 === 0)) { | ||
setGridSize(size); | ||
setError(""); | ||
} else { | ||
setError("Please enter a grid size where size is even (e.g., 2, 4, 6, 8, 10)"); | ||
} | ||
}; | ||
|
||
const initializeGame = useCallback(() => { | ||
const totalCards = gridSize * gridSize; | ||
const pairCount = totalCards / 2; | ||
|
||
const numbers = [...Array(pairCount).keys()].map((n) => n + 1); | ||
const cardNumbers = [...numbers, ...numbers]; | ||
const shuffledCardNumbers = fisherYatesShuffle(cardNumbers); | ||
const shuffledCards = shuffledCardNumbers.map((number, index) => ({ | ||
id: index, | ||
number, | ||
})); | ||
|
||
setArray(shuffledCards); | ||
setFlipped([]); | ||
setSelectedPairs([]); | ||
setDisabled(false); | ||
setWon(false); | ||
}, [gridSize]); | ||
|
||
useEffect(() => { | ||
initializeGame(); | ||
}, [initializeGame]); | ||
|
||
const handleMatch = (secondId) => { | ||
const [firstId] = flipped; | ||
|
||
if (array[firstId].number === array[secondId].number) { | ||
setSelectedPairs([...selectedPairs, firstId, secondId]); | ||
setFlipped([]); | ||
setDisabled(false); | ||
} else { | ||
setTimeout(() => { | ||
setDisabled(false); | ||
setFlipped([]); | ||
}, 1000); | ||
} | ||
}; | ||
|
||
const handleClick = (id) => { | ||
if (disabled || won) return; | ||
|
||
if (flipped.length === 0) { | ||
setFlipped([id]); | ||
return; | ||
} | ||
|
||
if (flipped.length === 1) { | ||
setDisabled(true); | ||
if (id !== flipped[0]) { | ||
setFlipped([...flipped, id]); | ||
handleMatch(id); | ||
} else { | ||
setFlipped([]); | ||
setDisabled(false); | ||
} | ||
} | ||
}; | ||
|
||
const isFlipped = (id) => flipped.includes(id) || selectedPairs.includes(id); | ||
const isSelectedPairs = (id) => selectedPairs.includes(id); | ||
|
||
useEffect(() => { | ||
if (selectedPairs.length === array.length && array.length > 0) { | ||
setWon(true); | ||
} | ||
}, [selectedPairs, array]); | ||
|
||
return ( | ||
<div className="h-screen flex flex-col justify-center items-center p-4 bg-gray-100 "> | ||
{/* Heading */} | ||
<h1 className="text-3xl font-bold mb-6">Memory Game</h1> | ||
{/* Grid Size */} | ||
<div className="mb-4"> | ||
<label htmlFor="gridSize">Grid Size: (max 10)</label> | ||
<input | ||
type="number" | ||
className="w-[50px] ml-3 rounded border-2 px-1.5 py-1" | ||
min="2" | ||
max="10" | ||
value={gridSize} | ||
onChange={handleGridSize} | ||
/> | ||
{error && ( | ||
<div className="text-sm text-red-500 mt-2">{error}</div> | ||
)} | ||
</div> | ||
{/* Cards */} | ||
<div | ||
className="grid gap-2 mb-4" | ||
style={{ | ||
gridTemplateColumns: `repeat(${gridSize}, minmax(0,1fr))`, | ||
width: `min(100%,${gridSize * 5.5}rem)`, | ||
}} | ||
> | ||
{array.map((card) => ( | ||
<div | ||
key={card.id} | ||
onClick={() => handleClick(card.id)} | ||
className={`aspect-square flex items-center justify-center text-xl transition-all duration-300 font-bold rounded-lg cursor-pointer ${ | ||
isFlipped(card.id) | ||
? isSelectedPairs(card.id) | ||
? "bg-green-500 text-white" | ||
: "bg-blue-500 text-white" | ||
: "bg-gray-300 text-gray-400" | ||
}`} | ||
> | ||
{isFlipped(card.id) ? card.number : "?"} | ||
</div> | ||
))} | ||
</div> | ||
{/* Result */} | ||
<div className="text-2xl text-green-500 font-bold"> | ||
{won ? "You Won!" : ""} | ||
</div> | ||
|
||
{/* Reset Button */} | ||
<button | ||
className="px-5 py-2 bg-green-500 rounded text-white mt-5" | ||
onClick={initializeGame} | ||
> | ||
Reset | ||
</button> | ||
</div> | ||
); | ||
}; | ||
|
||
export default MemoryGame; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import { dirname } from "path"; | ||
import { fileURLToPath } from "url"; | ||
import { FlatCompat } from "@eslint/eslintrc"; | ||
|
||
const __filename = fileURLToPath(import.meta.url); | ||
const __dirname = dirname(__filename); | ||
|
||
const compat = new FlatCompat({ | ||
baseDirectory: __dirname, | ||
}); | ||
|
||
const eslintConfig = [ | ||
...compat.extends("next/core-web-vitals"), | ||
{ | ||
ignores: [ | ||
"node_modules/**", | ||
".next/**", | ||
"out/**", | ||
"build/**", | ||
"next-env.d.ts", | ||
], | ||
}, | ||
]; | ||
|
||
export default eslintConfig; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
{ | ||
"compilerOptions": { | ||
"paths": { | ||
"@/*": ["./*"] | ||
} | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
/** @type {import('next').NextConfig} */ | ||
const nextConfig = {}; | ||
|
||
export default nextConfig; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.