1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330
|
#include <stdlib.h>
#include <stdio.h>
#include <time.h>//pour les nombres aleatoires
#include <SDL/SDL.h>// pour utiliser la sdl
#include <SDL/SDL_image.h>// pour coller autre que des bmp
#include <SDL/SDL_ttf.h>
#include "Define.h"//Il est deja dans Main.h
//#include "Main.h"
#include "Jeu.h"
#include "Affichage.h"//et pas #include "Jeu.h"
#include "Init.h"
#include "Aide.h"
#include "ia.h"
/*
Reste a faire :
3. créer code erreur : 10001 : pour chaque chargement. Puis boucle : si erreur = 00000 (pas erreur) alors jeu, sinon (chaque est une erreur)
selon chiffre 1 ou 0 liberation de tel ou tel tableu ou autre
5. Etudier les symetries et rotations pour limiter les recherches?
4. bouton tournoi :
a. afficher la ligne de titre
b. afficher les lignes suivantes
c. modification et zones de clic, definir des zones ?
6. augmenter le nombre de joueurs?
7. Integrer le son
On peut remplacer tous les "ecran" par SDL_GetVideoSurface et éviter de passer "ecran" en parametre.
*/
//on doit fournir "&Jeton" et modifier "*Jeton" pour modifier le pointeur dans la fonction
int main(int argc, char **argv)
{
SDL_Event event;//pour gérer les évenements souris et clavier
SDL_Surface *ecran=NULL;
TTF_Font *police = NULL;//police d'ecriture
int JeuFini = NON;//[NON : on continue][OUI : on arrête le jeu], pour la boucle de jeu
int PartieFinie = NON;//[NON :on continue la partie][OUI : on vide le jeu et recommence une nouvelle partie]
int N=3;
int M=3;
int NbJetonsAAligner=3;
int AncienN=N;
int AncienM=M;
int AncienNbJetonsAAligner=NbJetonsAAligner;//on aligne 3 jetons au depart
int PlateauJeuLarg=PlateauLarg;//Dimension reelle de la zone de jeu quand on personnalise les dimensions
int PlateauJeuHaut=PlateauHaut;
Case *plateau;
Info InfoZoneDeRecherche= {0, N, M,0, N, M};
int *HistoriqueJeton= FonctionAllocation1D(N*M);//Ce tableau doit etre dynamique, efectue le test de bonne attribution
int *ListeCasesVides= FonctionAllocation1D(N*M);//Tableau qui contient les numeros de toutes les cases vides au debut puis -1 pour les cases occupées.
int NbCasesJouees=0;
Images Jeton = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL}; //On initialise toutes les images à NULL
int ClicX=0;
int ClicY=0;
int posX=0;
int posY=0;
int SourisCachee=NON;//[NON : Souris visible][OUI : Souris cachée]
int NbAlignements=0;//Compte le nombre d'alignements gagnants
jeu TypeJeu=HH;//HH, HO, OH, OO; puis rajouter N si 3 jetons ou plus
Joueur ListeJoueurs[2]= {{H, Rond}, {H, Croix}};//2 joueurs humains pur commencer puis on changera en appuyant sur le bouton Config
Joueur joueurEnCours=ListeJoueurs[0];//il faut trouver un moyen de modifier la liste des joueur lorsque l'on modifie la config
int ConfigModifiee=NON;//[NON : ne pas actualiser si echap lors de ConfigDim][OUI : actualiser les tableaux lors de ConfigDim]
// int NumMatch=0;//indique le numero du match que l'on est en train de jouer
//char numMatch[2]="";//pour afficher les numéros du texte en chaine de caracteres
zone ZoneEvenement = MARGE;
// MancheTournoi MancheInitiale= {11,{H, Rond}, {H, Croix},3,3,3}; //tournoi de 10 manches au maximum
MancheTournoi Tournoi[10];/*=
{
{1,{H, Rond}, {H, Croix},3,3,3},
{2,{H, Rond}, {H, Croix},3,3,3},
{3,{H, Rond}, {H, Croix},3,3,3},
{4,{H, Rond}, {H, Croix},3,3,3},
{5,{H, Rond}, {H, Croix},3,3,3},
{6,{H, Rond}, {H, Croix},3,3,3},
{7,{H, Rond}, {H, Croix},3,3,3},
{8,{H, Rond}, {H, Croix},3,3,3},
{9,{H, Rond}, {H, Croix},3,3,3},
{10,{H,Rond}, {H, Croix},3,3,3}
};*///tournoi de 10 manches au maximum
int MaxMancheTournoi=10;
InitTournoi(Tournoi, &MaxMancheTournoi);
/**********************/ //debut du programme
initSDL(&ecran);
SDL_EventState(SDL_MOUSEBUTTONUP, SDL_IGNORE);//ignore tous les clics. A reactiver apres le titre avec SDL_EventState(SDL_MOUSEBUTTONUP, SDL_ENABLE);
police = TTF_OpenFont("times.ttf", 30);//chargement de la police d'ecriture et de la taille
if(police==NULL)//si erreur d'allocation de police
{
fprintf(stderr, "Erreur de chargement de la police: %s\n", SDL_GetError());
exit(EXIT_FAILURE);//quitter le programme
}
plateau=malloc(N*M*sizeof(*plateau));//Ce tableau doit etre dynamique
if(plateau==NULL)//si erreur d'allocation
{
free(plateau);//liberation de la 1ere dimension
fprintf(stderr, "Erreur de creation tableau plateau: %s\n", SDL_GetError());
exit(EXIT_FAILURE);//quitter le programme
}
if(ChargementImages(&Jeton)==NON)//Si l'initialisation retourne faux
{
fprintf(stderr, "Problème pour charger les images : %s\n", SDL_GetError());//Si l'initialisation de la SDL a échoué, on retourne faux
exit(EXIT_FAILURE);//quitter le programme
}//alors, nous sortons de la fonction main et mettons fin au programme.
SDL_ShowCursor(SDL_DISABLE);//on cache le pointeur de la souris
SourisCachee=OUI;//la souris est cachée
AfficheTitre(ecran);//Affiche le titre du jeu sur fond marron
AfficheBoutons(ecran, police, &Jeton, TypeJeu, EcranJeu);
SDL_Delay(1000);//attend 1000ms = 1 seconde avant de passer a la suite
srand(time(NULL)*1000); //
PlateauJeuLarg=PlateauLarg/maximumEntre(N, M)*N;//Dimension reelle de la zone de jeu
PlateauJeuHaut=PlateauHaut/maximumEntre(N, M)*M;
while(JeuFini==NON)//Maintenant que l'initialisation est valide, on entre dans la boucle de jeu
{
videJeu(plateau, N, M, ListeJoueurs, &joueurEnCours, &PartieFinie, &NbCasesJouees, HistoriqueJeton, ListeCasesVides);//Vide le plateau de jeu
AfficheJeu(ecran, plateau, N, M, &Jeton);//affiche le jeu vide
AfficheBoutons(ecran, police, &Jeton, TypeJeu, EcranJeu);
SDL_EventState(SDL_MOUSEBUTTONUP, SDL_ENABLE);//reactive les clics
while(PartieFinie==NON)
{
if(joueurEnCours.joueur==O)//Si c'est a l'ordi de jouer
{
DefinirZoneEtendue(&InfoZoneDeRecherche, N, M, &NbCasesJouees, NbJetonsAAligner, HistoriqueJeton);//determine la zone a etudier
DefinirListeCaseVide(&InfoZoneDeRecherche, N, M, &NbCasesJouees, HistoriqueJeton, /* HistoriqueJetonClasse, */ ListeCasesVides);//Détermine la TableauCaseVide
OrdiJoue(plateau, N, M,&InfoZoneDeRecherche, ListeJoueurs, &NbCasesJouees, &PartieFinie, NbJetonsAAligner, HistoriqueJeton, ListeCasesVides);
if(NbCasesJouees>=2*NbJetonsAAligner-1)//on verifie s'il y a alignement au bout du 5eme jeton rond posé, (Jouées = 3*o+2*x)
{
verifFini(plateau, N, M, HistoriqueJeton[NbCasesJouees-1], ListeJoueurs, &PartieFinie, &NbCasesJouees, NbJetonsAAligner, &NbAlignements); //Fonction pour vérifier si la partie est terminée
}
AfficheJeu(ecran, plateau, N, M, &Jeton);
joueurEnCours= ListeJoueurs[NbCasesJouees%2];//joueur suivant
SDL_Delay(500);
}
while(SDL_PollEvent(&event))//Traiter les évènements
{
switch(event.type)
{
case SDL_QUIT://Si on a cliqué sur la croix
ZoneEvenement=QUITTER;
break;
case SDL_KEYUP://Si touche du clavier enfoncée
switch (event.key.keysym.sym)//selon la touche enfoncée
{
case SDLK_ESCAPE: // Appui sur la touche Echap, on va arrêter le jeu
case SDLK_a: // Appui sur la touche q (Attention a<->q avec les claviers qwerty-azerty), on va arrêter le jeu
ZoneEvenement=QUITTER;
break;
case SDLK_q: // Appui sur la touche a (Attention a<->q avec les claviers qwerty-azerty), on va annuler le dernier coup
ZoneEvenement=ANNULER;
break;
case SDLK_n: //si on presse le n de nouveau
ZoneEvenement=NOUVEAU;
break;
case SDLK_t: //si on presse le t de Tournoi
ZoneEvenement=TOURNOI;
break;
case SDLK_i: //si on presse le i de aIde
ZoneEvenement=AIDE;
break;
case SDLK_v: //si on presse le v de Valider
ZoneEvenement=VALIDER;
break;
case SDLK_d: //si on presse le d de configDim
ZoneEvenement=CONFIGDIMENSION;
break;
default ://sinon rien pour eviter message d'alerte lors de la compilation
break;
}
break;
case SDL_MOUSEMOTION://Si souris déplacée
posX=event.motion.x;
posY=event.motion.y;
GestionPointeur(posX, posY, &SourisCachee, ecran, plateau, PlateauJeuLarg, PlateauJeuHaut, N, M, &Jeton, ListeJoueurs, &joueurEnCours, &NbCasesJouees); //Fonction pour gerer l'affichage du pointeur
break;
case SDL_MOUSEBUTTONUP://Si clic souris
ClicX=event.button.x;
ClicY=event.button.y;
ZoneEvenement = QuelleZoneCliquee(ClicX, ClicY,PlateauJeuLarg, PlateauJeuHaut, joueurEnCours);
break;
default: //Sinon on ne fait rien
break;
}
switch(ZoneEvenement)
{
case JEU :
HumainJoue(ClicX, ClicY, plateau, N, M, ListeJoueurs, &NbCasesJouees, HistoriqueJeton);//gestion du clic souris
if(NbCasesJouees>=2*NbJetonsAAligner-1)//on verifie s'il y a alignement au bout du 5eme jeton rond posé, (Jouées = 3*o+2*x)
{
verifFini(plateau, N, M, HistoriqueJeton[NbCasesJouees-1], ListeJoueurs, &PartieFinie, &NbCasesJouees, NbJetonsAAligner, &NbAlignements); //Fonction pour vérifier si la partie est terminée
}
AfficheJeu(ecran, plateau, N, M, &Jeton);
AffichePointeur(ecran, &Jeton, ListeJoueurs, &joueurEnCours, &NbCasesJouees, ClicX, ClicY);//pour afficher le pointeur quand on clique et que l'on ne bouge pas
ZoneEvenement=MARGE;
break;
case NOUVEAU:
videJeu(plateau, N, M, ListeJoueurs, &joueurEnCours, &PartieFinie, &NbCasesJouees, HistoriqueJeton, ListeCasesVides);
PartieFinie=OUI;//On met PartieFinie a OUI pour quitter la boucle secondaire*/
ZoneEvenement=MARGE;
break;
case ANNULER:
if(ListeJoueurs[(NbCasesJouees-1)%2].joueur==O)//si le joueur precedent est l'ordi, alors il faut annuler 2 jetons
{
AnnulerCoup(plateau, ListeJoueurs, &joueurEnCours, &NbCasesJouees, HistoriqueJeton);//on annule le coup supplementaire
}
AnnulerCoup(plateau, ListeJoueurs, &joueurEnCours, &NbCasesJouees, HistoriqueJeton);//on annule le coup obligatoire et on actualise le joueurEnCours
AfficheJeu(ecran, plateau, N, M, &Jeton);//on affiche la modification
AffichePointeur(ecran, &Jeton, ListeJoueurs, &joueurEnCours, &NbCasesJouees, posX, posY);//pour afficher le pointeur quand on clique et que l'on ne bouge pas
AfficheBoutons(ecran, police, &Jeton, TypeJeu, EcranJeu);
ZoneEvenement=MARGE;//pour eviter de boucler et de renouveller ANNULER
break;
case CONFIGTYPE:
TypeJeu=ConfigType(ecran, TypeJeu, &Jeton, ClicX-BoutonX, ClicY-BoutonYConfigType, ListeJoueurs/*, 2*/);//Les coordonnéees envoyées sont relatives au coin superieur gauche du bouton Config
joueurEnCours=ListeJoueurs[NbCasesJouees%2];//il faut actualiser le joueurEnCours
ZoneEvenement=MARGE;
break;
case CONFIGDIMENSION:
joueurEnCours=ListeJoueurs[NbCasesJouees%2];
AncienN=N;
AncienM=M;
AncienNbJetonsAAligner=NbJetonsAAligner;
ConfigDimension(ecran, police,TypeJeu,PlateauJeuLarg, PlateauJeuHaut, joueurEnCours, &Jeton, &N, &M, &NbJetonsAAligner, &ConfigModifiee);//on ouvre la configuration pour determiner le nombre de lignes et de colonnes du plateau de jeu et le nombre de jetons a aligner pour gagner
if(ConfigModifiee==OUI)//si on modifie les dimensions du plateau de jeu
{
/* videJeu(plateau, AncienN, AncienM, ListeJoueurs, &joueurEnCours, &PartieFinie, &NbCasesJouees, HistoriqueJeton, ListeCasesVides);//Vide le plateau de jeu AVANT d'avoir modifier les dimensions, pour tout remettre a zero
free(plateau);
plateau=NULL;
plateau=malloc(N*M*sizeof(*plateau));//on realloue un plateau aux nouvelles dimensions
if(plateau==NULL)//si erreur d'allocation
{
free(plateau);//liberation du plateau
fprintf(stderr, "Erreur de creation du tableau plateau");
exit(EXIT_FAILURE);//quitter le programme
}
free(HistoriqueJeton);//on libere HistoriqueJeu
HistoriqueJeton=NULL;
HistoriqueJeton= FonctionAllocation1D(N*M);//Ce tableau doit etre dynamique, efectue le test de bonne attribution
free(ListeCasesVides);//on libere HistoriqueJeu
ListeCasesVides=NULL;
ListeCasesVides= FonctionAllocation1D(N*M);//Tableau qui contient les numeros de toutes les cases vides au debut puis -1 pour les cases occupées.
videJeu(plateau, N, M, ListeJoueurs, &joueurEnCours, &PartieFinie, &NbCasesJouees, HistoriqueJeton, ListeCasesVides);//Vide le plateau de jeu APRES d'avoir modifier les dimensions, sinon, on ne vide pas tout le tableau
PlateauJeuLarg=PlateauLarg/maximumEntre(N, M)*N;//Dimension reelle de la zone de jeu quand on personnalise les dimensions
PlateauJeuHaut=PlateauHaut/maximumEntre(N, M)*M;
ConfigModifiee=NON;*/
ModificationConfigDimension(AncienN, AncienM, N,M, plateau, ListeJoueurs,&joueurEnCours, &PartieFinie, &NbCasesJouees, HistoriqueJeton, ListeCasesVides);
ConfigModifiee=NON;
PlateauJeuLarg=PlateauLarg/maximumEntre(N, M)*N;//Dimension reelle de la zone de jeu quand on personnalise les dimensions
PlateauJeuHaut=PlateauHaut/maximumEntre(N, M)*M;
}
AfficheJeu(ecran, plateau, N, M, &Jeton);
AfficheBoutons(ecran, police, &Jeton, TypeJeu, EcranJeu);
ZoneEvenement=MARGE;
break;
case TOURNOI:
DetermineTournoi(ecran, police, &Jeton, TypeJeu,PlateauJeuLarg, PlateauJeuHaut, joueurEnCours, Tournoi,10, &MaxMancheTournoi);//determine els composante du tournoi
AfficheJeu(ecran, plateau, N, M, &Jeton);
AfficheBoutons(ecran, police, &Jeton, TypeJeu, EcranJeu);
ZoneEvenement=MARGE;
break;
case AIDE:
Aide(ecran, police, &Jeton,TypeJeu,PlateauJeuLarg, PlateauJeuHaut, joueurEnCours);//on ouvre le menu d'aide
AfficheJeu(ecran, plateau, N, M, &Jeton);
ZoneEvenement=MARGE;//pour eviter de boucler su le menu AIDE
break;
case QUITTER:
JeuFini=OUI; //On met JeuFini a OUI pour quitter la 1ere boucle principale
PartieFinie=OUI;//On met PartieFinie a OUI pour quitter la 2eme boucle principale
ZoneEvenement=MARGE;
break;
case MARGE:
break;
default: //Sinon on ne fait rien
break;
}
}
SDL_Flip(ecran);//Rafraichissement de l'écran. Il faut le sortir du while car sinon il attend de bouger la souris pour faire jouer le joueur suivant
}
SDL_Delay(1000);//Attendre avant de fermer ou de commencer une nouvelle partie : 1000 ms = 1 s
}
free(ecran);//liberation de lecran
free(plateau);//liberation du plateau de jeu
plateau=NULL;
free(HistoriqueJeton);
HistoriqueJeton=NULL;
free(ListeCasesVides);
ListeCasesVides=NULL;
LiberationImages(&Jeton);
TTF_CloseFont(police); // Fermeture de la police, doit être fermée avant TTF_Quit()
TTF_Quit();
SDL_Quit();
return EXIT_SUCCESS;//on quitte le jeu avec succes
} |
Partager