Mini projet LOO

Dependencies:   mbed APDS_9960 mbed-rtos

Dependents:   MoveYourTetris_OK

Home du projet

src/cJeu.cpp

Committer:
clementdoreau
Date:
2016-04-20
Revision:
29:95469b25e187
Parent:
26:0897d27b6961
Child:
30:c647da947bd9

File content as of revision 29:95469b25e187:

#include "cJeu.h"
//////////////////////////////////////////////
#include "rtos.h"

//////////////////////////////////////////////
DigitalOut led2(LED2);





//Constructeur par défaut
cJeu::cJeu()
{
    _mat = new cMatrice(8, 8);
}

//Second constructeur:
//Il crée de crée une matrice de x LEDs de large sur y LEDS de HAUT,
//avec la broche pin comme entrée d'interruption si détection de mouvement du capteur
cJeu::cJeu(unsigned int x, unsigned int y)
{

//create the InterruptIn on the pin specified to Counter

    //on crée une nouvelle matrice
    _mat = new cMatrice(x, y);
    //on initialise la générateur de nombres pseudo-aléatoires
    srand(time(NULL));
    ///////////////////////////////////////////
    //_boussole = new cBoussole(p9,p10);
    // Initialize interrupt service routine

}

//Accesseur qui retourne un pointeur sur la matrice
cMatrice* cJeu::get_matrice()
{
    return _mat;
}

//Accesseur qui retourne la valeur du score du joueur
unsigned int cJeu::get_score()
{
    return _score;
}

//Mutateur pour la matrice
void cJeu::set_matrice(cMatrice *mat)
{
    _mat = mat;
}


//Mutateur pour le score
void cJeu::set_score(unsigned int sc)
{
    _score = sc;
}

void cJeu::setQueue(osMessageQId* queue, osPoolId* pool)
{
    _queue = queue;
    _pool = pool;
}

//Méthode d'initialisation de la liaison SPI et de la matrice RGB
//paramètres: fréquence 100kHz (maximum pour la matrice RGB 125KHz)
//            8 bits par envoi
//            Mode 3
void cJeu::initialiser()
{
    _spi.initSPI(100000, 8, 3);
    _mat->clear();
    _spi.envoyerMatrice(*_mat);

}

//Méthode de création d'une nouvelle pièce de manière pseudo-aléatoire
void cJeu::nouvellePiece()
{
    //On génère un nombre aléatoire entre 1 et 5 pour la pièce
    unsigned int nb = 1 + ((float)rand()/RAND_MAX) * 5;
    //On génère un deuxième nombre pour choisir la couleur de la pièce
    unsigned int couleur = 1 + ((float)rand()/RAND_MAX) * 7;
    //Selon le nombre généré, on va créer une nouvelle pièce
    switch(nb) {
            //On crée une pièce "L"
        case 1: {
            _ptrForme = new cEl(3,0);
            break;
        }
        //On crée une pièce "ligne"
        case 2: {
            _ptrForme = new cLigne(3,0);
            break;
        }
        //On crée une pièce "Z"
        case 3: {
            _ptrForme = new cZed(3,0);
            break;
        }
        //On crée une pièce "T"
        case 4: {
            _ptrForme = new cTe(3,0);
            break;
        }
        //On crée une pièce "carré"
        case 5: {
            _ptrForme = new  cCarre(3,0);
            break;
        }
        default:
        {}

    }//Et on choisi sa couleur
    switch(couleur) {
        case 1: {
            couleur = LED_ROUGE;
            break;
        }
        case 2: {
            couleur = LED_ORANGE;
            break;
        }
        case 3: {
            couleur = LED_JAUNE;
            break;
        }
        case 4: {
            couleur = LED_VERT;
            break;
        }
        case 5: {
            couleur = LED_BLEU_CLAIR;
            break;
        }
        case 6: {
            couleur = LED_BLEU_FONCE;
            break;
        }
        case 7: {
            couleur = LED_MAGENTA;
            break;
        }
        default:
        {}
    }

    //Enfin, on "attache" la pièce la matrice et on affiche celle-ci
    _mat->afficherForme(_ptrForme, couleur);
    _spi.envoyerMatrice(*_mat);
}

//Destructeur de la classe cJeu
cJeu::~cJeu()
{
    delete _ptrForme;
}



void cJeu::nouvelleManche()
{
    //cJeu::nouvelleLigne();
    //tant que l'on peut descendre
    //while(frfd)


    //puis on teste si une ligne est complete
    cJeu::ligneComplete();
}

/*Méthode qui permet de voir s'il une ligne est complète.
Entrées: aucune.
Sortie, une variable de type unsigned int égale à 1 si une ligne est complète, 0 le cas échéant.
Principe:
On parcourt chaque LED de chaque ligne de la matrice.
Si une LED n'est pas éteinte, alors on incrémente une variable.
Si cette variable atteint la valeur 8, c'est que toutes les LEDs d'une ligne sont allumées,
donc que la ligne est complète.
Si une de ces lignes est complète, alors on fait descendre toutes les pièces au-dessus
de la ligne(autres que celle de la manche) d'un cran.    */
unsigned int cJeu::ligneComplete()
{
    unsigned int total = 0, numLigne = 0;
    //On parcourt chaque ligne de la matrice.
    for( unsigned int i = 0; i < _mat->getLig(); i++) {
        total = 0;
        for( unsigned int j = 0; j < _mat->getCol(); j++) {
            //Pour chaque LED de la ligne, si celle-ci n'est pas éteinte
            if(_mat->getValTab(j, i) != LED_NOIR) {
                //alors on incrémente une variable
                total ++;
            }
            //Si cette variable atteint la valeur 8,
            if(total == 8) {
                //on note le numéro de la ligne complète
                numLigne = i;
                //et on quitte la boucle
                break;
            } else {
                //Pas de ligne complète
                return 0;
            }
        }
    }
    //On descend toutes les LEDs allumées au dessus de numLigne d'un cran
    if(numLigne != 0) {
        for( unsigned int i = 0; i < numLigne; i++) {
            total = 0;
            for( unsigned int j = 0; j < _mat->getCol(); j++) {
                _mat->setValTab(j, i, _mat->getValTab(j-1, i));
            }
        }
        //Et on augmente le score!
        _score+=10;
    }
    //On renvoie 1 pour indiquer la présente d'une ligne complète
    return 1;
}

//Méthode
int cJeu::partieEnCours()
{
    int _mvt = 0;
    int perdu = 0;
    Serial pc(USBTX, USBRX);
    cCollision col;
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////

    /*La boucle suivante correspond à une "manche" du jeu:
    On crée une nouvelle pièce.
    Si celle-ci ne peut pas descendre, c'est que la matrice est remplie donc que le joueur a perdu.
    On colore toute la matrice en bleue puis on l'efface.
    Sinon, on effectue s'il y a eu mouvement de l'utilisateur le mouvement de le pièce correspondante.
    On rafraîchit la matrice,
    Puis si c'est possible, on descend la pièce d'une ligne et on rafraîchi de nouveau */

///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
    // Boucle qui se répète tant que la partie n'est pas finie
    while(!perdu) {
        //On crée une nouvelle pièce.
        nouvellePiece();
        pc.printf("Nouvelle piece \n\r");
        //Si celle-ci ne peut pas descendre, c'est que la matrice est remplie donc que le joueur a perdu.
        if(col.pieceBas(*_ptrForme, *_mat) == true) {
            perdu = 1;
            pc.printf("Perdu!! \n\r");
            wait(0.1);
            //On colore toute la matrice en bleue
            for(unsigned int i = 0; i < _mat->getLig(); i++) {
                for(unsigned int j = 0; j < _mat->getCol(); j++) {
                    _mat->setValTab(i, j, LED_BLEU_FONCE);
                }
            }
            _spi.envoyerMatrice(*_mat);
            wait(0.1);
            //Puis on l'efface
            _mat->clear();
            _spi.envoyerMatrice(*_mat);
        }
//////////////////////////////////////////////////////////////////////
        while(col.bordBas(*_ptrForme, *_mat) == false && col.pieceBas(*_ptrForme, *_mat) == false && !perdu) {
            osEvent evt = osMessageGet(*_queue, 500);
            if (evt.status == osEventMessage) {
                pc.printf("Message ==> Recu\n");
                message_t *message = (message_t*)evt.value.p;
                _mvt = message->val;
                osPoolFree(*_pool, message);
            } else {   
                _mvt = 0;
                pc.printf("Pas de message ==> %d\n\r", _mvt);
            }
            switch(_mvt) {
                case 0: {
                    if(col.pieceBas(*_ptrForme, *_mat) == false && col.bordBas(*_ptrForme, *_mat) == false) {
                        pc.printf("AUCUN MOUVEMENT \n\r");
                        _ptrForme->deplacementBas();
                        _mat->updateMatrice();
                        _spi.envoyerMatrice(*_mat);
                    }
                    break;
                }
                case 2: {
                    pc.printf("BAS..");
                    while(col.pieceBas(*_ptrForme, *_mat) == false && col.bordBas(*_ptrForme, *_mat) == false) {
                        _ptrForme->deplacementBas();
                        _mat->updateMatrice();
                        _spi.envoyerMatrice(*_mat);
                        pc.printf("OK\n");
                    }
                    break;
                }
                case 3: {
                    pc.printf("GAUCHE..");
                    if(col.pieceGauche(*_ptrForme, *_mat) == false && col.bordGauche(*_ptrForme) == false) {
                    _ptrForme->deplacementGauche();
                    _mat->updateMatrice();
                    _spi.envoyerMatrice(*_mat);
                    pc.printf("OK\n\r");
                    }
                    break;
                }
                case 4: {
                    pc.printf("DROITE..");
                    if(col.pieceDroite(*_ptrForme, *_mat) == false && col.bordDroit(*_ptrForme) == false) {
                        _ptrForme->deplacementDroite();
                        _mat->updateMatrice();
                        _spi.envoyerMatrice(*_mat);
                        pc.printf("OK\n");
                    }
                    break;
                }
                case 1: {
                    
                    if(col.pieceBas(*_ptrForme, *_mat) == false && col.bordBas(*_ptrForme, *_mat) == false) {
                        pc.printf("ROTATION..");
                        _ptrForme->rotationHoraire();
                        //on rafraîchi la matrice
                        _mat->updateMatrice();
                        _spi.envoyerMatrice(*_mat);
                        pc.printf("OK");
                    }
                    break;
                }
                default: {
                    pc.printf("INCORRECT \n");
                }
            }
        }
        delete _ptrForme;
    }
    return 1;
}

//Méthode de suppression des objets alloués dynamiquement
void cJeu::fin()
{
    delete _ptrForme;
    delete _pool;
    delete _queue;
    delete _mat;
}