ma boucle marche pas !!!

_remi

Membre confirmé
11 Octobre 2004
21
0
62
Bonjour,

Cocoa débutant, j'essaie de développer un petit jeu qui doit générer 7 entiers différent. Faut bien débuter...
La première boucle ajoute 7 nombres aléatoires dans un tableau et la deuxieme vérifie que la valeur de chaque index soit différente, mais elle ne marche pas celle-là...
Pourtant en C# cette boucle fonctionne...




NSMutableArray *remTableau;
int i;
int j;
NSNumber *remNombre;
remTableau = [[NSMutableArray alloc] init];

for (i = 0; i < 7; i++)
{
remNombre = [[NSNumber alloc] initWithInt:( random() % 49) + 1];
[remTableau addObject: remNombre];
for (j = 0; j < 7; j++)
{
if ((i != j) && ([remTableau objectAtIndex: i] == [remTableau objectAtIndex: j]))
{
i--;
break;
}
}
}


[textField_1 setObjectValue: [remTableau objectAtIndex: 0]];
[textField_2 setObjectValue: [remTableau objectAtIndex: 1]];
[textField_3 setObjectValue: [remTableau objectAtIndex: 2]];
[textField_4 setObjectValue: [remTableau objectAtIndex: 3]];
[textField_5 setObjectValue: [remTableau objectAtIndex: 4]];
[textField_6 setObjectValue: [remTableau objectAtIndex: 5]];
[textField_7 setObjectValue: [remTableau objectAtIndex: 6]];
 
A première vue ce qui m'étonne c'est que ça tourne sous C#. Tu dis, si j'ai bien compris, vouloir tester ton tableau pour qu'il ne comporte pas deux éléments identiques (et non pas deux index ).

Dans ta deuxième boucle, tu parcours le tableau avec l'index j. Mais les éléments d'index j supérieur à i n'ont pas encore été créés !

De deux choses l'une : ou ton code que t'as tapé en C# est fondamentalement différent, ou bien C# accepte de tester sur des éléments encore non créés.

Te propose le code suivant :


for(i=0;i<7;i++)
{
remNombre =[....

[remTableau addObject ...

[remNombre release] // si tu oublies de relâcher tu as une fuite de mémoire

int j =0; BOOL OK = YES ;

while (j <i && ok){ // Voila l'erreur : j ne doit pas dépasser i. On sort de la boucle si deux
// éléments sont égaux

if(OK = !([rem...] == [...]) ) { // pas la peine de tester i!=j puisqu'il est inférieur à j

[remTableau removeObjectAtIndex:i] ; i -- // Il faut retirer l'élément indésirable !

} ; j++ ;

};

};
 
int rand;
rand=random() % 20+1;


[TextField setIntValue: rand];

NSString *myString = [[NSString alloc] initWithFormat:mad:"my number is %i.", rand];

so

@implementation Foo

- (IBAction)generate:(id)sender
{
int generated;
generated = (random() % 100) + 1;
[textField setIntValue:generated];
}

- (IBAction)seed:(id)sender
{
srandom(time(NULL));
[textField setStringValue:mad:"Generator seeded"];
}

- (unsigned short) Myrand
{

implemente une routine de random
return 0;
}

au final plutot que de faire des boucles
fait deux tableaux et compare les
 
arnolix a dit:
A première vue ce qui m'étonne c'est que ça tourne sous C#. Tu dis, si j'ai bien compris, vouloir tester ton tableau pour qu'il ne comporte pas deux éléments identiques (et non pas deux index ).

Dans ta deuxième boucle, tu parcours le tableau avec l'index j. Mais les éléments d'index j supérieur à i n'ont pas encore été créés !

De deux choses l'une : ou ton code que t'as tapé en C# est fondamentalement différent, ou bien C# accepte de tester sur des éléments encore non créés.

};

Merci Je vais tester ton code.
le code en C# ( il fonctionne très bien) :

private void button2_Click(object sender, System.EventArgs e)
{
int[] tab = new int[7];

for(int i=0; i < 7 ; i++ )
{
Random Alea = new Random();

tab = Alea.Next() %49 + 1;

for(int j=0; j < 7 ; j++ )
{
if ((i != j) && (tab == tab[j]))
{
i--;
break;
}
}

}

num1.Text = tab[0].ToString();
num2.Text = tab[1].ToString();
num3.Text = tab[2].ToString();
num4.Text = tab[3].ToString();
num5.Text = tab[4].ToString();
num6.Text = tab[5].ToString();
num7.Text = tab[6].ToString();

}
 
vite dit : es-tu sûr qu'il ne s'agit pas de i<j plutôt que j<7 dans ta deuxième boucle ?
Essaie avec i<j pour voir

ps : ai commis petite erreur sur le booléen OK.

enlève OK = ! dans le test if, puis entre les accolades mets OK = NO après j++
 
arnolix a dit:
vite dit : es-tu sûr qu'il ne s'agit pas de i<j plutôt que j<7 dans ta deuxième boucle ?
Essaie avec i<j pour voir

oui c'est i<j
puisque le tableau final fait 6 entrées

et surtout ca [remTableau addObject: remNombre]; non !!!!!!!!!!!!


mais je te conseille de faire une routine qui rempli un tableau
et juste de demander au tableau si il possède déjà cette clef

sinon

monmaintableau->add
et si mon tableau est plein de ses clefs uniques ont continu
 
tatouille a dit:
oui c'est i<j
puisque le tableau final fait 6 entrées

et surtout ca [remTableau addObject: remNombre]; non !!!!!!!!!!!!


mais je te conseille de faire une routine qui rempli un tableau
et juste de demander au tableau si il possède déjà cette clef

sinon

monmaintableau->add
et si mon tableau est plein de ses clefs uniques ont continu

Hé! Tacouille soit plus clair, je débute sur Cocoa et Objective C. Et j'ai vraiment des difficultés...
 
oui je me suis relu peu importe le language


routine {

boucle {

genere->rands
rempli->tmptableau

si clefs uniques dans tmptableau égal à 6
copie->clefs uniques->dansfinaltableau

sort
}

}


Cordialement tacramouille :D
 
Tu as peut être tes raisons (pédagogiques), mais pourquoi utiliser les classes NSMutableArray et NSNumber ?
Utiliser les tableaux comme tu le fais en C# est tout de même bien plus clair.


Ajoute à la fin de ta méthode
[remTableau dealloc];

Il n'est pas nécessaire de faire des dealloc sur les NSNumber puisqu'ils appartiennent au NSMutableArray.
 
arnolix a dit:
vite dit : es-tu sûr qu'il ne s'agit pas de i<j plutôt que j<7 dans ta deuxième boucle ?
Essaie avec i<j pour voir

ps : ai commis petite erreur sur le booléen OK.

enlève OK = ! dans le test if, puis entre les accolades mets OK = NO après j++

Je suis de retour, je viens de tester ton code mais il permet d'avoir 2 valeurs identiques.

le voilà :


- (IBAction)generate:(id)sender
{
NSMutableArray *remTableau;
int i = 0;
int j = 0;
NSNumber *remNombre;

NSAutoreleasePool *pool = [[ NSAutoreleasePool alloc] init];

remTableau = [[NSMutableArray alloc] init];

for (i; i < 7; i++)
{
remNombre = [[NSNumber alloc] initWithInt:( random() % 49) + 1];
[remTableau addObject: remNombre];
[remNombre release];
BOOL ok = YES;
while (j < i && ok)
{
if ([remTableau objectAtIndex: i] == [remTableau objectAtIndex: j])
{
[remTableau removeObjectAtIndex: i];
}
j++;
ok = NO;
}
}
 
>Céroce

Justement en utilisant des classes comme NSMutableARRay et compagnie on mets des garde-fous qu'il ne semble pas y avoir avec des tab[] et consorts. tu fais tab[10000000] sans problème, mais le résultat est plus que douteux à l'execution. Par contre avec un NSMutableArray...
Autre truc : tu veux envoyer un message whatTimeIsItPlease à tous tes objets d'un NSArray. Tape :
[montableau makeObjectsPerformSelector:mad:selector(whatTimeIsItPlease)]
(A condition que tes objets y répondent) . Je trouve ca supercool, mais c'est peut-être une question de gout ;)
 
Le pointeur j doit être remis à 0, ainsi que ok, à chaque nouveau élément nouvel élément introduit par la boucle for (i... Le ok est avant j++, pas après

Voila ce que je taperai. Mais ne l'ai pas vérifié encore

- (IBAction)generateid)sender
{
NSMutableArray *remTableau;



NSNumber *remNombre;

NSAutoreleasePool *pool = [[ NSAutoreleasePool alloc] init];

remTableau = [[NSMutableArray alloc] init];
int i ; int j;BOOL ok ;
for (i=0; i < 7; i++)
{
remNombre = [[NSNumber alloc] initWithInt random() % 49) + 1];
[remTableau addObject: remNombre];
[remNombre release];
j = 0; ok = YES;
while (j < i && ok)
{
if ([remTableau objectAtIndex: i] == [remTableau objectAtIndex: j])
{
[remTableau removeObjectAtIndex: i];ok = NO;
}
j++;

}
}
 
arnolix a dit:
Le pointeur j doit être remis à 0, ainsi que ok, à chaque nouveau élément nouvel élément introduit par la boucle for (i... Le ok est avant j++, pas après

Voila ce que je taperai. Mais ne l'ai pas vérifié encore

}


Non marche toujours pas...
 
Ton tableau remTableau doit être alloué en dehors de ta méthode generate:. Tout ce qui y est déclaré est perdu au retour. C'est dans main{} que tu place : remTableau = [NSMutableArray new] et NSAutoRelease...
 
Alors tu ajoutes une méthode accesseur -(nsmutablearray*)montableau à la classe principale qui le contient. Sinon c'est impossible !
 
Merci pour tous tes conseils, mais je ne comprend pas: le tableau fonctionne bien grâce à la boucle et s'affiche avec des valeurs aléatoires dans les NSTextField. C'est la deuxième condition avec un for ou un while qui ne marche pas, il peut avoir deux valeurs égales (voir la capture). J'ai donc procédé par étape et je me suis aperçu que même ce code marche pas:
int varTest;
for (i = 0; i < 7; i++)
{
remNombre = [[NSNumber alloc] initWith'Int':( random() % 49) + 1];
[remTableau addObject: remNombre];
[remNombre release];
if (i < 7){ // j'ai testé plusieurs conditions avec des if dans des for pour incrémenter un entier rien ne s'affiche!!
varTest += 5;
}
[monTexField setIntValue: varTest]; // ce NStextField ne fonctionne que si je déactive les 7 autres et encore pas toujours enfin des trucs complètement aléatoires...
Peut-être que mon .nib est corrompu ou XCode 1,5 ne fonction pas sur un G3 BB scsi ou est il buggé?

enfin laisse tomber et merci...