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

Brain Card Game Added #4050

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions Games/Brain_card_game/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# **BRAIN Card GAME**

---

<br>

## **Description 📃**
- This project is built on a basic web tech stacks such as HTML, CSS and Javascript.
- This is a single-player game.

<br>

## **Functionalities 🎮**
- Click on the boxes that are formed randomly.
- The boxes with same image will remain opened and without will be closed instantly
- There will be timer and moves to note in how much moves and time have you solve this game.
<br>


<br>

## **Screenshots 📸**

<br>

![image](./assets/image.png)

<br>
Binary file added Games/Brain_card_game/assets/image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 26 additions & 0 deletions Games/Brain_card_game/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Brain Game</title>
<link rel="stylesheet" href="style.css">
<script src="index.js" defer></script>
</head>
<body>
<div class="game">
<div class="controls">
<button>Start</button>
<div class="stats">
<div class="moves">0 moves</div>
<div class="timer">Time: 0 sec</div>
</div>
</div>
<div class="board-container">
<div class="board" data-dimension="4"></div>
<div class="win">You won!</div>
</div>
</div>
</body>
</html>
148 changes: 148 additions & 0 deletions Games/Brain_card_game/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
const selectors = {
boardContainer: document.querySelector('.board-container'),
board: document.querySelector('.board'),
moves: document.querySelector('.moves'),
timer: document.querySelector('.timer'),
start: document.querySelector('button'),
win: document.querySelector('.win')
}

const state = {
gameStarted: false,
flippedCards: 0,
totalFlips: 0,
totalTime: 0,
loop: null
}

const shuffle = array => {
const clonedArray = [...array]

for (let index = clonedArray.length - 1; index > 0; index--) {
const randomIndex = Math.floor(Math.random() * (index + 1))
const original = clonedArray[index]

clonedArray[index] = clonedArray[randomIndex]
clonedArray[randomIndex] = original
}

return clonedArray
}

const pickRandom = (array, items) => {
const clonedArray = [...array]
const randomPicks = []

for (let index = 0; index < items; index++) {
const randomIndex = Math.floor(Math.random() * clonedArray.length)

randomPicks.push(clonedArray[randomIndex])
clonedArray.splice(randomIndex, 1)
}

return randomPicks
}

const generateGame = () => {
const dimensions = selectors.board.getAttribute('data-dimension')

if (dimensions % 2 !== 0) {
throw new Error("The dimension of the board must be an even number.")
}

const emojis = ['🥔', '🍒', '🥑', '🌽', '🥕', '🍇', '🍉', '🍌', '🥭', '🍍']
const picks = pickRandom(emojis, (dimensions * dimensions) / 2)
const items = shuffle([...picks, ...picks])
const cards = `
<div class="board" style="grid-template-columns: repeat(${dimensions}, auto)">
${items.map(item => `
<div class="card">
<div class="card-front"></div>
<div class="card-back">${item}</div>
</div>
`).join('')}
</div>
`

const parser = new DOMParser().parseFromString(cards, 'text/html')

selectors.board.replaceWith(parser.querySelector('.board'))
}

const startGame = () => {
state.gameStarted = true
selectors.start.classList.add('disabled')

state.loop = setInterval(() => {
state.totalTime++

selectors.moves.innerText = `${state.totalFlips} moves`
selectors.timer.innerText = `time: ${state.totalTime} sec`
}, 1000)
}

const flipBackCards = () => {
document.querySelectorAll('.card:not(.matched)').forEach(card => {
card.classList.remove('flipped')
})

state.flippedCards = 0
}

const flipCard = card => {
state.flippedCards++
state.totalFlips++

if (!state.gameStarted) {
startGame()
}

if (state.flippedCards <= 2) {
card.classList.add('flipped')
}

if (state.flippedCards === 2) {
const flippedCards = document.querySelectorAll('.flipped:not(.matched)')

if (flippedCards[0].innerText === flippedCards[1].innerText) {
flippedCards[0].classList.add('matched')
flippedCards[1].classList.add('matched')
}

setTimeout(() => {
flipBackCards()
}, 100)
}

// If there are no more cards that we can flip, we won the game
if (!document.querySelectorAll('.card:not(.flipped)').length) {
setTimeout(() => {
selectors.boardContainer.classList.add('flipped')
selectors.win.innerHTML = `
<span class="win-text">
You won!<br />
with <span class="highlight">${state.totalFlips}</span> moves<br />
under <span class="highlight">${state.totalTime}</span> seconds
</span>
`

clearInterval(state.loop)
}, 1000)
}
}

const attachEventListeners = () => {
document.addEventListener('click', event => {
const eventTarget = event.target
const eventParent = eventTarget.parentElement

if (eventTarget.className.includes('card') && !eventParent.className.includes('flipped')) {
flipCard(eventParent)
} else if (eventTarget.nodeName === 'BUTTON' && !eventTarget.className.includes('disabled')) {
startGame()
}
})
}

generateGame()
attachEventListeners()
127 changes: 127 additions & 0 deletions Games/Brain_card_game/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@

html {
width: 100%;
height: 100%;
background: linear-gradient(325deg, #03001e 0%, #7303c0 30%, #ec38bc 70%, #fdeff9 100%);
font-family: Arial, Helvetica, sans-serif;
overflow: hidden;
}

.container {
display: flex;
}

.game {
position: relative;
margin-left: 40px;
}

.game {
position: absolute;
top: 50%;
left: 70%;
transform: translate(-50%, -50%);
}
.controls {
display: flex;
gap: 20px;
margin-bottom: 20px;
}
button {
background: #282A3A;
color: #FFF;
border-radius: 5px;
padding: 10px 20px;
border: 0;
cursor: pointer;
font-family: Arial, Helvetica, sans-serif;
font-size: 18pt;
font-weight: bold;
}
button:hover {
color: yellow;
transform: scale(1.1);
transition: 0.4s ease;
}
.disabled {
color: #757575;
}
.stats {
color: #FFF;
font-size: 14pt;
font-weight: bold;
}
.board-container {
position: relative;
}
.board,
.win {
border-radius: 5px;
box-shadow: 0 25px 50px rgb(33 33 33 / 25%);
background: linear-gradient(135deg, #03001e 0%,#7303c0 0%,#ec38bc 50%, #fdeff9 100%);
transition: transform .6s cubic-bezier(0.4, 0.0, 0.2, 1);
backface-visibility: hidden;
}
.board {
padding: 20px;
display: grid;
grid-template-columns: repeat(4, auto);
grid-gap: 20px;
}
.board-container.flipped .board {
transform: rotateY(180deg) rotateZ(50deg);
}
.board-container.flipped .win {
transform: rotateY(0) rotateZ(0);
}
.card {
position: relative;
width: 100px;
height: 100px;
cursor: pointer;
}
.card-front,
.card-back {
position: absolute;
border-radius: 5px;
width: 100%;
height: 100%;
background: #282A3A;
transition: transform .6s cubic-bezier(0.4, 0.0, 0.2, 1);
backface-visibility: hidden;
}
.card-back {
transform: rotateY(180deg) rotateZ(50deg);
font-size: 28pt;
user-select: none;
text-align: center;
line-height: 100px;
background: #FDF8E6;
}
.card.flipped .card-front {
transform: rotateY(180deg) rotateZ(50deg);
}
.card.flipped .card-back {
transform: rotateY(0) rotateZ(0);
}
.win {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
text-align: center;
background: #FDF8E6;
transform: rotateY(180deg) rotateZ(50deg);
}
.win-text {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 21pt;
color: #282A3A;
}
.highlight {
color: #7303c0;
}
Loading