IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

avec Java Discussion :

[Puissance 4] Gagner en diagonal au puissance 4 - JAVA


Sujet :

avec Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Candidat au Club
    Homme Profil pro
    Analyse système
    Inscrit en
    Décembre 2015
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Macédoine

    Informations professionnelles :
    Activité : Analyse système

    Informations forums :
    Inscription : Décembre 2015
    Messages : 3
    Par défaut [Puissance 4] Gagner en diagonal au puissance 4 - JAVA
    Bonjour !

    Je crée ce post en espérant trouver de l'aide ! En effet je suis actuellement entrain de programmer un petit puissance 4 pour un projet. Il n'y a rien de bien compliqué, il faut juste faire celui-ci dans le terminale (sans interface graphique donc), permettant de faire du 1v1 ou du 1vIA avec des rotations possibles. La plupart du boulot est fait, il ne me manque plus que les conditions de victoire.
    J'ai déjà fait la victoire en vertical et horizontal, il n'y avait rien de bien compliqué, mais maintenant je suis bloqué pour la victoire en diagonale ! En effet je sais comment ça fonctionne dans la tête, mais chaque tentative que je fais en java ne fonctionne pas et se résout par un échec .
    Un peu d'aide sera la bienvenue pour mon problème héhé

    Je vais pas vous montrez tout le code, voici juste le sous-programme pour les conditions de victoire : (sans celle de diagonale qui me rend fou !!)
    int i : ligne dans laquelle a été posé le dernier pion joué.
    int j : colonne dans laquelle a été posé le dernier pion joué.
    int pion : pion joué en fonction du joueur 1 ou 2.
    char [][] tab : tableau à 2D qui représente la grille.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    	public static void victoire (char [][] tab, int i, int j, int pion){
    	int compte = 0;
    	int di = i;
    	int dj = j;
    							/* TEST VERTICAL */
    		i = 6;
    		j = dj;
    		while ((compte<4) && (i>=0)){
    			if (tab[i][dj]==pion){
    				compte ++;
    				i --;
    			}else{
    				compte = 0;
    				i --;
    			}
    		}
    							/* TEST HORIZONTAL */
    		i = di;
    		j = 6;
    		while ((compte<4) && (j>=0)){
    			if (tab[di][j]==pion){
    				compte ++;
    				j --;
    			}else{
    				compte = 0;
    				j --;
    			}
    		}
    							/* VICTOIRE */
    		if (joueur == 1){
    			if (compte == 4){
    				joueur = 3;
    			}else{
    				joueur = 2;
    				jeton = jeton - 1;
    			}
    		}else{
    			if (compte == 4){
    				joueur = 4;
    			}else{
    				joueur = 1;
    				jeton = jeton - 1;
    			}
    		}
    	}

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Salut,

    C'est dommage de ne pas montrer ce que tu fais pour traiter la diagonale, si c'est cette partie sur laquelle tu sèches. En revanche, si je peux comprendre que tu traites la grille verticalement de manière à la remplir par les ordonnées les plus basse (malgré que ça necessite d'inverser l'affichage) puisque que tu décrémentes j pour déterminer s'il y a alignement de 4 pions, je vois mal comment ça pourrait fonctionner horizontalement en décrémétant i (donc en allant dans une seule direction).

    Prenons une grille de puissance 4 :

    1 2 3 4 5 6 7
    1 1
    2 2
    3 3
    4 o o 4
    5 x o x o 5
    6 x x o x x x 6
    7 x o o x o o o 7
    1 2 3 4 5 6 7

    x peut joueur en 4,1 :
    1 2 3 4 5 6 7
    1 1
    2 2
    3 3
    4 x o o 4
    5 x o x o 5
    6 x x o x x x 6
    7 x o o x o o o 7
    1 2 3 4 5 6 7
    Donc la pour compter les x, on va effectivement faire varier l'index de "ligne" de départ vers le bord (j'aurais fait ++, mais -- fonctionne avec un repère inversé)

    x peut joueur en 6,5 :
    1 2 3 4 5 6 7
    1 1
    2 2
    3 3
    4 o o 4
    5 x o x o 5
    6 x x o x x x x 6
    7 x o o x o o o 7
    1 2 3 4 5 6 7
    On voit qu'il y a des x de part et d'autres, donc se déplacer dans une seule direction n'est pas suffisant.
    2 solutions :
    1. soit se déplacer dans une direction (peu importe laquelle), jusqu'à ce qu'on arrive au bord, ou qu'on arrive à un changement de couleur, puis compter en partant dans l'autre sens.
    2. soit compter en se déplaçant dans les 2 sens, et faire la somme des 2 compteurs (attention à ne pas compter 2 fois le pion qu'on vient de jouer)


    pour les lignes en diagonales, x peut joueur en 4,4 :
    1 2 3 4 5 6 7
    1 1
    2 2
    3 3
    4 o o x 4
    5 x o x o 5
    6 x x o x x x 6
    7 x o o x o o o 7
    1 2 3 4 5 6 7
    Pour compter ici, il suffit de faire varier les lignes et les colonnes en même temps. Les lignes varient toujours dans un direction, mais il faudra faire varier les colonnes dans les 2 (on peut avoir 2 types de diagonales), avec la même technique que pour une ligne horizontale, puis qu'on peut avoir un cas comme ça :
    1 2 3 4 5 6 7
    1 1
    2 2
    3 3
    4 x 4
    5 o x 5
    6 o o x 6
    7 o x o x 7
    1 2 3 4 5 6 7
    voire insérer au milieu d'une diagonale, comme pour le cas ligne horizontale
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  3. #3
    Candidat au Club
    Homme Profil pro
    Analyse système
    Inscrit en
    Décembre 2015
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Macédoine

    Informations professionnelles :
    Activité : Analyse système

    Informations forums :
    Inscription : Décembre 2015
    Messages : 3
    Par défaut
    Hello,

    Déjà merci de ta réponse ! N'étant pas sûr de moi, je suis allez check mon programme par rapport à ce que tu m'as dit et je t'assure que tout fonctionne !
    Laisse-moi m'expliquer : que ce soit pour le vertical ou l'horizontal, je n'utilise qu'une variable utilisée par la case dans laquelle le joueur à jouer. En effet au lieu de faire en fonction de sa ligne et de sa colonne, c'est-à-dire de compter les pions à partir de son emplacement actuel, je reprends depuis le début. Pour la vertical, j'utilise la ligne dans laquelle le joueur à joué, mais pas la colonne, celle-ci sera égale à 0 soit la 1ère colonne du tableau. Du coup, pour chaque colonne, on va vérifier si le pion est identique à la variable pion actuelle, et ça dans la même ligne. Prenons un exemple : un jeton rouge a été joué à la colonne 6 et on fait un test vertical. Mon sous-programme va prendre la ligne dans laquelle le jeton est présent, et va tester pour chaque colonne de cette ligne. Dès qu'un jeton est identique et à la suite, il ajoute 1 à la variable compte et ainsi jusqu'à ce que compte = 4. Mais si un pion est différent, le compte revient à 0, mais on continue de regarder si il n'y a pas un enchaînement de 4 dans cette ligne quand même. Tu vois ce que je veux dire ? J'espère avoir bien expliquer !

    Sinon oui, j'aurai bien voulu mettre mes essais de diagonal sur le post, sauf que j'efface tout et je recommence à chaque fois :/ Mais j'ai gardé le dernier, si tu veux check le voici (celui avant le post) !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    							/* TEST DIAGONAL */
    		i = di;
    		j = dj;
    		if (j<=3){
    			while((compte<4) && (i>=3)){
    				if (tab[i][j] == pion){
    					compte ++;
    					System.out.println(compte);
    					i --;
    					j ++;
    				}else{
    					compte = 0;
    					i --;
    					j ++;
    				}
    			}
    		}
    C'était exactement sur le même principe sur les 2 autres, mais ça ne fonctionne pas...
    Bref, je te remercie de ta réponse, je vais aller essayer 2/3 autres trucs que j'ai en tête, tu m'as un peu éclaircis !

  4. #4
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Je n'avais pas regardé ton code, et comme tu parlais de passer la position du dernier pion joué, je pensais que tu partais de là pour compter. Effectivement, tu pars du bord (6). Déjà cette technique ne fonctionne pas pour des diagonales, parce que la case du bord n'est pas alignée verticalement, ou horizontalement, et encore moins, les deux à la fois (partir de 6, 6). On peut calculer la position de départ de la diagonale qui part du bord et qui passe par la dernière position jouée. Il y aura de toute manière 2 diagonales.
    Dans ton code, comme tu pars dans une direction, ça ne fonctionnera que si par hasard la dernière pièce jouée est en bout de série de 4 pions. Il faut donc compter en même temps dans la direction opposée (et s'arrêter dès qu'on a plus égalité du pion (sortir de la boucle). Mais il faudra toujours traiter les 2 diagonales possibles (ou alors faire un test d'élimination, en calculant la distance au bord).
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  5. #5
    Candidat au Club
    Homme Profil pro
    Analyse système
    Inscrit en
    Décembre 2015
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Macédoine

    Informations professionnelles :
    Activité : Analyse système

    Informations forums :
    Inscription : Décembre 2015
    Messages : 3
    Par défaut
    Hello again !

    Donc voilà, je pense avoir trouvé le début d'une solution ! J'ai juste un soucis que j'arrive pas à régler :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    		i = di;
    		j = dj;
    		while ((compte<4) && ( ((i>0)&&(i<6)) && ((j>=0)&&(j<6)) )){
    			while (tab[(i+1)][(j+1)] == pion){
    				i --;
    				j ++;
    			}
    			while ((tab[i][j] == pion) &&  ((j>=0)&&(i<=6))){
    				if (i==6 || j==0){
    					compte ++;
    				}else{
    					compte ++;
    					i ++;
    					j --;
    				}
    			}
    			if (tab[i][j] != pion){
    				i = 7;
    				j = 7;
    				compte = 0;
    			}
    		}
    Je ne comprends pas trop comment je pourrais résoudre ce problème... En gros dès que la case dans laquelle le pion se trouve est aux bords de la grille, le programme tourne sans cesse... Le problème vient du if de la 3ème boucle while mais je ne sais pas du coup comment le reglé, un peu d'aide svp ?

  6. #6
    Modérateur
    Avatar de kolodz
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2008
    Messages
    2 209
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 209
    Billets dans le blog
    52
    Par défaut
    As-tu utilisé le mode "debug" pour comprendre ce qui se passe lors de chaque itération de la boucle ?
    Ou un simple "syso" (System.out.println) ?

    Pour ma part dans le cas i==6 j>0 et tab[i][j]==pion cette boucle est une boucle infini :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    while ((tab[i][j] == pion) &&  ((j>=0)&&(i<=6))){
        if (i==6 || j==0){
            compte ++;
        }else{
            compte ++;
            i ++;
            j --;
        }
    }
    Pour ma part, je trouve ce code de vérification particulièrement complexe. Il devrait y avoir des sous-fonctions.
    Il est aussi important de de limiter le nombre de variable "magique" qui se balade dans ton code. Comme le "6" dans la boucle. Car, si on te demande de faire un puissance 4 avec 8/9/10 ligne/colonnes... il faudra changer partout dans le code.

    Voici une version qui me semble plus compréhensible pour un humain :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    package org.k.developpez.forum;
     
    import java.util.Arrays;
    import java.util.Random;
     
    public class Verificateur {
    	enum Direction {
    		NORD, SUD, EST, OUEST, NORD_EST, NORD_OUEST, SUD_EST, SUD_OUEST
    	};
     
    	enum Type {
    		X, O
    	};
     
    	Type tab[][] = new Type[7][7];
     
    	public boolean verification(int posNS, int posEO) {
    		int total = 0;
    		int LIMIT = 4;
    		// Protection 
    		if (posNS < 0 || posNS >= tab.length) {
    			return false;
    		}
    		if (posEO < 0 || posEO >= tab[posNS].length) {
    			return false;
    		}
    		Type typeVoulu = tab[posNS][posEO];
    		// Vérification verticale :
    		total = nombrePion(Direction.NORD, typeVoulu, posNS, posEO) + 1 + nombrePion(Direction.SUD, typeVoulu, posNS, posEO);
    		System.out.println("nombre de pion vers le NORD "+nombrePion(Direction.NORD, typeVoulu, posNS, posEO));
    		System.out.println("nombre de pion vers le SUD "+nombrePion(Direction.SUD, typeVoulu, posNS, posEO));
    		System.out.println("Total en N-S est " +total);
    		if (total >= LIMIT) {
    			return true;
    		}
    		// Vérification horizontale :
    		total = nombrePion(Direction.OUEST, typeVoulu, posNS, posEO) + 1 + nombrePion(Direction.EST, typeVoulu, posNS, posEO);
    		System.out.println("nombre de pion vers le OUEST "+nombrePion(Direction.OUEST, typeVoulu, posNS, posEO));
    		System.out.println("nombre de pion vers le EST "+nombrePion(Direction.EST, typeVoulu, posNS, posEO));
    		System.out.println("Total en O-E est " +total);
    		if (total >= LIMIT) {
    			return true;
    		}
    		// Vérification diagonale 1 :
    		total = nombrePion(Direction.NORD_OUEST, typeVoulu, posNS, posEO) + 1 + nombrePion(Direction.SUD_EST, typeVoulu, posNS, posEO);
    		System.out.println("nombre de pion vers le NORD_OUEST "+nombrePion(Direction.NORD_OUEST, typeVoulu, posNS, posEO));
    		System.out.println("nombre de pion vers le SUD_EST "+nombrePion(Direction.SUD_EST, typeVoulu, posNS, posEO));
    		System.out.println("Total en NO-SE est " +total);
    		if (total >= LIMIT) {
    			return true;
    		}
    		// Vérification diagonale 2 :
    		total = nombrePion(Direction.SUD_OUEST, typeVoulu, posNS, posEO) + 1 + nombrePion(Direction.NORD_EST, typeVoulu, posNS, posEO);
    		System.out.println("nombre de pion vers le SUD_OUEST "+nombrePion(Direction.SUD_OUEST, typeVoulu, posNS, posEO));
    		System.out.println("nombre de pion vers le NORD_EST "+nombrePion(Direction.NORD_EST, typeVoulu, posNS, posEO));
    		System.out.println("Total en SO-NE est " +total);
    		if (total >= LIMIT) {
    			return true;
    		}
    		return false;
    	}
     
    	public int nombrePion(Direction direction, Type typeVoulu, int posNSOrigin, int posEOOrigin) {
    		// Reprise des coordonées.
    		int posNS = deplacementNS(direction, posNSOrigin);
    		int posEO = deplacementEO(direction, posEOOrigin);
    		// Protection 
    		if (posNS < 0 || posNS >= tab.length) {
    			return 0;
    		}
    		if (posEO < 0 || posEO >= tab[posNS].length) {
    			return 0;
    		}
    		if (tab[posNS][posEO] == typeVoulu) {
    			return 1 + nombrePion(direction, typeVoulu, posNS, posEO);
    		}
    		return 0;
    	}
     
    	private int deplacementNS(Direction direction, int posNSOrigin) {
    		int posNS = posNSOrigin;
    		// Déplacement en NS
    		switch (direction) {
    		case NORD:
    		case NORD_EST:
    		case NORD_OUEST:
    			posNS--;
    			break;
    		case SUD:
    		case SUD_EST:
    		case SUD_OUEST:
    			posNS++;
    			break;
    		default:
    			break;
    		}
    		return posNS;
    	}
     
    	private int deplacementEO(Direction direction, int postEOOrigin) {
    		int posEO = postEOOrigin;
    		// Déplacement en EO
    		switch (direction) {
    		case OUEST:
    		case SUD_OUEST:
    		case NORD_OUEST:
    			posEO--;
    			break;
    		case EST:
    		case SUD_EST:
    		case NORD_EST:
    			posEO--;
    			break;
    		default:
    			break;
    		}
    		return posEO;
    	}
     
    	/**
             * Code pas beau fait à l'arrache pour avoir une entrée pour la fonction verification
             * @param args
             */
    	public static void main(String[] args) {
    		Random rn = new Random();
    		Verificateur verif = new Verificateur();
    		for (int i = 0; i < verif.tab.length; i++) {
    			for (int j = 0; j < verif.tab[i].length; j++) {
    				switch (rn.nextInt(3)) {
    				case 0:
    					// on laisse à null
    					break;
    				case 1:
    					verif.tab[i][j] = Type.X;
    					break;
    				case 2:
    					verif.tab[i][j] = Type.O;
    					break;
    				default:
    					break;
    				}
    			}
    		}
    		System.out.println(Arrays.deepToString(verif.tab));
    		System.out.println("A-t-on gagné en 0,0 => "+verif.verification(0, 0));
    		System.out.println("A-t-on gagné en 3,2 => "+verif.verification(3, 2));
    		System.out.println("A-t-on gagné en 9,9 => "+verif.verification(9, 9));
    	}
     
    }
    Je te conseil de le regarde et de le lancer pour voir ce que ça donne.

    Cordialement,
    Patrick Kolodziejczyk.
    Si une réponse vous a été utile pensez à
    Si vous avez eu la réponse à votre question, marquez votre discussion
    Pensez aux FAQs et aux tutoriels et cours.

Discussions similaires

  1. Méthode gagner puissance 4
    Par chasto dans le forum Général Java
    Réponses: 15
    Dernier message: 07/12/2011, 13h44
  2. [LG]Puissance et Indice
    Par luno2545 dans le forum Langage
    Réponses: 2
    Dernier message: 08/05/2004, 10h01
  3. [LG]fonction puissance en pascal
    Par le 27 dans le forum Langage
    Réponses: 8
    Dernier message: 13/12/2003, 23h21
  4. x² et puissance de x par récurrence
    Par olivieram dans le forum Algorithmes et structures de données
    Réponses: 7
    Dernier message: 15/12/2002, 23h59
  5. Besoin d'aide pour l'I.A. d'un puissance 4
    Par Anonymous dans le forum C
    Réponses: 2
    Dernier message: 25/04/2002, 17h05

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo