Jeu.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2007 by Pierre Schmitt, Ludovic Giacomello, Nhi Ly   *
00003  *      *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00019  ***************************************************************************/
00020 
00021 #include "Jeu.h"
00022 
00023 bool Jeu::GameOver(){
00024         if(!mPacmanVivant) return true;
00025         if(mNBPomme==0) return true;
00026         return false;
00027 }
00028 
00029 Jeu::Jeu(){
00030         mNbFantomeAuto=-1;
00031         //Initialisations des variables relatives aux joueurs 
00032         mJoueurPacman=false;
00033         for(unsigned int i=0; i<3; i++) mJoueurF[i]=false;
00034         
00035         //Initialisation des attributs de pacman
00036         mScorePacman=0;
00037         mPacmanVivant=true;
00038 
00039         //Initialisation de la grille
00040         Point coord;
00041         for(unsigned int i=0; i<20; i++){
00042                 for(unsigned int j=0; j<20; j++){
00043                         mGrille[i][j]='+';
00044                 }
00045         }
00046         //Construction des bordures
00047         ConstruireMur(0,0,20,'H');
00048         ConstruireMur(0,0,20,'V');
00049         ConstruireMur(0,19,20,'H');
00050         ConstruireMur(19,0,20,'V');     
00051         //Construction aléatoire de murs internes 
00052         char sens;
00053         for(unsigned int i=0; i<20; i++){
00054                 if(UintAleat(1,2)==1) sens='V'; //On détermine l'orientation à pile ou face
00055                 else sens='H';
00056                 ConstruireMur(UintAleat(0,19),UintAleat(0,19),UintAleat(0,5),sens);
00057         }
00058         unsigned int x,y;
00059         //On place 100 fruits
00060         mNBPomme=0;
00061         for(unsigned int i=0; i<100; i++){
00062                 do{
00063                         x=UintAleat(0,19); y=UintAleat(0,19);
00064                 } while(PointLibre(x,y)!=0); //Case non libre
00065                 SetPoint(x,y,'x');
00066                 mNBPomme++;
00067         }
00068         //On place 1 pacman 
00069         do{
00070                 x=UintAleat(0,19); y=UintAleat(0,19);
00071         } while(PointLibre(x,y)!=0); //Case non libre
00072         SetPoint(x,y,'P');
00073         coord.x=x; coord.y=y;
00074         mCoordPacman=coord;
00075         //On place 3 fantomes 
00076         for(unsigned int i=0; i<3; i++){
00077                 do{
00078                         x=UintAleat(0,19); y=UintAleat(0,19);
00079                 } while(PointLibre(x,y)!=0); //Case non libre
00080                 SetPoint(x,y,'F');
00081                 coord.x=x; coord.y=y;
00082                 mCoordF[i]=coord;
00083                 mScoreF[i]=0;
00084         }
00085 }
00086 
00087 Jeu::~Jeu(){}
00088 
00089 bool Jeu::DeplacerPersonnage(unsigned int codePerso, char sens){
00090         if(codePerso==3){
00091                 return DeplacerPacman(sens);
00092         } else if((codePerso>=0)&&(codePerso<=2)){
00093                 return DeplacerFantome(codePerso,sens);
00094         }
00095         return false;
00096 }
00097 
00098 bool Jeu::DeplacerPacman(char sens){
00099         unsigned int newX, newY;
00100         switch(sens){
00101                 case 'G' : {
00102                         newX=mCoordPacman.x-1; newY=mCoordPacman.y;
00103                         break;
00104                 }
00105                 case 'D' : {
00106                         newX=mCoordPacman.x+1; newY=mCoordPacman.y;
00107                         break;
00108                 }
00109                 case 'H' : {
00110                         newX=mCoordPacman.x; newY=mCoordPacman.y-1;
00111                         break;
00112                 }
00113                 case 'B' : {
00114                         newX=mCoordPacman.x; newY=mCoordPacman.y+1;
00115                         break;
00116                 }
00117         }
00118         switch(PointLibre(newX,newY)){
00119                 case -1 : { //Mouvement hors plateau
00120                         //Pas de déplacement
00121                         return false;
00122                 }
00123                 case 0 : {  //Case vide
00124                         SetPoint(mCoordPacman.x,mCoordPacman.y,'+');
00125                         mCoordPacman.x=newX; mCoordPacman.y=newY;
00126                         SetPoint(mCoordPacman.x,mCoordPacman.y,'P');
00127                         return true;
00128                 }
00129                 case 1 : { //Occupée par un fruit
00130                         SetPoint(mCoordPacman.x,mCoordPacman.y,'+');
00131                         mCoordPacman.x=newX; mCoordPacman.y=newY;
00132                         SetPoint(mCoordPacman.x,mCoordPacman.y,'P');
00133                         mScorePacman++;
00134                         mNBPomme--;
00135                         return true;
00136                 }
00137                 //case 2 impossible (pacman n'a pas le don d'ubiquité :=)
00138 
00139                 case 3 : { //Occupée par un fantôme
00140                         //On efface le pauvre pacman
00141                         SetPoint(mCoordPacman.x,mCoordPacman.y,'+');
00142                         mPacmanVivant=false;
00143                         return false;
00144                 }
00145                 case 4 : { //Occupée par un mur
00146                         //Pas de déplacement
00147                         return false;
00148                 }
00149         }               
00150 }
00151 
00152 bool Jeu::DeplacerFantome(unsigned int noFantome, char sens){
00153         unsigned int newX, newY;
00154         switch(sens){
00155                 case 'G' : {
00156                         newX=mCoordF[noFantome].x-1; newY=mCoordF[noFantome].y;
00157                         break;
00158                 }
00159                 case 'D' : {
00160                         newX=mCoordF[noFantome].x+1; newY=mCoordF[noFantome].y;
00161                         break;
00162                 }
00163                 case 'H' : {
00164                         newX=mCoordF[noFantome].x; newY=mCoordF[noFantome].y-1;
00165                         break;
00166                 }
00167                 case 'B' : {
00168                         newX=mCoordF[noFantome].x; newY=mCoordF[noFantome].y+1;
00169                         break;
00170                 }
00171         }
00172         switch(PointLibre(newX,newY)){
00173                 case -1 : { //Mouvement hors plateau
00174                         //Pas de déplacement
00175                         mVerrou.Unlock();
00176                         return false;
00177                 }
00178                 case 0 : {  //Case vide
00179                         //On efface la case sur laquelle était le fantome
00180                         SetPoint(mCoordF[noFantome].x,mCoordF[noFantome].y,'+');
00181                         //Si on a en mémoire les coordonées d'un fruit, on le replace sur la grille 
00182                         if((mCoordP[noFantome].x!=-1)&&(mCoordP[noFantome].y!=-1)) SetPoint(mCoordP[noFantome].x,mCoordP[noFantome].y,'x');
00183                         //On déplace le fantome
00184                         mCoordF[noFantome].x=newX; mCoordF[noFantome].y=newY;
00185                         SetPoint(mCoordF[noFantome].x,mCoordF[noFantome].y,'F');
00186                         //On indique que le fantome n'a pas écrasé de fruit 
00187                         mCoordP[noFantome].x=-1; mCoordP[noFantome].y=-1;
00188                         mVerrou.Unlock();
00189                         return true;
00190                 }
00191                 case 1 : { //Occupée par un fruit
00192                         //On efface la case sur laquelle était le fantome
00193                         SetPoint(mCoordF[noFantome].x,mCoordF[noFantome].y,'+');
00194                         //Si on a en mémoire les coordonées d'un fruit, on le replace sur la grille 
00195                         if((mCoordP[noFantome].x!=-1)&&(mCoordP[noFantome].y!=-1)) SetPoint(mCoordP[noFantome].x,mCoordP[noFantome].y,'x');
00196                         //On place le fantome à la nouvelle position ce faisant on efface un fruit
00197                         mCoordF[noFantome].x=newX; mCoordF[noFantome].y=newY;
00198                         SetPoint(mCoordF[noFantome].x,mCoordF[noFantome].y,'F');
00199                         //Mais on le garde en mémoire afin de le replacer ultérieurement
00200                         mCoordP[noFantome].x=newX; mCoordP[noFantome].y=newY;
00201                         mVerrou.Unlock();
00202                         return true;
00203                 }
00204                 case 2 : { //Occupée par pacman
00205                         //On efface la case sur laquelle était le fantome
00206                         SetPoint(mCoordF[noFantome].x,mCoordF[noFantome].y,'+');
00207                         //Si on a en mémoire les coordonées d'un fruit, on le replace sur la grille 
00208                         if((mCoordP[noFantome].x!=-1)&&(mCoordP[noFantome].y!=-1)) SetPoint(mCoordP[noFantome].x,mCoordP[noFantome].y,'x');
00209                         //On déplace le fantome
00210                         mCoordF[noFantome].x=newX; mCoordF[noFantome].y=newY;
00211                         SetPoint(mCoordF[noFantome].x,mCoordF[noFantome].y,'F');
00212                         //Pour pacman c'est la fin...
00213                         mScoreF[noFantome]+=10;
00214                         mPacmanVivant=false;
00215                         //On indique que le fantome n'a pas écrasé de fruit (par pure conscience professionelle hein)
00216                         mCoordP[noFantome].x=-1; mCoordP[noFantome].y=-1;
00217                         mVerrou.Unlock();
00218                         return true;
00219                 }
00220                 case 3 : { //Occupée par un fantôme
00221                         //Pas de déplacement
00222                         mVerrou.Unlock();
00223                         return false;
00224                 }
00225                 case 4 : { //Occupée par un mur
00226                         //Pas de déplacement
00227                         mVerrou.Unlock();
00228                         return false;
00229                 }
00230         }
00231         
00232 }
00233 
00234 //Private
00235 void Jeu::ConstruireMur(unsigned int x, unsigned int y, unsigned int l, char s){
00236         unsigned int i;
00237         if(s=='V'){
00238                 //De x,y vers le bas (x reste fixe, on incrémente y)
00239                 for(i=y; i<=y+l; i++) SetPoint(x,i,'I');
00240         } else {
00241                 //De x,y vers la droite (on incrémente x, y reste fixe)
00242                 for(i=x; i<=x+l; i++) SetPoint(i,y,'I');
00243         }
00244 }
00245 
00246 void Jeu::SetPoint(unsigned int x, unsigned int y, char c){
00247         mVerrou.Lock();
00248         if((x>=0)&&(x<20)){
00249                 if((y>=0)&&(y<20)){
00250                         mGrille[y][x]=c;
00251                 }
00252         }
00253         mVerrou.Unlock();       
00254 }
00255 
00256 string Jeu::JoueurConnectes() const{
00257         string res="";
00258         for(unsigned int i=0; i<3; i++) {
00259                 if(mJoueurF[i]) res+='1';
00260                 else res+='0';
00261         }
00262         if(mJoueurPacman) res+='1';
00263         else res+='0';
00264         return res;
00265 }
00266 
00267 string Jeu::toString(){
00268         mVerrou.Lock();
00269         string res="";
00270         for(unsigned int i=0; i<20; i++){
00271                 for(unsigned int j=0; j<20; j++){
00272                         res+=mGrille[i][j];
00273                 }
00274         }       
00275         mVerrou.Unlock();
00276         return res;
00277 }
00278 
00279 string Jeu::EtatPartie(){
00280 //mLoginPacman mScorePacman mLoginF mScoreF mNBPomme status
00281         string etat="";
00282         etat+=mLoginPacman; etat+=" ";
00283         ostringstream ossScoreP;
00284         ossScoreP<<mScorePacman;
00285         etat+=ossScoreP.str(); etat+=" ";
00286         for(unsigned int i=0; i<3; i++){
00287                 etat+=mLoginF[i]; etat+=" ";
00288                 ostringstream ossScore;
00289                 ossScore<<mScoreF[i];
00290                 etat+=ossScore.str(); etat+=" ";
00291         }
00292         ostringstream ossPomme;
00293         ossPomme<<mNBPomme;
00294         etat+=ossPomme.str(); etat+=" ";
00295         if(GameOver()) etat+="GAMEOVER";
00296         else etat+="GAMEOK";
00297         return etat;
00298         
00299 }
00300 
00301 bool Jeu::JeuPret() const{
00302         if((mJoueurPacman)&&(mJoueurF[0])&&(mJoueurF[1])&&(mJoueurF[2])) return true;
00303         return false;
00304 }
00305 
00306 unsigned int Jeu::UintAleat(unsigned int min, unsigned int max){
00307         static bool first=true;
00308         //On initialise le générateur en fonction de l'horloge
00309         if(first) {
00310                 srand((unsigned)time(NULL));
00311                 first=false;
00312         }
00313         unsigned int nb=(unsigned)rand();
00314         //on tire un nombre au hasard et on le place sur le bon intervalle.
00315         unsigned int final=(unsigned int)(min+((float)rand()/RAND_MAX*(max)));
00316         if(final==0) return 1;
00317         return final;
00318 }
00319 
00320 void Jeu::Afficher() const{
00321         for(unsigned int i=0; i<20; i++){
00322                 for(unsigned int j=0; j<20; j++){
00323                         switch(mGrille[i][j]){
00324                                 case '+' : {
00325                                         printf( "\e[30;47m%c \e[m",mGrille[i][j]);
00326                                         break;
00327                                 }
00328                                 case 'x' : {
00329                                         printf( "\e[30;47m\e[33m%c \e[m\e[m",mGrille[i][j]);
00330                                         break;
00331                                 }
00332                                 case 'P' : {
00333                                         printf( "\e[30;47m\e[34m%c \e[m\e[m",mGrille[i][j]);
00334                                         break;
00335                                 }
00336                                 case 'F' : {
00337                                         printf( "\e[30;47m\e[31m%c \e[m\e[m",mGrille[i][j]);
00338                                         break;
00339                                 }
00340                                 case 'I' : {
00341                                         printf( "\e[30;47m%c \e[m",mGrille[i][j]);
00342                                         break;
00343                                 }
00344                         }               
00345                 }
00346                 if(i==0) printf( "  \e[30;47m Score Pacman \e[31m%d \e[m\e[m\n",mScorePacman);
00347                 else cout<<endl;
00348         }       
00349 }
00350 
00351 int Jeu::PointLibre(unsigned int x, unsigned int y) {
00352         mVerrou.Lock();
00353         if((x>=0)&&(x<20)){
00354                 if((y>=0)&&(y<20)){
00355                         switch(mGrille[y][x]){
00356                                 case '+' : { mVerrou.Unlock(); return 0; } //Case vide
00357                                 case 'x' : { mVerrou.Unlock(); return 1; } //Occupée par un fruit
00358                                 case 'P' : { mVerrou.Unlock(); return 2; } //Occupée par Pacman
00359                                 case 'F' : { mVerrou.Unlock(); return 3; } //Occupée par un fantôme
00360                                 case 'I' : { mVerrou.Unlock(); return 4; } //Occupée par un mur
00361                                 default : { mVerrou.Unlock(); return -1; }
00362                         }
00363                 }
00364         }
00365         mVerrou.Unlock();
00366         return -1;
00367 }

Generated on Wed Jan 2 14:01:41 2008 for Pacman by  doxygen 1.5.1