Memory game concept

by Csaba Hellinger

HTML

<div id="header">
    Memória játék KicsiValinak
    <span id="score">0 pont</span>
</div>

<div id="container">
    <div id="table">
    </div>
</div>

CSS

body {
    background-color: #EEE;
    margin: 0;

    font-family: Arial, Helvetica, sans-serif;
    letter-spacing: -1px;
    line-height: 1;    
}

#header {
    background-color: #DDD;
    padding: 5px;
    font-size: 22px;
}

#score {
    float: right;
}

#container {
    margin-top: 80px;
    perspective: 500px;
}

#table {
    width: 400px;
    height: 400px;
    margin: 0 auto;
    position: relative;
    transform: rotateY(20deg);
    perspective: 500px;
}

.cell {
    position: absolute;
}

.card {
    background-color: #FFF;
    border-right: 1px solid #444;
    border-bottom: 1px solid #444;
    border-top: 1px solid #DDD;
    border-left: 1px solid #DDD;
    width: 100%;
    height: 100%;
}

.card-bg {
    background: url("http://0.s3.envato.com/files/35494669/Light%20And%20Dark%20Grey%20Marble%20002.jpg");
    background-size: 80px;    
}

.text {
    font-size: 50px;
    position: relative;
    top: 50%;
    transform: translateY(-50%);
    text-align: center;
    opacity: 0;
}

.hit {
    background-color: #DFD;
}

.miss {
    background-color: #FDD;
}

JavaScript

var $table = $("#table"),
    $score = $("#score"),
    margin = 30,
    size = 80,
    board = 6, // only even numbers!
    turned = []
    score = 0;

function cardRemove() {
    $(this).parent().remove();
}

function rotateEnd() {
    var $card = $(this),
        data0, data1;
    if ($card.hasClass("miss")) {
        $card.removeClass("miss");
    } else {
        turned.push($card);
    }
    if (turned.length === 2) {
        data0 = turned[0].data();
        data1 = turned[1].data();
        if (data0.letter === data1.letter) {
            turned[0].addClass("hit").delay(500).fadeOut(1000, cardRemove);
            turned[1].addClass("hit").delay(500).fadeOut(1000, cardRemove);
            score += 1;
            $score.text(score + " pont");
        } else {
            turned[0].addClass("miss").delay(500).click();
            turned[1].addClass("miss").delay(500).click();
        }
        turned = [];
    }
}

function rotateStep(now) {
    var $card = $(this);
    $card.css("transform", "rotateY(" + Math.round(now) + "deg)");
}

function rotateHalf(now) {
    var $card = $(this);
    if ($card.hasClass("card-bg")) {
        $card.removeClass("card-bg");
        $card.children(".text").css("opacity", 1);
    } else {
        $card.addClass("card-bg");
        $card.children(".text").css("opacity", 0);
    }
    $card.animate({ "data-r": 0 }, {
        "duration": 200,
        "step": rotateStep,
        "complete": rotateEnd
    });
}

function onCardClick() {
    var $card = $(this);
    $card.animate({ "data-r": 90 }, {
        "duration": 200,
        "step": rotateStep,
        "complete": rotateHalf
    });
}

function letterList() {
    var alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".substring(0, board * board / 2),
        letters = [],
        letter, i, j, temp;
    for (i=0; i<Math.ceil(Math.pow(board, 3) / 2); i++) {
        letter = alphabet.charAt(Math.floor((Math.random() * alphabet.length)));
        letters.push(letter);
       ...