Bonjour,
Je suis en train d créer un puissance 4 en C mais le problème est que quand il y a 4 pions alignés le programme ne s'arrête pas en affichant le gagnant, le programme continue jusqu'à ce que la grille soit remplie.
Mais je ne vois pas le problème dans ma fonction aGagne.. Auriez vous des solutions à me proposer ?
Merci d'avance !
Mon code :
void init (int ttint_plateau[N][N]){
int int_i;
int int_j;
for(int_i=0;int_i<N;int_i++){
for(int_j=0;int_j<N;int_j++){
ttint_plateau[int_i][int_j]=' ';
}
}
}
void affichage(int ttint_plateau[N][N]){
int int_i;
int int_j;
printf(" 0 1 2 3 4 \n");
for(int_i=0;int_i<N;int_i++){
printf(" +---+---+---+---+---+\n");
printf("%d|",int_i);
for(int_j=0;int_j<N;int_j++){
ttint_plateau[int_i][int_j];
printf("%c |", ttint_plateau[int_i][int_j]);
}
printf("\n");
}
printf(" +---+---+---+---+---+\n");
}
int jouer (int ttint_plateau[N][N], int int_joueur, int int_x){
int retour_choixCol;
int int_choixCol;
int int_ligne;
int_ligne=5;
do {
printf("Joueur %d, entrez un numéro de colonne entre 0 et 4 :\n", int_joueur);
retour_choixCol=scanf("%d", &int_choixCol);
if(retour_choixCol==1){
while(ttint_plateau[int_ligne][int_choixCol]!=' '){
if(int_ligne>=1){
int_ligne=int_ligne-1;
}else{
printf("Cette colonne est remplie perdu !!");
exit(ERREURSAISIE);
}
}
if(int_x==1){
ttint_plateau[int_ligne][int_choixCol]='O';
return(ttint_plateau);
}else{
ttint_plateau[int_ligne][int_choixCol]='X';
return(ttint_plateau);
}
}else{
return(ERREURSAISIE);
}
}while(int_choixCol<0 || int_choixCol>4);
}
int horizontale(int ttint_plateau[N][N]){
int int_i;
int int_j;
for(int_i=0;int_i<N;int_i++){
for(int_j=0;int_j<2;int_j++){
if (ttint_plateau[int_i][int_j]==ttint_plateau[int_i][int_j+1]==ttint_plateau[int_i][int_j+2]==ttint_plateau[int_i][int_j+3]&& ttint_plateau[int_i][int_j]!=' '){
if(ttint_plateau[int_i][int_j]=='0'){
return(1);
}else{
return(2);
}
}
}
}
return(-1);
}
int verticale(int ttint_plateau[N][N]){
int int_i;
int int_j;
for(int_j=0;int_j<N;int_j++){
for(int_i=0;int_i<2;int_i++){
if (ttint_plateau[int_i][int_j]==ttint_plateau[int_i+1][int_j]==ttint_plateau[int_i+2][int_j]==ttint_plateau[int_i+3][int_j] && ttint_plateau[int_i][int_j]!=' '){
if(ttint_plateau[int_i][int_j]=='0'){
return(1);
}else{
return(2);
}
}
}
}
return(-1);
}
int diagonaledroite(int ttint_plateau[N][N]){
int int_i;
int int_j;
for(int_i=0;int_i<2;int_i++){
for(int_j=0;int_j<2;int_j++){
if (ttint_plateau[int_i+3][int_j]==ttint_plateau[int_i+2][int_j+1]==ttint_plateau[int_i+1][int_j+2]==ttint_plateau[int_i][int_j+3] && ttint_plateau[int_i+3][int_j]!=' '){
if(ttint_plateau[int_i+3][int_j]=='0'){
return(1);
}else{
return(2);
}
}
}
}
return(-1);
}
int diagonalegauche(int ttint_plateau[N][N]){
int int_i;
int int_j;
for(int_j=0;int_j<2;int_j++){
for(int_i=1;int_i>=0;int_i--){
if (ttint_plateau[int_i][int_j]==ttint_plateau[int_i+1][int_j+1]==ttint_plateau[int_i+2][int_j+2]==ttint_plateau[int_i+3][int_j+3] && ttint_plateau[int_i][int_j]!=' '){
if(ttint_plateau[int_i][int_j]=='0'){
return(1);
}else{
return(2);
}
}
}
}
return(-1);
}
int caserestante(int ttint_plateau[N][N]){
int int_i;
int int_j;
for(int_i=0;int_i<N;int_i++){
for(int_j=0;int_j<2;int_j++){
if(ttint_plateau[0][0]!=' '&&ttint_plateau[0][1]!=' '&&ttint_plateau[0][2]!=' '&&ttint_plateau[0][3]!=' '&&ttint_plateau[0][4]!=' '){
return(0);
}
}
}
return(-1);
}
int aGagne(int ttint_plateau[N][N]){
if(verticale(ttint_plateau)==1 || verticale(ttint_plateau)==2){
return(verticale(ttint_plateau));
printf("Le joueur %d a gagné !", verticale(ttint_plateau));
}else{
if(horizontale(ttint_plateau)==1 || horizontale(ttint_plateau)==2){
return(horizontale(ttint_plateau));
printf("Le joueur %d a gagné !", horizontale(ttint_plateau));
}else{
if(diagonaledroite(ttint_plateau)==1 || diagonaledroite(ttint_plateau)==2){
return(diagonaledroite(ttint_plateau));
printf("Le joueur %d a gagné !", diagonaledroite(ttint_plateau));
}else{
if(diagonalegauche(ttint_plateau)==1 || diagonalegauche(ttint_plateau)==2){
return(diagonalegauche(ttint_plateau));
printf("Le joueur %d a gagné !", diagonalegauche(ttint_plateau));
}else{
if(caserestante(ttint_plateau)==0){
return(0);
printf("match nul...");
}else{
return(-1);
}
}
}
}
}
}
void tourDeJeu(int ttint_plateau[N][N]){
int int_i;
int int_j;
int int_joueur;
while(aGagne(ttint_plateau)==-1){
for(int_joueur=1;int_joueur<=2;int_joueur++){
jouer(ttint_plateau, int_joueur, int_joueur);
affichage(ttint_plateau);
aGagne(ttint_plateau);
printf("%d\n", aGagne(ttint_plateau));
if(aGagne(ttint_plateau)==0 || aGagne(ttint_plateau)==1 || aGagne(ttint_plateau)==2){
printf("%d",aGagne(ttint_plateau));
exit(-1);
}
}
}
}
# Dur à comprendre
Posté par gUI (Mastodon) . Évalué à 6.
C'est pas facile de t'aider, parce qu'il faut entrer dans ton code, et tel qu'il est écrit c'est compliqué (et j'avoue que même si j'aime les os à ronger, je vais pas faire trop d'effort).
1/ Il n'y a aucun commentaire
La fonction
ttint()
par exemple, elle fait quoi ? Pourquoi ? Quelles valeurs elle retourne ? Rien n'est évident, mêmeverticale()
on sait pas ce qu'elle fait.2/ Les valeurs de retour sont incompréhensible
Ça retourne 2 ou 1 ou -1… pourquoi pas, mais à ce moment il te faut faire un
#define
style :et après un code comme
if (cherche_colonne() == RET_TROUVE_CONONNE)
c'est bcp plus facile à comprendreune fonction comme aGagne par exemple on s'attend à ce qu'elle retour
true
oufalse
, son prototype serait donc3/ Trop de else if imbriqués
Tu dois avoir manqué quelqchose sur tes algo de base, parce que envoyer une grande suite de
if
imbriqés avec seuelment un indice de tableau qui change… ça sent vraiment qu'il y a mieux à écrire :)En théorie, la théorie et la pratique c'est pareil. En pratique c'est pas vrai.
[^] # Re: Dur à comprendre
Posté par loiloi21 . Évalué à 1.
Oui désolé pour le manque de commentaire, en général je le fais quand j'ai terminé mais sur des programmes de cette taille c'est vrai que ce n'est pas une bonne idée de procéder comme ça..
[^] # Re: Dur à comprendre
Posté par Pol' uX (site web personnel) . Évalué à 7.
Honnêtement, à la place de mettre des commentaires, met du code qui se comprend sans ambiguïté et met des tests. :)
Adhérer à l'April, ça vous tente ?
[^] # Re: Dur à comprendre
Posté par loiloi21 . Évalué à 1.
Merci du conseil je l'appliquerai sur mes prochains codes !
[^] # Re: Dur à comprendre
Posté par David Demelier (site web personnel) . Évalué à 2.
Plutôt :
git is great because linus did it, mercurial is better because he didn't
# commentaires
Posté par vmagnin (site web personnel) . Évalué à 4.
Ce n'est pas forcément dans
aGagne()
que se trouve le problème. Est-ce que ça ne marche pas dans tous les cas où il y a 4 pions alignés ? (verticale, horizontale, diagonales droite et gauche)Dans ce bloc, il y a des choses étranges :
A quoi sert le premier appel
aGagne(ttint_plateau)
? L'entier retourné n'est pas récupéré dans une variable, qui permettrait en plus de ne pas appeler à nouveau cinq fois la fonction ! Même remarque dansaGagne()
.Dans
aGagne()
, lesreturn
devraient être après lesprintf
, sinon ils ne sont pas exécutés car on a déjà quitté la fonction.Le problème doit venir des tests d'égalité de quatre cases : en C, on ne peut tester l'égalité que de deux variables à la fois, on ne peut pas les enchaîner comme ça :
Donc il manque des
&&
.[^] # Re: commentaires
Posté par loiloi21 . Évalué à 2.
Merci beaucoup pour votre aide vous avez vu juste, je le saurais pour la prochaine fois ! :)
# vieux souvenirs de code
Posté par NeoX . Évalué à 6.
il me semble qu'un "return" dans un IF va quitter la section
du coup
va sortir de la section AVANT d'afficher 'le joueur XXX a gagné !'
et donner a la suite, la valeur du ttint_plateau
[^] # Re: vieux souvenirs de code
Posté par loiloi21 . Évalué à 1. Dernière modification le 05 décembre 2021 à 18:01.
Oui vous avez raison, merci !
[^] # Re: vieux souvenirs de code
Posté par fearan . Évalué à 5. Dernière modification le 06 décembre 2021 à 10:30.
autre remarque, si verticale(param) ne modifie pas ce dernier, ne l'appelle pas 4 fois de suite c'est très mauvais coté perf
utilise une variable locale
et comme dit plus haut, met des noms qui veulent dire quelque chose.
ah et d'un point de vue style
c'est non
est beaucoup plus lisible!!!
Il ne faut pas décorner les boeufs avant d'avoir semé le vent
[^] # Re: vieux souvenirs de code
Posté par fearan . Évalué à 6.
Bon et après le style, c'est les perfs.
C'est tout simplement catastrophique!
pour chaque tour de jeu tu teste l'intégralité des positions sur tout le plateau… J'ajouterai que si tu changes de dimensions tu va au devant de gros ennuis, au vu des fonctionnement des verticale/horizontales; tu ferais mieux de faire une fonction
Il ne faut pas décorner les boeufs avant d'avoir semé le vent
[^] # Re: vieux souvenirs de code
Posté par Papey . Évalué à 1. Dernière modification le 06 décembre 2021 à 22:55.
C'est plus succinct !
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.