Aller au contenu

[Java]un autre problème :D


eYo

Messages recommandés

Bonsoir,

Bon je débute en java, et j'ai un petit programme (tout bête) à faire.

Ce programme me demande d'enter une nombre entier, qui correspond à un nombre d' ''*'' qui serviront comme base d'un triangle (fait avec des *) rectangle avec l'angle droit à gauche.

* * * * * * * * * * 
* * * * * * * * * 
* * * * * * * * 
* * * * * * * 
* * * * * * 
* * * * * 
* * * * 
* * * 
* * 
* 

Pour n = 10

Vous allez vous demander ce que j'ai comme problème alors :p

Et bien en fait, j'ai réussie à écrire le programme, mais je dois avouer que je ne le comprends pas dans sa totalité, je ne comprends pas ce qu'il se passe exactement au niveau des for.

Donc si quelqu'un peut m'éclairer :keskidit:

Merci d'avance :dd:

Lien vers le commentaire
Partager sur d’autres sites

Ce serait plus simple en perl :keskidit:

 perl -e 'for ($i=10; $i>0; $i--) {print "*"x$i."\n"}'

Sérieusement, c'est simple :

En pseudo code (en supposant que tu rentres 10) :

 // On imprime 10 lignes
pour i allant de 1 à 10
 // On imprime 10-l'itération en cours étoiles
 // 10 la première fois, 9 la seconde etc
 pour j allant de i à 10
impression de l'étoile
 fin pour
 retour à la ligne
fin pour

Lien vers le commentaire
Partager sur d’autres sites

Je "réouvre" avec un autre problème, j'ai peut être du mal ce soir, mais je ne comprends pas pourquoi mon code tourne en boucle (enfin il à l'air, parce que javaw.exe sature ma ram...)

Alors voilà mon code, je me doute qu'il y a plus simple.

Le but étant de faire un mini jeu (comme dans fort boyard) où l'on retire 1,2 ou 3 allumettes, et celui qui retire la dernière perd la partie :mdr2:

D'après l'output (ça compile quand même ;)), j'ai l'impression que c'est la première boucle (do ...while, au début j'avais fait un simple while,mais bon c'est pareil dans ce cas la, et l'ouput est le même..).

import java.util.Scanner;


public class jeu {

/**
 * @param args
 */
public static void main(String[] args) {
	// TODO Auto-generated method stub

	Scanner sc = new Scanner(System.in);

	int player = 0,computer,nombre;
	String name_player;
	nombre = 17;

	System.out.println("Quelle est votre nom ?");
		name_player = sc.nextLine();

	do {
		while (player < 1 || player > 3) {

			System.out.println("Combien d'allumette(s) voulez vous retirez (entre 1 et 3)?");
			player = sc.nextInt();

			if (player < 1 || player > 3){
				System.out.println("Veuillez entrez un nombre en 1 et 3 s'il vous plait");
			}

			nombre = nombre-player;

			if (nombre > 0){
				System.out.println("Il reste "+nombre+" allumette(s)");	
			}

			if (nombre <= 0){
				System.out.println(name_player+" a perdu contre l'ordinateur");
			}

			computer =(int)(Math.random()*3)+1;
			nombre = nombre - computer;
			System.out.println("L'ordinateur enlève "+computer+" allumette(s)");

			if (nombre >0) {
				System.out.println("Il reste donc "+nombre+" allumette(s)");
			}

			if (nombre <= 0) {
				System.out.println("L'ordinateur a perdu contre"+name_player);
			}

		}
	} while (nombre > 0);
}

}

Une idée?

(j'avais aussi pensé faire un booléen pour éviter les if et mettre des switch, mais il y a pas tant de cas que ça...)

Merci d'avance ;)

Lien vers le commentaire
Partager sur d’autres sites

Ok.

Essaye de donner des noms + clairs à tes variables, par exemple nombreAllumettesTotal au lieu de nombre et nombreAllumettesSaisi au lieu de computer et player. Ca aide à la compréhension :craint:

Sinon, il y a différents points de problèmes dans ton algorithme.

Pourquoi dans ta boucle sur la saisie tu effectue aussi l'action de l'ordinateur ?

Ca veut dire que si le joueur saisit toujours 0, l'ordinateur va enlever toutes les allumettes.

Par contre, si tu saisis un nombre qui est bien entre 1 et 3, tu ne satisfais plus la condition de ton deuxième while. Et comme nombre est toujours > 0 et qu'il n'est jamais modifié sans rentrer dans le deuxième while, ça boucle indéfiniment.

C'est une mauvaise idée de faire comme ça. Essaie aussi d'utiliser des méthodes.

Pour faire un truc du genre :

Game game = new Game();
boolean tourJoueur = true;
while (nombreAllumettesTotal > 0) {

if (tourJoueur) {
nombreAllumettesSaisi = game.getNombreJoueur();

  } else {

nombreAllumettesSaisi = game.getNombreOrdinateur();
  }

  game.updateNombreAllumettesTotal( nombreAllumettesSaisi );
  tourJoueur = !tourJoueur; 
}

Je te laisse faire les méthodes :D

Lien vers le commentaire
Partager sur d’autres sites

L'algorithme pour ce jeu est simple. À deux joueurs, tu compte le nombre d'allumettes restant avant que tu ne joues.

S'il te reste un nombre qui n'est pas un multiple de 4, tu as gagné. Il te suffit d'enlever le reste de la division euclidienne du nombre par 4 à chaque fois. Ce qui en pratique se traduira par un certain nombre si tu es le premier à jouer, puis 4-x à chaque coup, avec x le nombre d'allumettes enlevé par ton adversaire.

S'il reste un multiple de 4 et que ton adversaire n'est pas bête, tu as forcément perdu.

Lien vers le commentaire
Partager sur d’autres sites

Merci :transpi: je vois à peu près

Par contre fabien, on a pas vu encore les "fonctions" (je penses que c'est ça que tu me donnes), on s'est arréter aux boucles pour le moment, mais je penses que si dans ce que tu me donnes je remplaces les fonctions par les instructions à faire ça marchera (enfin je penses...).

Je vais voir si j'arrive à faire ça...

Lien vers le commentaire
Partager sur d’autres sites

Mais essaie de penser en 1er d'un point de vue très global pour ensuite décrire chaque élément de l'aglorithme.

Là par exemple, dans ce que j'ai, on ne se concentre pas sur comment on récupère la saisie de l'utilisateur, ni comment l'ordinateur génère le nombre.

Je vois ça d'un point de vue très basique :

tant qu'il y a des allumettes

si c'est au tour du joueur : on récupère le nombre saisi

sinon on génère un nombre pour l'ordinateur

on décrémente le nombre d'allumettes

inversion du flag de tour de jeu

fin tant que

Ensuite, comment récupère-t-on le nombre saisi par le joueur ? Comment gérer les mauvaises saisies ?

Comment gérer le nombre de l'ordinateur ?

Comment gérer le message de fin de jeu ?

Tout ça est à voir après avoir déterminé l'algorithme global du jeu.

Tu t'occupes de créer la serrure d'une voiture après avoir créé son moteur :transpi:

Lien vers le commentaire
Partager sur d’autres sites

TSss...mais avant de se pencher sur le moteur, il convient de se pencher sur le chassis...ce qui permet bien souvent d'éviter de tuer une mouche avec un coup de canon...comprendre, dans le futur, il faut d'abord se pencher sur l'architecture de ton appli...m'enfin si tu n'as pas vu les classes et les fonctions ca va être tendu...idem si tu ne connais pas encore les divers patterns de conception ou toute une floppée d'algos ;)

Bonne chance pour quand tu va aborder les tableaux, la récursivité, les piles, les files, les arbres, les graphes...j'espère que tu as un bon prof :transpi:

Lien vers le commentaire
Partager sur d’autres sites

Merci :transpi:

Ce n'est pas un problème de "logique" je penses (car je vois exactement ce qu'il faut que je fasses, et globalement dans quel ordre le faire) mais j'ai encore un peu de mal (avec 2 semaines de prog dans les pattes...) avec la "réaction" des outils si on peut dire :p

Mais je vais me pencher ce soir dessus, je vous tiens au courant, mais j'y ai réfléchis cette aprem (ba oui en méca, la CAO ça va vite :p) et je penses avoir trouver comment m'y prendre :merci:

Encore merci d'être aussi patient :ouioui:

Lien vers le commentaire
Partager sur d’autres sites

Bon, et bien me revoilà, j'ai essayé de faire quelque chose, le contenu n'est pas le même, mais le résultat reste le même...

import java.util.Scanner;


public class jeu {

/**
 * @param args
 */
public static void main(String[] args) {
	// TODO Auto-generated method stub

	Scanner sc = new Scanner (System.in);

	int nombreAllumettesTotal = 17, nombreAllumettesJoueur = 0, nombreAllumettesOrdinateur = 0;
	boolean tourJoueur;
	int tourJoueurInt = (int)(Math.random()*2)+1;

	// On fait le tirage au sort pour savoir qui commence

	if (tourJoueurInt == 1){
		tourJoueur = true;
		System.out.println("Vous commencez la partie");
	}
	else {
		tourJoueur = false;
		System.out.println("C'est l'ordinateur qui commence la partie");
	}
	// On commence la boucle du jeu
		while (nombreAllumettesTotal > 0){
			if (tourJoueur = true){
				while (nombreAllumettesJoueur < 1 || nombreAllumettesJoueur >3){ // On vérifie la saisie
					System.out.println("Combien d'allumettes enlever ? (entre 1 et 3");
					nombreAllumettesJoueur = sc.nextInt();

					if (nombreAllumettesJoueur < 1 || nombreAllumettesJoueur >3){
						System.out.println("Entrez un nombre correct s'il vous plait");
					}

						if (nombreAllumettesTotal <= 0) {
							System.out.println("Vous avez perdu");
						}
						else {
											nombreAllumettesTotal = nombreAllumettesTotal - nombreAllumettesJoueur;
					System.out.println("Il reste "+nombreAllumettesTotal+" allumettes");
						}
			}
		}
			else {
				nombreAllumettesOrdinateur = (int)(Math.random()*3)+1;
				nombreAllumettesTotal = nombreAllumettesTotal - nombreAllumettesOrdinateur;

				if (nombreAllumettesTotal <= 0){
					System.out.println("Vous avez gagné");
				}
				else {
					System.out.println("Il reste "+nombreAllumettesTotal+" allumettes");
				}
			}
			tourJoueur = !tourJoueur; 
	}

}
}

(j'ai rajouté un test pour définir qui commence la partie, qui ne marche pas d'ailleurs...).

:transpi:

Lien vers le commentaire
Partager sur d’autres sites

tu fais une affectation dans le if qui te permet de tester si c'est au joueur de jouer...comme tu affecte true à tour joueur dans ton if tu as quelque chose qui revient à :

if (true) {

//toujours utilisé

}

else {

//jamais utilisé

}

il faut que tu fasse

if (tourJoueur == true) {

//tour joueur

}

else {

//tour ordinateur

}

HS : tu utilise quel environnement de développement ? Il existe des plugins pour Eclipse et NetBeans pour trouver ce genre d'erreur (qui est plus fréquente qu'on ne le pense)

Sinon, évite de déclarer toutes tes variables d'un même type sur la même ligne. Tu ne gagne strictement rien à tout mettre sur la même ligne, si ce n'est à perdre en lisibilité :transpi:

Il faudra aussi que tu prévoie de gérer les cas ou l'ordinateur ou le joueur veulent enlever plus d'allumettes qu'il n'y a sur le plateau :transpi:

Lien vers le commentaire
Partager sur d’autres sites

Et même avec un booléen, tu peux faire :

if (tourJoueur)

Sinon, Charles.w l'a effectivement dit, si tu fais if( uneVaraible = uneValeur), en Java (comme dans pas mal de langages), ça te renverra toujours vrai et ça mettra uneValeur dans uneVariable.

Sinon, autre point d'algorithmique, moins il y a de duplication mieux c'est.

Dans ton code, tu as 2 fois le code de vérification pour savoir si le joueur a gagné ou non, le code de mise à jour du nombre d'allumettes, le code d'affichage du nombre d'allumettes.

Il y a sans doute moyen de faire que ces tests et messages ne soient faits qu'une fois ;)

Lien vers le commentaire
Partager sur d’autres sites

Pour l'utilisation directe du booleen, je suis d'accord, mais là il débute, et ca permet de faciliter la lecture du code...

Tu peux aussi rajouter des commentaire indiquant les pré-conditions et les posts-conditions...

Si tu utilise NetBeans, tu peux installer le plugin pour FindBugs / checkstyle / pmd : http://javahowto.blogspot.com/2008/03/inst...netbeans-6.html cela te permettra de détecter pas mal de bugs (enfin surtout les résultats de PMD et de FindBugs)

Après, pour ce qui est de la factorisation du code, pareil...j'avais posté (brièvement...si tu le veux je peux le remettre) une solution complète allant dans ce sens ;)

Lien vers le commentaire
Partager sur d’autres sites

J'utilise Eclipse, oui je me suis rendu compte de mon erreur avec le égale juste en allant me coucher...

Maintenant les problèmes sont :

- quand l'utilisateur rentre un mauvais chiffre, il est quand même retiré...

- une fois un chiffre correct rentré, le tour entre les joueurs n'alterne pas, c'est l'ordinateur qui joue jusqu'à la fin... (mon tourJoueur = !tourJoueur serrait-il mal placé ?)

Merci de votre aide ;)

(au passage eclipse est bien ? ou il vaut mieux commencer sur NetBeans ? et oui Charles je veux bien voir la correction, sauf si j'en suis vraiment trop loin :down:)

Lien vers le commentaire
Partager sur d’autres sites

- quand l'utilisateur rentre un mauvais chiffre, il est quand même retiré...

Je pense qu'il serait + pédagogique de te demander pourquoi le programme devrait se comporter autrement.

- une fois un chiffre correct rentré, le tour entre les joueurs n'alterne pas, c'est l'ordinateur qui joue jusqu'à la fin... (mon tourJoueur = !tourJoueur serrait-il mal placé ?)

Non, cette instruction est très bien placée mais quelle est la première instruction quand on rentre dans le tour du joueur ? Quelle valeur a la variable en question ?

au passage eclipse est bien ? ou il vaut mieux commencer sur NetBeans ?

Eclipse est bien et très utilisé en entreprise. Mais il n'est pas forcément évident à prendre en main.

Lien vers le commentaire
Partager sur d’autres sites

Concernant Eclipse et NetBeans ou tout autre environnement de dev...si tu utilises Eclipse à l'école, alors utilise aussi Eclipse chez toi...sinon, utilise NetBeans, plus simple à apréhender...et où tout fonctionne "out of the box" excepté le fait qu'il manque les plugins dont je parlais ci-avant (mais ils sont, et je pense que c'est un tord trop peu utilisés...faire du code propre doit demander trop d'efforts à certains)...

Ma solution...sans définir de fonctions...et en utilisant des do while en lieu et place des while...là tu veux que ton programme tourne au moins un coup...dans tous les cas...donc mettre un do while permet de s'assurer que tu rentre bien dans le code de la boucle...après si la condition d'arrêt (le while) n'est pas valide, c'est un autre problème ;)

import java.util.Scanner;

public class NewClass {

public static void main(String[] args) {

	Scanner sc = new Scanner(System.in);

	int nombreAllumettesTotal = 17;
	int nombreAllumettesJoueur = 0;
	int nombreAllumettesOrdinateur = 0;
	int tourJoueurInt = 0;

	boolean tourJoueur;

	//Détermine qui commencera le premier :-)
	tourJoueurInt = (int) (Math.random() * 2) + 1;

	// On fait le tirage au sort pour savoir qui commence
	if (tourJoueurInt == 1) {
		tourJoueur = true;
		System.out.println("Vous commence la partie");
	} else {
		tourJoueur = false;
		System.out.println("C'est l'ordinateur qui commence la partie");
	}

	// On commence la boucle du jeu
	do {
		System.out.println("Il reste " + nombreAllumettesTotal + " allumettes.");

		//Si c'est au joueur
		if (tourJoueur == true) {
			System.out.println("A vous de jouer");

			//Sert à déterminer si le nombre d'allumettes saisi est correct
			//vis à vis du nombre d'allumettes restant sur le plateau
			do {

				//On lui demande de saisir un nombre d'allumettes compris entre 1 et 3
				do {
					System.out.println("Combien d'allumettes enlever ? (entre 1 et 3)");
					nombreAllumettesJoueur = sc.nextInt();
				} while ((nombreAllumettesJoueur < 1) || (nombreAllumettesJoueur > 3));
				//A ce point, on sait que l'utilisateur a saisi un nombre entre 1 et 3
				//mais il peut être supérieur au nombre d'allumettes restant sur le plateau

			} while (nombreAllumettesJoueur > nombreAllumettesTotal);
			//A ce point, on est certain que le nombre d'allumettes saisi est
			//compris entre 1 et 3, et que ce nombre est inférieur au nombre
			//d'allumettes restant sur le plateau

			//On modifie le nomnbre d'alumettes
			nombreAllumettesTotal = nombreAllumettesTotal - nombreAllumettesJoueur;

			System.out.println("Vous avez enlevé : " + nombreAllumettesJoueur);
		} else {
			System.out.println("L'ordinateur joue.");

			//Sert à déterminer si le nombre d'allumettes saisi est correct
			//vis à vis du nombre d'allumettes restant sur le plateau
			do {

				//L'ordinateur choisi le nombre d'allumettes qu'il enlève du plateau
				nombreAllumettesOrdinateur = (int) (Math.random() * 3) + 1;

			} while (nombreAllumettesOrdinateur > nombreAllumettesTotal);
			//A ce point, on est certain que le nombre d'allumettes calculé est
			//compris entre 1 et 3, et que ce nombre est inférieur au nombre
			//d'allumettes restant sur le plateau

			//On modifie le nombre d'allumettes
			nombreAllumettesTotal = nombreAllumettesTotal - nombreAllumettesOrdinateur;

			System.out.println("L'ordinateur a enlevé " + nombreAllumettesOrdinateur + " allumettes.");
		}
		//A ce point, soit l'ordinateur vient de jouer, soit le joueur vient de jouer

		//On indique le prochain joueur
		tourJoueur = !tourJoueur;
	} while (nombreAllumettesTotal > 0);
	//A ce point, on est certain qu'on a un gagnant...

	//si true...c'est le joueur qui a joué en dernier
	if (tourJoueur == false) {
		System.out.println("L'ordinateur à gagné");
	} //sinon, c'est l'ordinateur qui a joué en dernier
	else {
		System.out.println("Vous avez gagné");
	}
}
}

HS : FindBugs me sort une warning sur le Math.random() alors que le code est correct...c'est juste qu'il est conseillé d'utiliser les méthodes de la classe java.util.Random...mais tu n'en est pas encore là :down:

Edit : correction pour prendre en compte les bonnes règles lors de la fin de partie

Lien vers le commentaire
Partager sur d’autres sites

- quand l'utilisateur rentre un mauvais chiffre, il est quand même retiré...

Je pense qu'il serait + pédagogique de te demander pourquoi le programme devrait se comporter autrement.

- une fois un chiffre correct rentré, le tour entre les joueurs n'alterne pas, c'est l'ordinateur qui joue jusqu'à la fin... (mon tourJoueur = !tourJoueur serrait-il mal placé ?)

Non, cette instruction est très bien placée mais quelle est la première instruction quand on rentre dans le tour du joueur ? Quelle valeur a la variable en question ?

au passage eclipse est bien ? ou il vaut mieux commencer sur NetBeans ?

Eclipse est bien et très utilisé en entreprise. Mais il n'est pas forcément évident à prendre en main.

- Je dirai que même si le nombre est incorrect, il rentre dans le else du second if (nombreAllumettesTotal <= 0) donc il procède à la modification de la variable nombreAllumettesTotal..., c'est ça ?

- La je vois pas trop, c'est par rapport à la variable nombreAllumettesJoueur ?

Sinon à la fac on utilise SciTe, qui n'est vraiment pas top (en gros sa on édite le code, ça compile, ça exécute mais rien d'autre..).

Je vais essayé NetBeans

Sinon Charles, ton programme marche bien, y a juste un truc, c'est juste que c'est celui qui enlève la dernière qui perd :cartonrouge: (juste à inverser le if et c'est bon)

Lien vers le commentaire
Partager sur d’autres sites

Pas grave :D

Globalement ce qu'il me manquait c'était :

1 : faire des do...while

2 : faire le test pour voir si le nombreAllumettesJoueur/Ordinateur n'est pas plus grand que nombreAllumettesTotal

3 : le test pour voir qui a gagné (enfin pas fait de cette manière)

Et ben, y a du boulot :cartonrouge:

Lien vers le commentaire
Partager sur d’autres sites

Archivé

Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.

×
×
  • Créer...