[MV-Sabios] Problema programacion

iRiBaR

Hola MV. Estoy haciendo un juego en c++ para programacion, el mastermind, y tengo que generar una clave aleatoria, de 4 letras (esto ya lo tengo).

pero dentro de la clave no se puede repetir ninguna letra, y he aqui el problema. Lo he hecho con una funcion auxiliar que compruebe al generar cada clave si algun elemento se repite, y con un do-while en la funcion CreaClaveAleatoria que hasta que todos los elementos (los 4) sean distintos, no salga.

Pero hay algun error, en la funcion que comprueba si la clave es correcta, seguramente algun (!variablebooleana) que se me haya pasado. Lo que pasa que llevo 1hora comprobandolo todo y no caigo...

Asi que aqui entra vuestro papel. Me podeis echar una mano???

NOTA: NO PIDO que me hagais un programa, pido que busqueis el fallo de uno que he hecho yo. El programa esta escrito ordenadamente y no deberia haber problemas para entenderlo, pero si teneis algun problema, decidmelo y os explico.

EL CODIGO FUENTE (compila): http://www.megaupload.com/es/?d=YGFZSAO8

Gracias MV!!!!

Edit: Foro equivocado:(

B

http://www.media-vida.net/verforo.php?fid=17

DeFiNiTioN

En Software están MV programadores.

-Crack-

apaga tu pantalla y escribe la función en papel. No falla.

Gandalf530

Pastea el codigo aqui anda, no pienso bajarme eso de megaupload, ademas no tengo el compilador aqui y por lo que veo la extension es cpp

iRiBaR

#include
#include <stdlib.h>
#include <time.h>
using namespace std;

const int MAXCLAVE=10;
typedef char TVector[MAXCLAVE];

bool CompruebaClave (TVector clave1)
{
int i=0, j=0;
bool hayelemrepe=false;
while (hayelemrepe && i<4) {
while (hayelemrepe && j<4) {
if (clave1==clave1[j]) {
hayelemrepe=true;
}
j++;
}
i++;
}
return hayelemrepe;
}

void CreaClave (TVector& clave1)
{
TVector auxiliar;
char letra='a';
int i, j, k=0, l=0, aux;
bool hayelemrepe=false;


 for (i=0 ; i<MAXCLAVE ; i++) {
     auxiliar[i]=letra;
     letra++;
     }
     
 do {
    for (i=0 ; i<4 ; i++) {
        for (j=0 ; j<100 ; j++) {
            aux=rand()%10;
            }
            clave1[i]=auxiliar[aux];
            }
            } while (CompruebaClave (clave1));
              
 for (i=0 ; i<4 ; i++) {
     cout << clave1[i] << " ";
     }
 cout << endl;

}

int main ()
{
srand(time(0));
TVector clave;
CreaClave (clave);
system("Pause");
return 0;
}

EDIT: Si quieres te lo paso en un .txt porque aqui no respeta los tabuladores ni nada de eso y es ilegible.

_

Pero hay algun error, en la funcion que comprueba si la clave es correcta, seguramente algun (!variablebooleana) que se me haya pasado. Lo que pasa que llevo 1hora comprobandolo todo y no caigo...

Pones:

bool CompruebaClave (TVector clave1)
{
int i=0, j=0;
bool nohayelemrepe=true;
while (hayelemrepe && i<4) {
while (hayelemrepe && j<4) {
if (clave1==clave1[j]) {
nohayelemrepe=false;
}
j++;
}
i++;
}

Así que al comparar uno de los elementos con sí mismo, dará siempre que hay un elemento repetido.

Sería:

bool CompruebaClave (TVector clave1)
{
int i=0, j;
bool hayelemrepe=false;
while (!hayelemrepe && i<3) {
j=i+1;
while (!hayelemrepe && j<4) {
if (clave1==clave1[j]) {
hayelemrepe=true;
}
j++;
}
i++;
}

LOc0

Al margen de que esto vaya en DEV...

No me he bajado el código (ponlo en www.pastebin.es ), pero te recomiendo que te crees un array booleano de 256 elementos y lo inicialices con un FOR a FALSE.

Cada vez que generes una letra de la clave mira si array_booleano[(int)letra] está a FALSE. Si es así, lo pones a TRUE y pasas a generar la siguiente letra de la clave y si no, vuelves a generar otra letra y haces lo mismo.

Salu2 ;)

JuAn4k4

si son 4 hay mas comparaciones:

1,2
1,3
1,4

2,3
2,4

3,4

para este tipo de comparaciones el algoritmo es :

desde i=1 hasta max-1
desde j=i+1 hasta max
correcto = correcto && clave != clave[j]
fin
fin

Tu caso:

bool correcto = true;

for ( int i = 1; i<=3; i++)
{
for( int j= i; j<=4; j++)
{
correcto = correcto && ( clave != clave[j] ) ;
}
}

PD: En tu funcion ni siquiera entra al bucle tio, tu cuanto lo has mirado ?

hayelementorepe= falso

while FALSO && ... {
tucodigo
}

OhYeAh

ponlo en FAKE haber si va xD

_

#9, es desde j=i+1 hasta 4. Sino siempre saldrá igual en la primera comparación.

Y la primera posición sería el 0, en lugar de el 1 (o al menos eso parece según lo que pone en su código).

edit: Además, cierto que no entra en su código por el bool. Tiene que invertirlo xD

iRiBaR

k es lo k tengo k invertir?

JuAn4k4

#11 pues eso xD

#12 aqui tienes corregido tu cacho de codigo creo que seria algo asi :

bool CompruebaClave (TVector clave1)
{
int i=0, j=1;
bool hayelemrepe=false;
while ( !(hayelemrepe) && i<3) {
while ( !(hayelemrepe) && j<4) {
if (clave1==clave1[j]) {
hayelemrepe=true;
}
j++;
}
i++; j=i+1;
}
return hayelemrepe;
}

Mientras las claves sean de long 4 vas bien, si se empieza a agrandar igual tienes problemas ya que es de orden cuadratico ( en tu caso no pasa ), la solucion seria hacerlo lineal ,de forma que conforme vas creando la clave, al sacar un nuevo random mirar que no este ya en el trozo de clave que hayas creado.

_

#13, si. Ese ya está bien xD

iRiBaR

#13 tienes razon. me habia equivocado en los finales de "i" y "j" xD. gracias :):)

iRiBaR

y ahora por qué hostias me da este problema al compilar??

CreaClave (TVector clave[nivel+3], nivel);

dice "expected primary expression before nivel".

lo unico que he hecho ha sido ajustar la longitud de la cadena al nivel del juego. la longitud es el nivel+3.

nivel 1: 4 letras
nivel 2: 5 letras.
...
nivel 5: 8 letras.

JuAn4k4

Porque no le puedes pasar: TVector clave[nivel+3]

Tu vector en memoria no se yo si puedes cambiarlo en c++ ( a no ser q lo hagas en memoria dinamica ), lo que si puedes hacer es reservar espacio en memoria de 100 por ejemplo ( como nivel maximo ) al definirlo:
TVector clave[100] y en la funcion pasarle:

crearClave(clave, nivel+3);

Lo que no se puede es pasar como parametro una definicion de una variable.

MTX_Anubis

Hay cosas que no entiendo:

for (i=0 ; i<MAXCLAVE ; i++) {
auxiliar=letra;
letra++;
}

(Aquí estás metiendole a auxiliar a,b,c,d,e,f,g,h,i,j. Esto no es que no lo entienda, es que es innecesario.)

do {
for (i=0 ; i<4 ; i++) {
for (j=0 ; j<100 ; j++) {
aux=rand()%10;
}
clave1=auxiliar[aux];


Esto es lo que no entiendo, haces dos for, uno dentro de otro y el de dentro se va a repetir 100 veces porque sí creando números aleatorios. Es decir, vas a crear 400 números para quedarte con 4 :/. Es que no entiendo muy bien el por qué has hecho eso xD

En vez de hacer eso, el crear una array con las 10 primeras letras del alfabeto, le añades directamente 97 al número aleatorio (97 es la 'a' en ASCII) y ya tienes una función que genera letras xD

clave=char(rand()%10 + 97);

de hecho sería mejor así:

clave=char(rand()%MAXCLAVE + 97);

(creo que no haría falta usar la función char pero tampoco estoy muy seguro ahora mismo xD)

Pero bueno, si lo quieres hacer con la auxiliar, lo que puedes hacer es que cada vez que saques una letra, la pones en NULL y así puedes comprobar directamente si ya ha sido cogida o no. Te ahorras el tener que hacer otra función que compruebe eso, ya que tienes una array auxiliar, aprovechala al máximo xD

También tienes algunas variables declaradas que no usas.

Y por cierto, el debugger es la mejor herramienta de ayuda para cualquier programador xD

Usuarios habituales