JSFiddle - React, Tailwind, and code Playground
by clapynick
HTML
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, intitial-scale=1">
<title>Matching Game</title>
<meta name="description" content="">
<link rel="stylesheet prefetch" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.1/css/font-awesome.min.css">
<link rel="stylesheet prefetch" href="https://fonts.googleapis.com/css?family=Coda">
<link rel="stylesheet" href="css/app.css">
</head>
<body>
<div class="container">
<header>
<h1>Matching Game</h1>
</header>
<section class="score-panel">
<span id="timer">Timer: 00 s</span>
<span class="moves">Move(s): 0</span>
<ul class="stars">
<li><i class="fa fa-star"></i></li>
<li><i class="fa fa-star"></i></li>
<li><i class="fa fa-star"></i></li>
</ul>
<div class="restart">
<i class="fa fa-repeat"></i>
</div>
</section>
<ul class="deck">
<li class="card">
<i class="fa fa-diamond"></i>
</li>
<li class="card">
<i class="fa fa-paper-plane-o"></i>
</li>
<li class="card">
<i class="fa fa-anchor"></i>
</li>
<li class="card">
<i class="fa fa-bolt"></i>
</li>
<li class="card">
<i class="fa fa-cube"></i>
</li>
<li class="card">
<i class="fa fa-anchor"></i>
</li>
<li class="card">
<i class="fa fa-leaf"></i>
</li>
<li class="card">
<i class="fa fa-bicycle"></i>
</li>
<li class="card">
<i class="fa fa-diamond"></i>
</li>
<li class="card">
<i class="fa fa-bomb"></i>
...
CSS
html {
box-sizing: border-box;
}
*,
*::before,
*::after {
box-sizing: inherit;
}
html,
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
body {
background: #ffffff url('../img/geometry2.png'); /* Background pattern from Subtle Patterns */
font-family: 'Coda', cursive;
}
.container {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
h1 {
font-family: 'Open Sans', sans-serif;
font-weight: 300;
}
/*
* Styles for the deck of cards
*/
.deck {
width: 660px;
min-height: 680px;
background: linear-gradient(160deg, #02ccba 0%, #aa7ecd 100%);
padding: 32px;
border-radius: 10px;
box-shadow: 12px 15px 20px 0 rgba(46, 61, 73, 0.5);
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: center;
margin: 0 0 3em;
}
.deck .card {
height: 125px;
width: 125px;
background: #2e3d49;
font-size: 0;
color: #ffffff;
border-radius: 8px;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
box-shadow: 5px 2px 20px 0 rgba(46, 61, 73, 0.5);
}
.deck .card.open {
transform: rotateY(0);
background: #02b3e4;
cursor: default;
}
.deck .card.show {
font-size: 33px;
}
.deck .card.match {
cursor: default;
background: #02ccba;
font-size: 33px;
}
/*
* Styles for the Score Panel
*/
.score-panel {
font-weight: bold;
text-align: center;
width: 630px;
margin-bottom: 10px;
}
.score-panel .stars {
margin: 0 20px;
padding: 0;
display: inline-block;
margin: 0 0 0 30px;
color: #02b3e4;
}
.score-panel .stars li {
list-style: none;
display: inline-block;
}
.score-panel .restart {
float: right;
cursor: pointer;
margin-right: 80px;
}
#timer{
float: left;
margin-right: -300px;
margin-left: 20px;
}
.moves{
margin-right: 60px;
margin-left: 80px;
}
JavaScript
let card = document.getElementsByClassName('card'),
cards = [...card],
checkName = [], // store the name of the shape (based on class name) to compare if card matches or not
matchCard = [], // store parent of clicked card in this array to change its class for flipping card that matches
totalMatchedCards = [],
t0, // start time of timer when player select a card
counter = 0, // move(s) counter
winGame = false, // to be used later!!!
deck = document.getElementsByClassName('deck')[0];
//shuffle the deck and add it
shuffle(cards);
for (let i = 0; i < cards.length; i++) {
card = cards[i];
card.addEventListener('click', _ => game(i));
}
// RESTART
document.getElementsByClassName('fa-repeat')[0].addEventListener('click', function () {
// shuffle the deck and add it
shuffle(cards);
t0 = Date.now(), counter = 0;
setInterval(timer);
});
function game(i) {
/* skip any matched cards so they aren't clickable nor stored anywhere
note to myself: return true is same as continue */
if (cards[i].classList[1] === "match" || cards[i].classList[1] === "open" || cards[i].classList[1] === "show") {
return true;
}
// open/close cards
if (matchCard.length <= 1) { // don't open more than two cards!
revealCard(cards[i]); // new func
}
// add cards to array
openCards(cards[i]); //new func
// empty the arrays & close inncorrect matching.
if (matchCard.length === 2) {
checkMatching();
automaticallyCloseCards();
counter++;
}
if (counter === 0) {
t0 = Date.now();
setInterval(timer);
}
if (totalMatchedCards.length === 16) {
winGame = true;
console.log("PLAYER HAS WON THE GAME!!") // to be changed to result pop up.
}
// STARS Rating
if (counter === 15) {
document.getElementsByClassName('fa-star')[2].style.color = "#d3d3d3";
}
if (counter === 20) {
...