Java - Ejercicio validación Pin o como enfrentarte a un tanque con un tirachinas.

 
Vista:
Imágen de perfil de Javi

Ejercicio validación Pin o como enfrentarte a un tanque con un tirachinas.

Publicado por Javi (18 intervenciones) el 04/11/2022 23:32:21
Hola compañeros. daros las gracias de antemano. Soy alumno de 1º de DAM a distancia. Nos dan unos apuntes desfasados y sin clases. Un poquito de de do-while, else else if, switch case. Y con eso ta mandan la tarea. Un par de ejercicios "decentes" por ser la segunda tarea.....pero. PUM buscarse la vida con esto:

Cada vez que un cliente de un banco desea acceder a sus cuentas a través de una plataforma de banca electrónica, se le solicitan dos posiciones aleatorias de su PIN de seis dígitos.

En pantalla aparecerá una representación del PIN con cada dígito enmascarado mediante un carácter asterisco ('*') excepto los las dos posiciones que se solicitan, que estarán enmascaradas por guiones bajos o subrayados ('_'). Por ejemplo, para el caso de las posiciones 2 y 5, se mostraría algo como:

Para acceder al sistema debe introducir el contenido de las posiciones 2 y 5 de su pin:
*_**_*
Tras esto se solicitará primero el primer dígito:

Introduzca contenido de la posición 2 del PIN:
y a continuación el segundo dígito:

Introduzca contenido de la posición 5 del PIN:
Una vez introducidos los dos dígitos se comprobarán si coinciden realmente con los del PIN. Si no es así, volverán a solicitarse esos mismos dígitos. Se pedirán hasta un máximo de tres veces. Si se introducen correctamente, se entrará en el sistema. Si no se introducen correctamente en ninguno de los tres intentos, entonces se bloqueará el sistema y no se permitirá entrar. Hay que tener en cuenta que, una vez generadas las dos posiciones aleatorias, no se vuelven a generar, sino que se preguntan siempre las mismas.

Escribe un programa en Java que simule la entrada en ese sistema llevando a cabo las siguientes acciones:

generamos un PIN aleatorio de seis dígitos, que se almacenará en un String y se mostrará por pantalla. Esto nos servirá para que el PIN no sea siempre el mismo y de ese modo podamos simular una situación más "real". Obviamente, en la realidad no aparecería el PIN por pantalla, pues entonces el resto del proceso carecería de sentido. Hacemos esto para que podamos probar cada vez con un PIN distinto sin tener que escribirlo nosotros por teclado o incluirlo como constante en el programa. Esta parte se te proporciona ya resuelta en la plantilla de tu programa utilizando la herramienta Utilidades.generaPin();
generamos dos números aleatorios entre 1 y 6 que sean diferentes y que representan dos posiciones aleatorias del PIN. Para ello, puedes realizar lo siguiente:
generamos un primer número. Puedes utilizar la herramienta Utilidades.numAleatorio(1, 6), que te prorporcionará un número entero aleatorio entre 1 y 6;
generamos un segundo número. Hemos de tener en cuenta que deben ser dos números diferentes. Eso significa que tendrás que asegurarte de que el segundo número que obtengas, no coincida con el primero. Si coincidiera, tendrías que volver a generar ese segundo número hasta que no coincidiera. Esto puedes resolverlo fácilmente con un bucle do-while.
Una vez tengas dos números aleatorios diferentes, asegúrate de que el primero es menor que el segundo. Si no es así, simplemente puedes intercambiar el contenido de las variables donde los tengas almacenados;
creamos una cadena (String) con el PIN "enmascarado" teniendo en cuenta las reglas que se nos han indicado anteriormente (con asteriscos y subrayados). Debes hacerlo mediante un bucle for que vaya acumulando en el String caracteres del tipo asterisco ('*') o subrayado ('_'), según toque. Se trataría de un acumulador de tipo cadena, donde su valor inicial debería ser la cadena vacía y va "creciendo" mediante el operador de concatenación de cadenas;
mostramos por pantalla el PIN "enmascarado" indicando las dos posiciones que se solicitan;
solicitamos esas posiciones al usuario y se lleva a cabo la comprobación (tres intentos como máximo):
solicitamos la primera posición. Para obtener un único carácter (char) que luego puedas comparar con una posición de una cadena (charAt), puedes hacer la siguiente lectura de teclado: teclado.nextLine().charAt(0);
solicitamos la segunda posición;
comprobamos si lo introducido por el usuario es correcto (esos valores coinciden con los contenidos de las posiciones del PIN solicitadas).
Una vez finalizada la entrada de posiciones (bien porque se hayan introducido valores válidos bien porque se hayan consumidos los tres intentos), se procederá a:
Si la entrada fue válida (los dos componentes del PIN introducidos han sido correctos), se procederá a crear una nueva cadena (String) con el PIN "enmascarado" teniendo en cuenta que en esta ocasión tendrás que "desenmascarar" las dos posiciones que se han introducido. Debes hacerlo nuevamente mediante un bucle for que vaya acumulando en el String caracteres del tipo asterisco ('*') o numérico, según toque. Tras eso se indicará que el PIN es correcto y que se procede al entrar en el sistema;
Si la entrada no fue válida (se consumieron los tres intentos sin conseguirlo), entonces simplemente se mostrará por pantalla un mensaje del tipo "Ha introducido tres veces un PIN incorrecto. Sistema bloqueado".

Os agradecería la más mínima ayuda. Porque llevo una semana dándome cabezazos con el poco material que nos dan.


Éste es el proyecto base que debemos cumplir:

package tarea02;

import java.util.Scanner;
import libtarea2.Utilidades;


/**
* Ejercicio 5. Validación de PIN.
* @author Indicar nombre de alumno/a
*/
public class Ejercicio05 {

public static void main(String[] args) {
//----------------------------------------------
// Declaración de variables
//----------------------------------------------

// Variables de entrada


// Variables de salida


// Variables auxiliares
String pin;


// Clase Scanner para petición de datos de entrada
Scanner teclado = new Scanner(System.in);

//----------------------------------------------
// Entrada de datos + Procesamiento
//----------------------------------------------
System.out.println("VALIDACIÓN DE PIN");
System.out.println("-----------------");

// 1. Creamos el PIN de seis dígitos
pin = Utilidades.generaPin();
System.out.println ("Creando un número de identificación personal de seis dígitos: " + pin);

// 2. Generamos aleatoriamente dos posiciones aleatorias y diferentes entre la 1 y la 6
// 2.1. Generamos primer número

// 2.2. Generamos segundo número garantizando que va a ser diferente al primero

// 2.3. Si el primer número es superior al segundo, los intercambiamos


// 3. Creamos el String con el PIN "enmascarado"


// 4. Mostramos el PIN enmascarado por pantalla e indicamos las posiciones que se deben introducir


// 5. Solicitamos esas posiciones al usuario y se lleva a cabo la comprobación (tres intentos como máximo)

// 5.1. Solicitamos primera posición aleatoria del PIN

// 5.2. Solicitamos segunda posición aleatoria del PIN

// 5.3. Comprobación de lo introducido frente al PIN


//----------------------------------------------
// Salida de Resultados
//----------------------------------------------
System.out.println();
System.out.println("RESULTADO");
System.out.println("---------");
// 6. Mostramos un resultado

// 6.1. Si el PIN es válido: Creamos el String con el PIN "enmascarado" desenmascarando la dos posiciones solicitadas e indicando el éxito

// 6.2. Si el PIN no es válido: Se indica que no se ha logrado introducir un PIN correcto y que el sistema se bloqueará


}
}
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

Ejercicio validación Pin o como enfrentarte a un tanque con un tirachinas.

Publicado por Tom (1831 intervenciones) el 05/11/2022 08:55:17
En mi opnión, no solamente es trivial sino que además te van dando las ayudas necesarias en el propio enunciado ...
Dedícale atención. No puede ser que en una semana no hayas avanzado nada ...
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Kabuto
Val: 3.428
Oro
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

Ejercicio validación Pin o como enfrentarte a un tanque con un tirachinas.

Publicado por Kabuto (1381 intervenciones) el 05/11/2022 10:35:43
Te están indicando paso a paso el proceso a seguir.
Así que olvídate del conjunto total y céntrate en cada uno de los pasos.

El método que genera un pin dicen que ya te lo dan hecho.

Vale, pues ahora céntrate en esto:
1
2
3
4
5
6
// 2. Generamos aleatoriamente dos posiciones aleatorias y diferentes entre la 1 y la 6
// 2.1. Generamos primer número
 
// 2.2. Generamos segundo número garantizando que va a ser diferente al primero
 
// 2.3. Si el primer número es superior al segundo, los intercambiamos

Inténtalo y si no lo consigues, muestra tu código y dinos donde te atascas.

Un saludo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Javier

Ejercicio validación Pin o como enfrentarte a un tanque con un tirachinas.

Publicado por Javier (18 intervenciones) el 09/11/2022 01:11:55
Muchas gracias por tu atención Kabuto.
Te pongo lo que llevo y te hago una preguntilla.


package tarea02;

import java.util.Scanner;
import libtarea2.Utilidades;


/**
* Ejercicio 5. Validación de PIN.
* @author Indicar nombre de alumno/a
*/
public class Ejercicio05 {

public static void main(String[] args) {
//----------------------------------------------
// Declaración de variables
//----------------------------------------------

// Variables de entrada

int posicion1, posicion2, contador, pin1, pin2;

// Variables de salida



// Variables auxiliares
String pin, enmascarado;


// Clase Scanner para petición de datos de entrada
Scanner teclado = new Scanner(System.in);

//----------------------------------------------
// Entrada de datos + Procesamiento
//----------------------------------------------
System.out.println("VALIDACIÓN DE PIN");
System.out.println("-----------------");

// 1. Creamos el PIN de seis dígitos
pin = Utilidades.generaPin();
System.out.println ("Creando un número de identificación personal de seis dígitos: " + pin);
System.out.println ( "Acceso al sistema.");
// 2. Generamos aleatoriamente dos posiciones aleatorias y diferentes entre la 1 y la 6
// 2.1. Generamos primer número
do {
posicion1= Utilidades.numAleatorio(1, 6);
// 2.2. Generamos segundo número garantizando que va a ser diferente al primero

posicion2= Utilidades.numAleatorio(1, 6);}
while (posicion1 == posicion2);
// 2.3. Si el primer número es superior al segundo, los intercambiamos

int temp = posicion1;

if (posicion1 > posicion2){

posicion1=posicion2;
posicion2= temp;

}


// 3. Creamos el String con el PIN "enmascarado"

enmascarado="";

contador=1;

for (contador = 1; contador <=6; contador ++){

if (posicion1 == contador || posicion2 == contador){

enmascarado+="-";
}

else {

enmascarado += "*";
}
}

// 4. Mostramos el PIN enmascarado por pantalla e indicamos las posiciones que se deben introducir

System.out.println ("Para acceder al sistema debe introducir el contenido de las posiciones " + posicion1 + " y " + posicion2 + " de su PIN: ");
System.out.println (enmascarado);

// 5. Solicitamos esas posiciones al usuario y se lleva a cabo la comprobación (tres intentos como máximo)

// 5.1. Solicitamos primera posición aleatoria del PIN

System.out.print("Introduzca contenido de la posicion " + posicion1 + " del PIN: ");
pin1= teclado.nextInt();

// 5.2. Solicitamos segunda posición aleatoria del PIN

System.out.print("Introduzca contenido de la posicion " + posicion2 + " del PIN: ");
pin2= teclado.nextInt();

// 5.3. Comprobación de lo introducido frente al PIN



//----------------------------------------------
// Salida de Resultados
//----------------------------------------------
System.out.println();
System.out.println("RESULTADO");
System.out.println("---------");
// 6. Mostramos un resultado

// 6.1. Si el PIN es válido: Creamos el String con el PIN "enmascarado" desenmascarando la dos posiciones solicitadas e indicando el éxito



System.out.println ("PIN correcto: " );

// 6.2. Si el PIN no es válido: Se indica que no se ha logrado introducir un PIN correcto y que el sistema se bloqueará

System.out.println("Ha introducido tres veces un PIN incorrecto. Sistema bloqueado.");

}
}


El problema que tengo ahora es que no se como comparar el valor que se obtiene de forma aleatoria con la que introduce el usuario.
Se supone que nos dan esta pista pero estoy un poco perdido.
Esto es lo que nos aconsejan:
"solicitamos esas posiciones al usuario y se lleva a cabo la comprobación (tres intentos como máximo):
solicitamos la primera posición. Para obtener un único carácter (char) que luego puedas comparar con una posición de una cadena (charAt), puedes hacer la siguiente lectura de teclado: teclado.nextLine().charAt(0);
solicitamos la segunda posición;
comprobamos si lo introducido por el usuario es correcto (esos valores coinciden con los contenidos de las posiciones del PIN solicitadas)."

Gracias de antemano
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Kabuto
Val: 3.428
Oro
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

Ejercicio validación Pin o como enfrentarte a un tanque con un tirachinas.

Publicado por Kabuto (1381 intervenciones) el 09/11/2022 20:12:14
A ver, primeras cosas que veo...

Esta parte diría que hay un error de sintaxis, aunque el compilador lo está dando como bueno...
Pero yo lo veo raro.
Este bucle DO WHILE, su cierre de llave está DESPUÉS de la sentencia de WHILE, cuando tendría que estar junto antes.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
		// 2.1. Generamos primer número
		do {
			posicion1= azar.nextInt(7) + 1;
			// 2.2. Generamos segundo número garantizando que va a ser diferente al primero
 
			posicion2= azar.nextInt(7) + 1;
			while (posicion1 == posicion2);
			// 2.3. Si el primer número es superior al segundo, los intercambiamos
 
			int temp = posicion1;
 
			if (posicion1 > posicion2){
 
				posicion1=posicion2;
				posicion2= temp;
 
			}

Es raro, porque es como si la sentencia WHILE estuviera en mitad del bucle, cuando ha de estar al final.
Yo desde luego no tengo claro donde está terminando el bucle. Yo cambiaría el cierre de llave y lo pondría junto la sentencia WHILE.

La parte donde se intercambia el orden de los números generados, no es necesario que esté dentro de ese bucle.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
		// 2.1. Generamos primer número
		do {
			posicion1= azar.nextInt(7) + 1;
			// 2.2. Generamos segundo número garantizando que va a ser diferente al primero
 
			posicion2= azar.nextInt(7) + 1;
		} while (posicion1 == posicion2);
		// 2.3. Si el primer número es superior al segundo, los intercambiamos
 
		int temp = posicion1;
 
		if (posicion1 > posicion2){
 
			posicion1=posicion2;
			posicion2= temp;
		}

Luego aquí hay otro error:
1
2
3
			// 5.3. Comprobación de lo introducido frente al PIN
 
			System.out.println(pin.charAt(pin));
El mismo String pin no puede ser también argumento para el método charAt(), quien además lo que necesita recibir es un int.
Pero ya veremos luego qué debería hacerse en ese apartado 5.3

Deja que siga mirando el resto del código y comento en otro mensaje...
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Kabuto
Val: 3.428
Oro
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

Ejercicio validación Pin o como enfrentarte a un tanque con un tirachinas.

Publicado por Kabuto (1381 intervenciones) el 09/11/2022 20:54:49
OK.
La verdad es que está todo bastante bien, solo falta rematar la parte final donde te has quedado atascado.

Lo primero es cambiar las variables pin1 y pin2 y declararlas como char en lugar de int
1
2
3
4
		// Variables de entrada
 
		int posicion1, posicion2, contador;
		char pin1 = ' ', pin2 = ' ';

Esto es porque como vamos a comparar caracteres, pues mejor pedirle caracteres al usuario en lugar de valores int

Luego nos vamos al punto 5 del programa y ahí podemos declarar dos nuevas variables (puedes declararlas al principio del programa si lo prefieres)
Vamos a usar un int inicializado a valor 3, que serán los intentos que tiene el usuario para adivinar el pin.
También vamos a usar un boolean para controlar si el usuario ha conseguido acertar los dos números (TRUE) o no ha sido capaz (FALSE).

Y con estas dos variables, abrimos un nuevo bucle while que se repetirá mientras el contador de intentos no llegue a 0 y mientras el usuario NO acierte los dos números.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
		// 5. Solicitamos esas posiciones al usuario y se lleva a cabo la comprobación (tres intentos como máximo)
 
		int intentos = 3;
		boolean esCorrecto = false;
		while (intentos > 0 && !esCorrecto) {
			// 5.1. Solicitamos primera posición aleatoria del PIN
			System.out.print("Introduzca contenido de la posicion " + posicion1 + " del PIN: ");
			pin1= teclado.nextLine().charAt(0);
 
			// 5.2. Solicitamos segunda posición aleatoria del PIN
			System.out.print("Introduzca contenido de la posicion " + posicion2 + " del PIN: ");
			pin2= teclado.nextLine().charAt(0);
 
			// 5.3. Comprobación de lo introducido frente al PIN
			if (pin1 == pin.charAt(posicion1 - 1) && pin2 == pin.charAt(posicion2 - 1))
				esCorrecto = true;
			else {
				intentos--;
				System.out.println("\nNo es correcto");
				System.out.println("Intentos restantes: " + intentos);
			}
		}

Fíjate que para comparar los caracteres correctos, tenemos que restarles -1 a las posiciones generadas al azar
1
if (pin1 == pin.charAt(posicion1 - 1) && pin2 == pin.charAt(posicion2 - 1))

Esto es porque, aunque estamos tratando las posiciones con números del 1 al 6, en realidad Java internamente las enumera del 0 al 5.
Así que el primer carácter aunque en pantalla decimos que está en la posición 1, en realidad está en la 0. La 2 está en la 1, etc....

Bien, asegúrate de que entiendes ese código y pregunta lo que necesites.

Ya luego podemos pasar al punto 6, la muestra de resultados.
A este punto llegamos cuando termina el bucle WHILE, que puede ser porque se han agotado los intentos o porque ha conseguido acertar.
¿Cómo sabemos nosotros cuál de las dos posibilidades ha ocurrido?

Pues por ejemplo podemos preguntarselo al boolean que habíamos declarado. Si es TRUE, es que ha acertado y tenemos que construir un nuevo pin "enmascarado", pero esta vez mostrando los dos números acertados.
Y si no, si es FALSE, pues es que ha agotado los intentos sin acertar pin, así que se le indica que al usuario que el sistema queda bloqueado.
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
}
 
 
 
		//----------------------------------------------
		//           Salida de Resultados
		//----------------------------------------------
		System.out.println();
		System.out.println("RESULTADO");
		System.out.println("---------");
		// 6. Mostramos un resultado
 
		// 6.1. Si el PIN es válido: Creamos el String con el PIN "enmascarado" desenmascarando la dos posiciones solicitadas e indicando el éxito
		if (esCorrecto) {
			String pinCorrecto = "";
			for (contador = 1; contador <=6; contador ++){
 
				if (contador == posicion1)
					pinCorrecto += Character.toString(pin1);
				else if (contador == posicion2)
					pinCorrecto += Character.toString(pin2);
				else
					pinCorrecto += "*";
			}
 
			System.out.println ("PIN correcto: " + pinCorrecto);
 
		}
		else {
			// 6.2. Si el PIN no es válido: Se indica que no se ha logrado introducir un PIN correcto y que el sistema se bloqueará
			System.out.println("Ha introducido tres veces un PIN incorrecto. Sistema bloqueado.");
		}


Y con esto se termina el programa.
Espero que el código que he escrito te quede claro la lógica que se ha seguido.
Pregunta cualquier duda que tengas.

Un saludo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Javier

Ejercicio validación Pin o como enfrentarte a un tanque con un tirachinas.

Publicado por Javier (18 intervenciones) el 09/11/2022 23:29:11
Hola Kabuto.

Lo primero agradecerte enormemente el tiempo que has perdido conmigo.
La verdad es cuando ves el programa escrito por alguien que sabe y te lo explica, piensas que es hasta facil.

Solo tengo una ultima dudita.
He cambiado todo lo que me has dicho pero no funciona. Me dice que al intentar esto:
Lo primero es cambiar las variables pin1 y pin2 y declararlas como char en lugar de int
1
2
3
4
// Variables de entrada

int posicion1, posicion2, contador;
char pin1 = ' ', pin2 = ' ';

incompatible types: String cannot converted to char

Y he petado.

Pero lo dicho, eres un grande y gracias por tus rápidas respuestas.



no-funciona
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Kabuto
Val: 3.428
Oro
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

Ejercicio validación Pin o como enfrentarte a un tanque con un tirachinas.

Publicado por Kabuto (1381 intervenciones) el 10/11/2022 17:58:06
Ojito a lo que marco en negrita. Ahí es muy fácil equivocarse.
1
2
int posicion1, posicion2, contador;
char pin1 = ' ', pin2 = ' ';

Siempre es recomendable, y a veces incluso necesario, inicializar las variables con un valor cualquiera, el que sea.
Los int por costumbre suelen inicializarse con valor 0.
1
int posicion1 = 0;
A no ser que necesitemos inicializar con un valor concreto, como hicimos con la variable intentos:
1
int intentos = 3;

Y los char, con un espacio en blanco. Este espacio ha de estar entre dos comillas simples, nunca comillas dobles
Este es el problema que estás teniendo, en tu código, has usado comillas dobles.

MAL, al ser comillas dobles Java lo interpreta como un String.
1
char pin1 = " ";

BIEN, las comillas simples se interpretan como un char.
1
char pin1 = ' ';


Los String, como hemos dicho, se usan comillas dobles y suelen inicializarse con una cadena vacía, es decir, ni siquiera un espacio en blanco.
Un par de comillas dobles vacías son suficiente:
1
String cadena = "";

En los char no se admite el "vacío". Entre las comillas simples ha de haber algo, un espacio en blanco, una letra, un guion, un punto,... lo que sea.

Poco a poco irás aprendiendo estas cositas básicas y no será tan frustrante. Al principio siempre parece que todo lo hacemos mal je je je, pero es cuestión de ir conociendo las "normas" y los usos y costumbres.

Un saludo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Javi

Ejercicio validación Pin o como enfrentarte a un tanque con un tirachinas.

Publicado por Javi (18 intervenciones) el 10/11/2022 18:22:55
Que grande eres. Ya funciona perfecto
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar