[Java] Maquina Tragaperras

Iniciado por /d3v/nu11, Abril 08, 2015, 08:39:12 PM

Tema anterior - Siguiente tema

0 Miembros y 1 Visitante están viendo este tema.

Ejercicio de Maquina tragaperras que he hecho para la universidad.

1. Main
Código: java

import java.util.Scanner;
import java.util.Arrays;

public class Programa {
public static void main(String[] args) {

// 1. Declara dos variables locales de tipo Premio
Fruta[] combinacion1 = {Fruta.FRESA, Fruta.FRESA, Fruta.FRESA};
Premio premio1 = new Premio(combinacion1, 20);
Fruta[] combinacion2 = {Fruta.SANDIA, Fruta.FRESA,Fruta.SANDIA};
Premio premio2 = new Premio(combinacion2, 10);

/* 2. Crea una máquina con un tamaño de combinación de 3 frutas,
* un precio por partida de 0,5 euros
* y los dos premios declarados previamente
*/
Maquina maquina = new Maquina(3, 0.5, premio1, premio2);

/* 3. Solicita al usuario que introduzca por teclado la cantidad
* de crédito para jugar.
*/
System.out.println("Introduzca el crédito: ");
Scanner teclado = new Scanner(System.in);
double credito = teclado.nextDouble();
teclado.nextLine();
maquina.incrementarCredito(credito);
System.out.println(credito);


// 4. Jugamos mientras haya crédito disponible
Fruta[] combinacion;
maquina.setCredDisp(credito);
while (maquina.getCredito() > 0){

//4.1 Realiza la jugada
combinacion = maquina.jugar();

//4.2 Muestra la combinación obtenida y el crédito
System.out.println(Arrays.toString(combinacion)+" --- "+maquina.getCredito());

//4.3 Pide al usuario que pulse intro para continuar
System.out.println("Pulse intro para volver a jugar");
teclado.nextLine();
}
System.out.println("Fin del juego: no dispone de credito suficiente");
}
}


2. Maquina
Código: java

import java.util.Random;
import java.util.Arrays;

public class Maquina {
private int casillas;
private double precJug;
private double credDisp;
private Premio[] coleccion;

public Maquina(int nCasillas, double precio, Premio... premio) {
precJug=precio;
casillas=nCasillas;
coleccion=premio;
}

public double getPrecJug() {
return precJug;
}
public void setPrecJug(double precio) {
precJug = precio;
}
public double getCredito() {
return credDisp;
}
public void setCredDisp(double credito) {
credDisp = credito;
}
public int getnCasillas() {
return casillas;
}
public Premio[] getColeccion() {
return coleccion;
}

public double incrementarCredito(double incremento) {
return credDisp + incremento;
}

public double cobrar() {
System.out.println("Retirando "+credDisp+" euros de la maquina");
credDisp = 0;
return credDisp;
}

public Fruta[] jugar() {
setPrecJug(precJug);
if (getCredito() >= precJug) {
credDisp = credDisp - precJug;

Random generador = new Random();
Fruta[] frutas;
frutas = new Fruta[casillas];
Fruta[] frutas_aleatorias=Fruta.values();

for (int i = 0;i<casillas; i++){
int index = generador.nextInt(5);
frutas[i]=frutas_aleatorias[index];
}

int n = 1; // n = numero de premios
for (int i = 0; i <= n; i++) {
//comprueba si combinación esta en premios registrados
if (Arrays.equals(frutas, coleccion[i].getCombGanad()) == true){
credDisp = credDisp + coleccion[i].getPremio();
}
}
return frutas;
}
return null;
}
}


3.Premio
Código: java

public class Premio {
private Fruta[] CombGanad;
private int premio;

public Fruta[] getCombGanad() {
return CombGanad;
}

public int getPremio() {
return premio;
}

// CONSTRUCTORES
public Premio(Fruta[] combinacion, int p) {
CombGanad=combinacion;
premio=p;
}
}


4.Frutas
Código: java

public enum Fruta {
FRESA, SANDIA, PLATANO, MELOCOTON, PERA
}


Piensa por ti mismo y cuestiona a la autoridad.

Buen aporte. Sería bueno que ahora lo hagas con una GUI. Lo complicado sería la animación de las figuras corriendo si es que lo haces en Swing. JavaFX provee una API para animaciones, inténtalo.

Saludos.

La verdad es que no estoy muy puesto en el tema de interfaces graficas. Pero lo intentare de todos modos.

Un saludo compañero!!!


Piensa por ti mismo y cuestiona a la autoridad.

Hola /d3v/nu11,

realmente relevantes son solamente los dos últimos. Puede que en semejantes programas pequeños la entrada de usuario invalidante todavía este okay; y simplemente se debe al formato. Pero el bucle con el índice fijo es justamente un bug que nunca debería pasar.

Citar
Código: java

int n = 1; // n = numero de premios
                        for (int i = 0; i <= n; i++) {
                                //comprueba si combinación esta en premios registrados
                                if (Arrays.equals(frutas, coleccion[i].getCombGanad()) == true){
                                        credDisp = credDisp + coleccion[i].getPremio();
                                }       
                        }

Código: java

for (Premio premio : coleccion) {
    if (Arrays.equals(frutas, premio.getCombGanad()) == true){
        credDisp = credDisp + premio.getPremio();
    }   
}


Sobre todo evita el bug de sencillamente presuponer una longitud de Array fija en una clase pero no comprobar esto en ninguna parte.


Saludos
Este es el mayor reproche al pueblo hispanohablante:

Que a pesar de su inteligencia y a pesar de su valentía siempre adoran el poder.

Hola /d3v/nu11,

Gran aporte, como dice @No tienes permitido ver los links. Registrarse o Entrar a mi cuenta Garsaky, sería una gran idea que este programa tuviera GUI. También te recomiendo que subieras este código a GIthub.

Saludos

Hola /d3v/nu11,

revisando de nuevo tu código, se me ocurre esto:
produjiste algo que en realidad es mucho mejor que las publicaciones de otros usuarios. Mejor, pero no fantástico o bueno en absoluto. Hay bastantes comentarios que puedo hacer para permitirte mejorar.

En primer lugar, tu clase principal:
Código: java

System.out.println("Introduzca el crédito: ");
Scanner teclado = new Scanner(System.in);
double credito = teclado.nextDouble();


Sin manejo de excepciones. Simplemente puedo ingresar cualquier valor de NaN y tu aplicación se bloqueará porque no estás verificando la entrada. Para empezar, puedo detener completamente tu juego simplemente ingresando un crédito negativo, que es algo que probablemente quieras restringir.

También puedo interrumpir tu aplicación ingresando un valor de crédito que es menor que el costo de "jugar". Debes verificar esto:

Código: java

Maquina maquina = new Maquina(3, 0.5, premio1, premio2);


Código: java

if (getCredito() >= precJug) {
                        credDisp = credDisp - precJug;
                       
                        Random generador = new Random();
                        Fruta[] frutas;
                        frutas = new Fruta[casillas];
                        Fruta[] frutas_aleatorias=Fruta.values();
                       
                        for (int i = 0;i<casillas; i++){
                                int index = generador.nextInt(5);
                                frutas[i]=frutas_aleatorias[index];
                        }
                       
                        int n = 1; // n = numero de premios
                        for (int i = 0; i <= n; i++) {
                                //comprueba si combinación esta en premios registrados
                                if (Arrays.equals(frutas, coleccion[i].getCombGanad()) == true){
                                        credDisp = credDisp + coleccion[i].getPremio();
                                }       
                        }
                        return frutas;
                }
                return null;


Esto hace que tu función retorne null en lugar de una excepción adecuada o simplemente no permitir jugadas cuando el crédito < la cantidad requerida para jugar. En este momento estoy atrapado en un bucle infinito. Gracias por el bucle infinito, /d3v/nu11...

No tienes que seguir configurando el 'prec jug', sea lo que sea que eso signifique. Hacerlo una vez es más que suficiente y no tiene absolutamente ningún propósito establecer un valor para que sea igual a sí mismo una y otra vez cuando se juega. Ya has establecido este valor en el constructor:
Código: java

public Maquina(int nCasillas, double precio, Premio... premio) {
                precJug=precio;
                casillas=nCasillas;
                coleccion=premio;
        }


Pero tu constructor no maneja adecuadamente los valores de variables ilegales. Puedes hacer fácilmente una Máquina con un 'precJug' (mierhw hombre, usa nombres de variables adecuados) negativo, por ejemplo.

Este método aquí devuelve un valor, pero nunca usas este valor:
Código: java

public double incrementarCredito(double incremento) {
                return credDisp + incremento;
        }


También usas esto solo una vez al comienzo del 'juego', lo que hace que esta función sea completamente redundante. No sirve para nada. No hace nada. Tienes otra función que establece el crédito correctamente si eso es lo que pretendías hacer, pero por alguna razón la nombraste mal (como suelen hacer los usuarios de aquí):
Código: java

public void setCredDisp(double credito) {
                credDisp = credito;
        }


Además del nombramiento de esta función, no debes permitir que se pase crédito negativo.

En tu clase de Premio, se supone que tu constructor agregue un crédito al saldo total del usuario si gana, sin embargo, puedes poner fácilmente números negativos y vectores null aquí ya que una vez más no verificas los valores de las variables que son pasadas. Esto puede causar un comportamiento que no deseas para el propósito de este 'juego':
Código: java

public Premio(Fruta[] combinacion, int p) {
                CombGanad=combinacion;
                premio=p;
        }


También tienes bastantes métodos que no sirven para nada porque no se usan en ningún lado:
Código: java

System.out.println("Retirando "+credDisp+" euros de la maquina");
                credDisp = 0;
                return credDisp;
        }
public int getnCasillas() {
                return casillas;
        }
public Premio[] getColeccion() {
                return coleccion;
        }
public double getPrecJug() {
                return precJug;
        }


Aquí, haces algo que es bastante divertido:
Código: java

if (Arrays.equals(frutas, coleccion[i].getCombGanad()) == true){
                                        ...
                                }


Puedes simplificar esto:
Código: java

if (Arrays.equals(frutas, coleccion[i].getCombGanad())){
                                        ...
                                }


Por cierto, tampoco cierras tu Scanner.

Entonces para concluir:
. Usa nombres de variables apropiados
. Usa getters y setters adecuados
. Usa nombres de funciones adecuados
. Utiliza manejos de errores adecuados
. Restringe la entrada de usuario a valores que tengan sentido
. Elimina funciones no utilizadas
. Cierra tu Scanner de mierhw


Saludos
Este es el mayor reproche al pueblo hispanohablante:

Que a pesar de su inteligencia y a pesar de su valentía siempre adoran el poder.