Morpion en mode console à 1 ou 2 joueurs (visual c++ .net)

Contenu du snippet

Il s'agit d'un Morpion en c++ , oui je sais il y en a deja , mais celui la ajoute la possibilié de jouer tout seul c'est à dire que l'ordinateur est un peu "intelligent" . J'ai fait en sorte comme vous le verrai qu'il y ai tout de meme quelque coups aléatoires de la part de l'ordi car si il joue trop bien toutes les parties finnissent en égalité (oui le morpion est un jeu très simple :/ ).Mais il ne vous laissera pas gagner comme ca non plus ^^ .

C'est mon premier programme en C++ , testé sous Visual c++ .Net
mais je pense qu'il doit etre compatible sur les autres compilateur ...

Source / Exemple :


//Morpion (par: Thibouf (thibouf@hotmail.com))
//1 joueur contre CPU  ou 2 joueurs en 1 contre 1
//Testé sous Microsoft Visual C++ .net

//-----Declarations -----

//includes
#include <stdlib.h> //systeme
#include <iostream.h> //cin,  cout
#include <time.h> // time pour le rand()

//prototypes fonctions 
void clearscreen();
void grille();
void testape();
void verifgagne();
void defgrille() ;
void changejoueur();
void cin_zero();
void IA ();
void nombrejoueur(); 

//declaration entiers 
const int lignes[8][3] ={{1,2,3},{4,5,6},{7,8,9},{1,4,7},{2,5,8},{3,6,9},{1,5,9},{3,5,7}}; //tableau contenant la liste des lignes possibles dans le tableau  
int n = 0; //chiffre tapé - choix du joueur
int gagne ; //variable pour savoir si le coup est gagnant
int joueur = 2 ; //joueur en cour
int ok = 0; //pour l'IA , permet de savoir si elle a joué 
int nbrjoueur = 1 ;//nombre de joueur selectonné au depart (1 ou 2)
int tabl[10]={0,1,2,3,4,5,6,7,8,9}; //grille sous forme INT pour les calculs 
int valjoueur[3]= {0,100,1000} ; //valeur attribué a chaque joueur permettant de faire les calcul sur chaque ligne 

//declaration char 
char buf[80]; //utilisée pour remettre le cin a zero 
char box[10]={'0','1','2','3','4','5','6','7','8','9'}; // grille affichée 
char  *message = "Choisir un chiffre"; //message à droite 
char signe[3]={0,'X','O'} ;  //charactere associés a chaque joueur

//-----fin des déclarations -----

void grille() //affiche la grille
{
	clearscreen();
	int i =0 ;
	for (i=1; i<=9 ;i++)
	{
		if  (tabl[i] ==valjoueur[1])
			box[i] = 'X';
		else if  (tabl[i] ==valjoueur[2])
			box[i] = 'O';
	}

	cout <<"Joueur : " <<joueur <<" ["<<signe[joueur] <<"]            " <<message <<endl <<endl ; // affiche joueur en cour + message
	cout <<"          |-----------|" <<endl ; //ligne de separation
	cout <<"          | " <<box[7] <<" | " << box[8] <<" | " << box[9] <<" |" <<endl ; // affiche 1ere ligne de la grille
	cout <<"          |-----------|" <<endl ; //ligne de separation
	cout <<"          | " <<box[4] <<" | " << box[5] <<" | " << box[6] <<" |"  <<endl;//affiche 2ere ligne de la grille 
	cout <<"          |-----------|" <<endl ; //ligne de separation
	cout <<"          | " <<box[1] <<" | " << box[2] <<" | " << box[3] <<" |"<<endl ; //affiche 3ere ligne de la grille 
	cout <<"          |-----------|" <<endl <<endl; //ligne de separation
	return ;
}

void clearscreen() // efface l'ecran
{
	system("cls");
	return ;
}

void changejoueur() //passe au joueur suivant
{
	ok = 0;
	if (joueur == 1) { // si 1er joueur 
		joueur = 2 ; 
		if (nbrjoueur == 1) //si un seule joueur  lancer l'"IA"
			IA();
	}else if (joueur == 2) {// si 2e joueur 
		joueur = 1 ;
	}	
	return ;
}

void cin_zero()
{
	cin.clear();//remettre le flux dans l'état good
	cin.getline(buf,80);// poubelliser le reste du buffer
}

void defgrille() // efface l'ecran
{
	int i=0;
	for (i=0 ; i<10;i++)
	{
		tabl[i] =i ;
	}
	box[0]='0';
	box[1]='1';
	box[2]='2';
	box[3]='3';
	box[4]='4';
	box[5]='5';
	box[6]='6';
	box[7]='7';
	box[8]='8';
	box[9]='9';
	return ;

}

void testape() // verifie que le chiffre tapé existe
{
	int erreur =1; 
	while (erreur != 0) { //tant que la frappe n'est pas bonne
		if (!(cin >> n)) //si ce n'est pas un chiffre
		{ 
			cout << "ce n'est pas un chiffre! "<<endl;
			cin_zero();
			erreur = 1;
		}
		else 
		{
			if ( n != 1 && n != 2 && n != 3 && n != 4 && n != 5 && n != 6 && n != 7 && n != 8 && n !=9 ) //si le nombre tapé n'existe pas
			{      
				cout <<" ! Erreur : Case inexistante  !" <<endl; 
				erreur = 1;
			}else if (tabl[n] == valjoueur[1] || tabl[n]== valjoueur[2]  ) //si le nombre tapé est deja utilisé
			{
				cout <<" ! Erreur : Case deja prise  !" <<endl;
				erreur = 1;
			}else
			{
				erreur = 0;
			}
		}
	}
	return ;
}

void verifgagne() // teste si une ligne est complete
{
	gagne =0 ;
	int total = 0; //valeur de la somme d'une ligne
	int i=1;
	for(i=0; i<=7; i++)//verifier si une des ligne est pleine
	{ 
		if ((tabl[lignes[i][0]] == tabl[lignes[i][1]]) && (tabl[lignes[i][1]]==tabl[lignes[i][2]]))
			gagne = 1 ; //gagné
	}
	for(i=0; i<=2 && gagne == 0; i++) //faire le total du tableau en ajoutant le total des 3 1ere lignes  (seulement si personne n'a gangné)
	{ 
		total = total+ (tabl[lignes[i][0]]+tabl[lignes[i][1]]+tabl[lignes[i][2]]); 
		if ((total==((5*valjoueur[1])+(4*valjoueur[2]))) || (total==((4*valjoueur[1])+(5*valjoueur[2])))) //si a partir du total on obtient que le tableau est plein 
			gagne = 2 ; //egalité
	}
	return ;
}

void IA() //Tour ordinateur 
{
	int total = 0; //valeur de la somme d'une ligne
	int j=2; 
	for (j=2;j>=1 && ok==0;j--) //boucle pour verifier chez les 2 joueurs si on peut gagner en commencant par soit meme
	{
		int i=0;
		for(i=0; i<=7; i++) 
		{ 
			total =(tabl[lignes[i][0]]+tabl[lignes[i][1]]+tabl[lignes[i][2]]); //faire le total de la ligne en cour
			if ((total >= (2*valjoueur[j])) &&(total <= (2*valjoueur[j]+9))) //si le total est egal a 2 * la valeur d'un joueur 
			{
				n=total-(2*valjoueur[j]); // jouer la case qui est vide
				ok=1;
			}
		}
	}
	if (ok == 0) //si toujours pas jouer :
	{
		if ( tabl[5]==5) //si la case 5 est vide:  la cocher
		{
			n=5;
			ok=1;
		}
		else //sinon cocher une case au hazard
		{
			srand( (unsigned)time( NULL ) ); //definition de rand() en fonction de time
			while (ok == 0) //tant que la valeur selectionner n'est pas bonne
			{
				int r = (rand()%9)+1; //valeur prise au hazar entre 1 et 9

				if( tabl[r]==r ) //si la case est vide la remplir
				{
					n=r ; 
					ok=1 ;
				}
			}
		}
	}
}

void nombrejoueur()
{
	int erreur =1 ;
	cout << "Choisissez le mode de jeux : " <<endl ;
	cout << "1- Joueur 1 VS CPU" <<endl ;
	cout << "2- Joueur 1 VS Joueur 2" <<endl ;
	while (erreur != 0) { //tant que la frappe n'est pas bonne
		if (!(cin >> nbrjoueur)) //si ce n'est pas un chiffre
		{ 
			cout << "ce n'est pas un chiffre!" <<endl;
			cin_zero();
			erreur = 1;
		}
		else  if  (nbrjoueur!=1 && nbrjoueur!=2) //si le choix n'est ni 1 ni 2
		{
			cout << "Mauvais choix." <<endl ;
			erreur = 1;
		}else
		{
			return ;
		}
	}
	return ;
}

void main() 
{
a:	nombrejoueur();
b:	changejoueur();
	grille();
	if (ok == 0) //si c a un joueur humain de jouer on lui demande de taper un chiffre
		testape();
	tabl[n]=valjoueur[joueur]; //on ecrit le choix dans le tableau
	verifgagne();
	if (gagne == 0) //Si le jeu n'est pas fini , 
		goto b; //tour suivant
	else // si la partie est finie (1 gagnant ou egalite)
	{ 
		grille(); 
		if (gagne == 1) 
			cout <<"Joueur " <<joueur <<" gagne !" <<endl ;
		else if (gagne == 2)
			cout << "Egalite" <<endl ;

		int erreur =1 ;
		int type ;// charactere tapé 
		cout << "Rejouer ?" <<endl ;
		cout << "1- Oui" <<endl ;
		cout << "2- Non" <<endl ;
		while (erreur != 0) //tant que la frappe n'est pas bonne
		{ 
			if (!(cin >> type)) //si ce n'est pas un chiffre
			{ 
				cout << "ce n'est pas un chiffre!" <<endl;
				cin_zero();
				erreur = 1;
			}
			else if (type == 1 ) //si le choix est 2
			{ 
				defgrille() ; //remettre la grille a zero
				cin_zero(); 
				erreur = 0;
			}
			else if  (type == 2 ) //si le choix est 2
			{
				cin_zero(); 
				return ; //quitte le programme
			}
			else  //si le caractere tapé est un autre
			{
				cin_zero();
				erreur = 1;		
			}
		}
	}
	goto a; //revenir au debut
	return ;
}

Conclusion :


Comme vous pouvez le voir j'ai essayé de commenter au maximum mon code et de l'espacer sous forme de fonction pour plus de clarté.
Mais ceci étant ma premiere source n'hesitez pas à me faire part de vos remarques .

Merci.

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.