Antes de empezar quizá te interese revisar los tutoriales anteriores:
Cómo compilar y ejecutar programas en Java
"Hola Mundo" en java, pero gráfico
Hoy vamos a hacer algo un poco más útil, y más complicado. El objetivo es entender un poco mejor lo que Java proporciona: programación orientada a objetos. Espero ser capaz de ayudaros a ver lo que esto significa, poco a poco.
Bien, nuestro programa no va a tener interfaz gráfica. Aun es demasiado temprano para meterse en eso, aunque más adelante sería un buen ejercicio hacerle interfaz a este programa.
Va a funcionar por consola de comandos.
En qué va a consistir? Será una especie de "juego", donde el usuario tendrá que adivinar un número del 1 al 10. Sin duda de lo más divertido y adictivo :icon_mrgreen: (qué esperabas, un metin2 en java? jejeje)
Así que el programa sacará un número aleatorio, y el usuario tendrá 3 intentos para adivinarlo. Sencillo, como todo ejemplo para principiantes. Algo así:
Vamos a ello!
hr
Nuestro programa constará de dos clases: Main.java y AdivinaAleatorio.java
En la clase Main, meteremos únicamente nuestro método main(). Todo programa debe tener este método, es por donde comienza la ejecución. Si no hay main, el programa da error, y no se ejecuta.
Bien, pues nuestro main se encargará de decirle "bienvenido" al usuario, y de arrancar el juego.
Pero toda la funcionalidad del juego estará en la clase AdivinaAleatorio.
Vamos al código:
AdivinaAleatorio.java
Esta clase nos permitirá jugar a esta especie de juego un tanto estúpido. Como toda clase en java, empezamos escribiendo:
public class AdivinaAleatorio {
}
Va a necesitar un par de atributos, que son el número máximo de intentos que permitiremos al usuario, y el número aleatorio que genera el programa. Con esas dos cosas el programa tendrá lo básico para funcionar. Lo añadimos a la clase, así:
public class AdivinaAleatorio {
public int intentos;
public int aleatorio;
}
Ya tenemos la clase y sus dos atributos. Ahora vamos a escribir el método constructor. Un constructor debe llamarse igual que la clase, en este caso debe llamarse AdivinaAleatorio, y va a hacer lo siguiente:
public AdivinaAleatorio() {
intentos = 3;
aleatorio = (int) (Math.random() * 10) + 1;
}
Inicializa el número de intentos y "sortea" el número aleatorio que debe adivinar el usuario.
El constructor nos permitirá crear objetos de la clase AdivinaAleatorio, es decir, nos permitirá hacer new AdivinaAleatorio(). Lo veremos después.
Ok, tenemos la clase, sus atributos, y su constructor de objetos "AdivinaAleatorio". Ahora nos hacen falta un par de métodos, para que el juego haga algo jeje. Empecemos con un método facilote:
public void reiniciar()
{
intentos = 3;
aleatorio = (int) (Math.random() * 10) + 1;
}
Este método vuelve a poner el atributo "intentos" a 3, y sortea un nuevo número aleatorio. Esto lo usaremos cada vez que el usuario acierte un número o agote sus intentos y empiece una nueva partida. Reiniciaremos los atributos para empezar un nuevo turno.
Vamos a necesitar otro pequeño método que pida un número al usuario, lo llamaremos "leerNúmero" y tendrá esta pinta (es un poco feo el pobre, así que no os asustéis):
public int leerNumero()
{
BufferedReader linea = new BufferedReader( new InputStreamReader( System.in ) );
int num = -1;
System.out.println( "Introduzca un numero: ");
try
{
num = Integer.parseInt( linea.readLine( ) ) ;
}
catch (NumberFormatException e) {
System.err.println( "Error al convertir a entero" );
} catch (IOException e) {
System.err.println( "Error al leer entrada de datos" );
}
return num;
}
Os dije que era feo, no se asuste nadie. En realidad esa mierda de código simplemente nos da el número que escribe el usuario. No hace más, sin embargo queda bastante feo porque leer un número no es tan sencillo como suena: ¿y si el usuario, muy cabroncete él, mete una letra? ¿y si ocurre algún error con la entrada de datos? Es delicado, por eso el código queda tan feo. Pero da igual, de momento sólo os importa que eso pide un número y lo devuelve, así que ahora cuando queramos un número del usuario, escribiremos tan solo: numero = leerNumero(); Y quedará guardado en la variable "numero" el valor introducido por el usuario. Así no volveremos a ver ese horrible pedazo de código.
Ya casi está, tenemos la clase, los atributos, el constructor, un método que resetea el juego, y otro que lee un número del usuario. Nos falta juntarlo todo en un método principal.
Ese método principal simplemente pedirá un número al usuario hasta que acierte o se agoten los intentos. Vamos a llamarlo jugarPartida y quedará así:
public void jugarPartida()
{
int usuario;
System.out.println( "Se ha generado un numero del 1 al 10, adivinelo =)" );
do
{
usuario = this.leerNumero(); //pedimos un número al usuario
if ( usuario == aleatorio )
{
System.out.println( "Enhorabuena, ha acertado! El numero es el: " + aleatorio );
}
else
{
intentos = intentos - 1 ;
System.out.println( "Lo siento, no es correcto, le quedan " + intentos + " intentos." );
}
} while (intentos>0 && usuario != aleatorio);
if (intentos==0)
System.out.println("Game Over! El numero era: " + aleatorio );
}
Vamos línea a línea:
1- public void jugarPartida()
Esto declara un método público (otras clases podrán usarlo), que no nos devuelve nada (void) a diferencia del leer número que nos devolvía int, y que se llama jugarPartida.
2- int usuario;
Declara una variable llamada usuario, de tipo int (integer, o entero en español).
3- System.out.println( "Se ha generado un numero del 1 al 10, adivinelo =)" );
Muestra por pantalla esa frase "Se ha generado...".
Ahora viene lo bueno, tenemos un do while. Es un bucle, que se repite mientras al usuario le queden intentos (intentos>0) y no haya acertado el número todavía (usuario != aleatorio). != significa distinto de.
Dentro de ese bucle haremos una y otra vez lo mismo:
leer un número, y comprobar si es el correcto o no.
Si es el correcto, felicitamos al usuario.
Si no es correcto, restamos uno al número de intentos restantes, y le decimos al usuario que no es correcto.
Así hasta que acaben los intentos o el usuario acierte.
Fin de la clase AdivinaAleatorio. Os dejo el código al completo. Las 3 primeras líneas son librerías necesarias para algunas órdenes que he usado, no tienen más importancia.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class AdivinaAleatorio {
/* Atributos */
public int intentos; //aquí almacenaremos el número máx. de intentos que permitiremos al usuario
public int aleatorio; //aquí guardaremos el número generado por el programa, que debe adivinar el usuario
/* Constructor */
public AdivinaAleatorio() {
/* Inicializamos atributos */
intentos = 3;
aleatorio = (int) (Math.random() * 10);
}
/* Llamaremos a este método cuando queramos resetear
* los valores del programa, por ejemplo cada vez que el usuario
* adivine el número y quiera jugar de nuevo
* */
public void reiniciar()
{
intentos = 3;
aleatorio = (int) (Math.random() * 10);
}
/* Este método se encarga de comparar el número que introduce el usuario
* con el número generado aleatoriamente durante el máximo de intentos permitidos
* */
public void jugarPartida()
{
int usuario;
System.out.println( "Se ha generado un numero del 1 al 10, adivinelo =)" );
do
{
usuario = this.leerNumero(); //pedimos un número al usuario
if ( usuario == aleatorio )
{
System.out.println( "Enhorabuena, ha acertado! El numero es el: " + aleatorio );
}
else
{
intentos = intentos - 1 ;
System.out.println( "Lo siento, no es correcto, le quedan " + intentos + " intentos." );
}
} while (intentos>0 && usuario != aleatorio);
if (intentos==0)
System.out.println("Game Over! El numero era: " + aleatorio );
}
public int leerNumero()
{
BufferedReader linea = new BufferedReader( new InputStreamReader( System.in ) );
int num = -1;
System.out.println( "Introduzca un numero: ");
try
{
num = Integer.parseInt( linea.readLine( ) ) ;
}
catch (NumberFormatException e) {
System.err.println( "Error al convertir a entero" );
} catch (IOException e) {
System.err.println( "Error al leer entrada de datos" );
}
return num;
}
}
Main.java
Vamos con el remate final, hacer un main que cree un objeto de la clase AdivinaAleatorio y lo use. Como siempre que hacemos una clase, el código básico:
public class Main {
}
Bien, atributos vamos a ponerle solamente uno. Esta vez no va a ser un "int", ni nada de eso. Va a ser una variable de tipo AdivinarAleatorio. Como ya hemos creado la clase con su constructor, podemos crear objetos de ese tipo. Similar a cuando creas un int, o un string... así de fácil. Veamos la línea exacta:
public class Main {
static AdivinaAleatorio miJuego = new AdivinaAleatorio();
}
Crea un atributo, de tipo AdivinaAleatorio, llamado miJuego. La palabra reservada "new" es la que hace uso del constructor. Vamos, que al escribir esa línea, el programa "entra" en la clase AdivinaAleatorio, busca el método constructor, y ejecuta ese código. En nuestro caso inicializa el número de intentos y el aleatorio.
Vale, por último creamos un método main dentro de la clase Main. Como dije al principio, el método main es el que se ejecuta. Si no hay método main, el programa no hace nada. Vale, añadimos un método main y quedará así:
public class Main {
static AdivinaAleatorio miJuego = new AdivinaAleatorio();
public static void main(String[] args) {
}
}
Ya tenemos clase Main, atributo de tipo AdivinaAleatorio, y método main (vacío pero ahí está).
Solo falta rellenarlo, vamos a ir metiendo cosas:
System.out.println( "----- Bienvenido al programa -----" );
System.out.println( "" );
System.out.println( "Pulse 1 para empezar una partida o 0 para salir" );
Eso se entiende no? La segunda línea simplemente deja un "intro" adicional entre las dos frases.
Ahora el usuario va a meter un número. Nos sirve la función que hicimos en la otra clase, la de "leerNumero". Así que vamos a usarla que no me apetece meter otra vez el tocho horrible de código aquel:
int opcion = miJuego.leerNumero();
Hay que poner "miJuego." delante, ya que ese método está en el objeto miJuego, no en nuestra clase Main.
Y ahora, un bucle. ¿Para qué? Para que mientras el usuario no introduzca un 0, el programa siga permitiendo jugar. Ahí va el código:
while (opcion == 1)
{
miJuego.reiniciar();
miJuego.jugarPartida();
System.out.println( "Para jugar otra partida escriba 1. Si no, escriba 0" );
opcion = miJuego.leerNumero();
}
Mientras el usuario siga poniendo la opción 1, reiniciamos el juego (para que se genere otro número aleatorio y los intentos restantes se reseteen a 3), y usamos el método de jugarPartida. Cuando termine la partida, le preguntamos al usuario si quiere jugar de nuevo y leemos el número que escriba. Si mete un 1, el bucle se repetirá. Si mete un cero, saldremos del bucle.
Y ya está, le vamos a añadir una despedida cuando el programa termine:
System.out.println( "----- Gracias por usar el programa -----" );
System.out.println( "Que pase un buen dia!" );
Ahora sí, hemos terminado.
public class Main {
static AdivinaAleatorio miJuego = new AdivinaAleatorio();
public static void main(String[] args) {
System.out.println( "----- Bienvenido al programa -----" );
System.out.println( "" );
System.out.println( "Pulse 1 para empezar una partida o 0 para salir" );
int opcion = miJuego.leerNumero();
while (opcion == 1)
{
miJuego.reiniciar();
miJuego.jugarPartida();
System.out.println( "Para jugar otra partida escriba 1. Si no, escriba 0" );
opcion = miJuego.leerNumero();
}
System.out.println( "----- Gracias por usar el programa -----" );
System.out.println( "Que pase un buen dia!" );
}
}
Hemos acabado, os dejo los dos archivos fuente:
[attachment=3][attachment=2]
Y esos dos archivos ya compilados, para que podáis ejecutarlos sin necesidad de compilador:
[attachment=1][attachment=0]
Recordad, para compilar "javac Main.java"
Para ejecutar algo compilado: "java Main".
No se ejecuta la clase AdivinaAleatorio, lo he dicho varias veces, se ejecuta la clase que contenga el método main. Probad a ejecutar la otra jeje, escribid "java AdivinaAleatorio" y os dirá que no encuentra el main:
Exception in thread "main" java.lang.NoSuchMethodError: main
Bueno espero que os haya gustado. En un futuro espero que no muy lejano añadiremos otro tipo de juegos a nuestro main, para que al ejecutar el programa se dé la opción al usuario de escoger el juego al que prefiera jugar
[licencia][/licencia]