Mostrar Mensajes

Esta sección te permite ver todos los posts escritos por este usuario. Ten en cuenta que sólo puedes ver los posts escritos en zonas a las que tienes acceso en este momento.


Mensajes - Kabuto

Páginas: 1 ... 12 13 14 15 16 [17] 18 19 20 21 22 ... 50
321
Aprender a programar desde cero / Re: Lenguaje en c
« en: 24 de Octubre 2021, 00:28 »
Bueno, a ver...

La verdad es que el lenguaje C no es lo mío, lo conozco muy por encima...

Aquí he escrito un código que, usando dos funciones para generar distintos tipos de aleatorios, se crean, rellenan y muestran ambos vectores.
No se si es el código más adecuado, ya digo que estoy poco familiarizado con C, pero parece funcionar.

Sería maravilloso que alguien con mejores capacidades nos diera su opinión.

Faltarían los puntos 4) y 5). Inténtalos, a ver hasta donde puedes llegar.

Código: [Seleccionar]
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int generaImpar5_15(); //Función que genera un impar entre 5 y 15
int generaImpar20_40(); //Función que genera un impar entre 20 y 40, y que no acaba en 5

int main()
{
    srand(time(NULL));
    //Creamos vectores
    int longitud = generaImpar5_15();
    int vector1[longitud], vector2[longitud];
    //Rellenamos
    for (int i  = 0; i < longitud; i++) {
        vector1[i] = generaImpar20_40();
        vector2[i] = generaImpar20_40();
    }
    //Los mostramos
    printf("Vector 1:\n");
    for (int i  = 0; i < longitud; i++) {
        printf("%d ", vector1[i]);
    }
   
    printf("\nVector 2:\n");
    for (int i  = 0; i < longitud; i++) {
        printf("%d ", vector2[i]);
    }
   
    return 0;
}

int generaImpar5_15() {
   
    int impar;
    do {
        impar = 5 + (rand() % 11);
    } while (impar % 2 == 0); //Si es par, se repite el bucle
   
    return impar;
}

int generaImpar20_40() {
   
    int imparNo5;
    do {
        imparNo5 = 20 + (rand() % 21);
    } while(imparNo5 % 2 == 0 || imparNo5 % 5 == 0);//Si es par, o impar múltiplo de 5, se repite el bucle
   
    return imparNo5;
}

322
Aprender a programar desde cero / Re: Lenguaje en c
« en: 23 de Octubre 2021, 10:13 »
Hola.
Muestra lo que tengas hecho y/o específica que parte es la que se te resiste, o donde tienes dudas sobre que proceso lógico aplicar.

Un saludo.

323
A ver, sigo sin tiempo  :-\

Pero puedo proponer un diseño de como podría ser la clase principal

Tendría dos ArrayLists, uno para Galerías y otro para Artistas.
Las Exposiciones se guardaría directamente en alguna de las Galerías, podemos hacer que el usuario elija la Galería o bien que el sistema automáticamente una Galería donde pueda registrarse siempre que sea aceptable por su horario.
Si dejamos que el usuario elija Galería, igualmente puede encontrarse con que la Galería escogida rechace su Exposicion por problemas de horarios, así que quizás sea más sencillo hacer que sea el programa quien busque una Galería disponible.

Las Galerías habrá que crearlas a mano al comenzar el programa. Se puede ofrecer opción para que el usuario elija cuantas quiere crear y que inserte los datos de codigo y capacidad.
Pero como el enunciado no dice nada sobre esto, pues podemos simplificarlo creandolas "a mano" nosotros en el código.

Tras crearlas, ofrecemos menú de opciones que se repita hasta que el usuario elija terminar.
Al leer opción, la analizamos con un switch y según lo escogido, llamaremos al método correspondiente.

Porque eso lo que haremos, un método para cada función: uno para crear un artista, otro para crear una exposicion y guardarla en una galeria, etc...

Propongo este código, que como digo, es un "boceto". Habría que añadir todos los métodos para cada opción del menú.

Código: [Seleccionar]
import java.util.ArrayList;
import java.util.Scanner;

public class GestionMuseo {

private static ArrayList<Galeria> galerias = new ArrayList<Galeria>();
private static ArrayList<Artista> artistas = new ArrayList<Artista>();
private static Scanner teclado = new Scanner(System.in);

public static void main(String[] args) {
crearGalerias();
int opcion = 0;
while (opcion != 9) {
System.out.println("\n\n\tGESTION MUSEO");
System.out.println("\t------- -----\n");
System.out.println("[1] -- Registrar EXPOSICION");
System.out.println("[2] -- Registrar ARTISTA");
System.out.println("[3] -- Listar EXPOSICIONES por ARTISTA");
System.out.println("[4] -- Listar EXPOSICIONES activas");
System.out.println("[5] -- Listar tipos de EXPOSICION");
System.out.println("[6] -- Listar GALERIAS ocupadas y vacantes");
System.out.println("[9] -- TERMINAR PROGRAMA");
System.out.print("Elija opcion: ");
opcion = Integer.parseInt(teclado.nextLine());
switch(opcion) {
case 1:
//Llamar a método para registrar EXPO y asignarla a una GALERIA
break;
case 2:
//Llamar a método para registrar ARTISTA
break;
case 3:
//Llamar a método para listar EXPOS según un ARTISTA
break;
case 4:
//Llamar a método para listar EXPOS activas, según una hora indicada
break;
case 5:
//Llamar a método para listar los tipos de EXPOSICION
//O tal vez haya que pedir un tipo y listar EXPOSICIONES de dicho tipo...
//No estoy seguro.... ¯\_(ツ)_/¯
break;
case 6:
//Llamar a método para listar GALERIAS ocupadas y vacantes(o sea, todas...)
break;
case 9:
System.out.println("\n\tFIN DE PROGRAMA");
break;
default:
System.out.println("Opcion equivocada...");
}
}

}

private static void crearGalerias() {
galerias.add(new Galeria(101, 45));
galerias.add(new Galeria(102, 55));
galerias.add(new Galeria(103, 40));
galerias.add(new Galeria(104, 25));
}

}

324
Hola de nuevo.
Releyendo el enunciado, parece ser que nos ha faltado un atributo para la clase Exposicion, ya que pide listar los "tipos de exposición".
Así que habría que agregarle dicho atributo, además de sus métodos get y set y actualizar el constructor
Citar
public class Exposicion {

   private int inicio;
    private int fin;
    private Artista artista; //Una exposicion, solo tiene un artista
    private String tipo;

    public Exposicion(int inicio, int fin, Artista artista, String tipo) {
        this.inicio = inicio;
        this.fin = fin;
        this.artista = artista;
        this.tipo = tipo;

    }

    public int getInicio() {
        return inicio;
    }

    public void setInicio(int inicio) {
        this.inicio = inicio;
    }

    public int getFin() {
        return fin;
    }

    public void setFin(int fin) {
        this.fin = fin;
    }
   
    public Artista getArtista() {
      return artista;
   }

   public void setArtista(Artista artista) {
      this.artista = artista;
   }

   public String getTipo() {
      return tipo;
   }

   public void setTipo(String tipo) {
      this.tipo = tipo;
   }


}


Dicho esto, volviendo a la clase Galeria, dijimos que al recibir una nueva Exposicion, antes de agregarla había que comprobar que su horario no se solapase con el horario de otras exposiciones ya registradas.
Así que he decidido hacer un método que sea de tipo boolean, para que retorne true si aceptamos la exposición o false si la rechazamos.

Para decidir si se acepta o no, lo que hago es recorrer el ArrayList y comparar los horarios de la nueva expo con las existentes, si veo que hay alguna que se solapa el horario, directamente retorno false y se acabó la búsqueda.
No se si el código que he puesto para comprobar los horarios es correcto, pero bueno, creo que más o menos funcionará.
Código: [Seleccionar]
public boolean agregarExposicion(Exposicion expo) {
if (LExposicion.isEmpty()) {//Lista exposiciones vacía
LExposicion.add(expo); //aceptamos expo sin comprobar nada.
return true;
}
else {
/*
* Recorremos la lista de exposiciones para ver si hay alguna
* que se solape con la que queremos agregar.
* En cuanto encontremos una que se solape, rechazaremos la nueva expo
* Si no se encuentra ninguna, entonces es aceptable
*/
for (Exposicion otraExpo: LExposicion) {
if (expo.getInicio() == otraExpo.getInicio())
return false; //Se solapan, comienzan al mismo tiempo
else if (expo.getFin() == otraExpo.getFin())
return false; //Se solapan, acaban a la misma hora
else if (expo.getInicio() < otraExpo.getInicio() && expo.getFin() > otraExpo.getInicio())
return false; //Se solapan, hay una expo que comienza antes de que la nueva termine
else if (expo.getInicio() < otraExpo.getFin())
return false; //Se solapan, la nueva expo comienza cuando ya hay otra exponiéndose
}
//Si el bucle for consigue finalizar sin retornar false, es que la nueva expo es aceptable
LExposicion.add(expo);
return true;
}
}


Bueno, tras esto, y mirando en el enunciado lo que se pide registrar y lo que se pide listar, me surge una duda.
La línea que marco en negrita:
Citar
1. Registrar exposición
      - Registrar exposición
      - Registrar artista
      - Registrar exposiciones del artista (anteriores y actuales)
      - Listar exposiciones activas
2. Configurar exposiciones y galerías
      - Listar tipos de exposición
      - Listar galerias ocupadas y vacantes

¿Es posible que esté equivocada y lo correcto sea "Listar exposiciones del artista" ?
Es que si es "Registrar", pues la verdad es que entonces no se a qué se refiere. Ya tenemos un registro de exposiciones, y cada exposición está relacionada con su artista.
¿Qué es eso de un segundo registro de "exposiciones del artista"?
No lo entiendo...

En cambio, si fuera "Listar", lo veo más lógico. Consistiría en que al usuario le preguntamos por un Artista, para luego darle un listado de las exposiciones asociadas con dicho artista.

Mientras se aclara esta duda, podemos fijarnos en los otros listados.
Nos piden:

Citar
- Listar exposiciones activas
Supongo que por "activas" se refieren a que si se están exponiendo en "este momento".
Es decir, le preguntaríamos al usuario ¿Qué hora es? y entonces recorremos las exposiciones buscando cuáles tienen horarios que coincidan con esa hora.
Para lograr esto, necesitamos que la clase Exposicion sea capaz ella misma de informar si está activa o no.
Así que podemos añadirle un método que reciba una hora y retorne true si dicha hora está dentro de su horario o false en caso contrario.
A Exposicion, le añadimos este método:
Citar
   public boolean estaActiva(int hora) {
      if (hora >= inicio && hora < fin)
         return true;
      else
         return false;
   }

También podríamos añadirle (sobreescribir para ser más exactos) el método toString().
Este método se usa para hacer que una clase devuelva una cadena de texto con los datos y formato que consideremos adecuados para mostrarse en pantalla.
Así cuando queramos listar sus objetos en pantalla, será más cómodo porque la propia clase ya nos proporcionará la cadena que hay que mostrar:
Código: [Seleccionar]
@Override
public String toString() {
String cadena = "Artista: " + artista.getnombre();
cadena += " - Tipo: " + tipo;
cadena += "\nHorario: " + inicio + ":00 - " + fin + ":00";

return cadena;
}
La etiqueta @Override es para indicarle a Java que dicho método, es para sobreescribir un método heredado.
En Java, TODAS las clases heredan el método toString() desde la clase Object, que es algo así como la superclase suprema de la que todas las demás son hijas.
Lo que pasa es que ese método heredado, solo será útil si lo sobreescribimos para decirle como tiene que actuar.

Pues bueno, ahora que la clase Exposicion ya sabe decirnos si está activa o no, y también sabe como ha de ser la cadena con la que se muestre en pantalla, vamos a ver como le decimos a Galeria que nos haga un listado de las exposiciones activas.
Bueno, en realidad no será una lista. Se supone que en cada momento solo habrá una exposicion activa en una galería.

Así que cada galería, mostrará una sola exposicion activa, o ninguna...

A la clase Galeria, le damos este método:
Código: [Seleccionar]
public void imprimirExposicionesActivas(int hora) {
System.out.println("\nCodigo de Galería: " + codigo);
System.out.println("Exposicion Activa:");
boolean hayActiva = false;
for (Exposicion expo: LExposicion)
if (expo.estaActiva(hora)) {
hayActiva = true;
System.out.println(expo); //Gracias al método toString(), con esto es suficiente
}
//Es posible que no haya ninguan expo activa, hay que informar de esto.
if (!hayActiva)
System.out.println("No hay exposiciones activas en esta Galería");
}

Que más listados nos piden:
Citar
      - Listar tipos de exposición

Pues habrá que pedirle a cada Galeria, que recorra sus exposiciones y muestre el valor del atributo "tipo".
Creo que con este método es suficiente:
Código: [Seleccionar]
public void imprimirTiposExposiciones() {
System.out.println("\nCodigo de Galería: " + codigo);
System.out.println("Tipos de Exposición:");
if (LExposicion.isEmpty())
System.out.println("No hay exposiciones en esta Galería");
else
for (Exposicion expo: LExposicion)
System.out.println("- " + expo.getTipo());
}

Más listados:
Citar
      - Listar galerias ocupadas y vacantes

Yo ahí entiendo que se refiere a listar TODAS las galerías, sin condiciones.
Pero este listado, se tendrá que hacer desde la clase principal, que será quien tenga un ArrayList de objetos Galería

Sin embargo, igual que hemos hecho antes, podemos darle a Galeria un método toString() para que ella misma sepa construir una cadena informando de si está vacante(sin exposiciones) o si está ocupada y que entonces además nos diga cuántas exposiciones tiene registradas.
Así cuando escribamos el método para listar galerías, será más sencillo.
Código: [Seleccionar]
@Override
public String toString() {
String cadena = "Codigo de Galería: " + codigo;
cadena += "\nCapacidad: " + capacidad;
if (LExposicion.isEmpty())
cadena += "\nEstado: Vacante. No hay exposiciones";
else
cadena += "\nEstado: Ocupada. Hay " + LExposicion.size() + " exposiciones";

return cadena;
}


Pues bien, solo queda aclarar la duda que puse antes, sobre si lo de las "exposiciones de artistas" es registrar, o es listar.
Y ponernos ya con la clase principal.
Pero me temo que hasta mañana por la noche no podré continuar.

Un saludo.

325
Algo parecido a esto:


Código: [Seleccionar]
do {

            System.out.println("(T) - Ingresar TV);
            System.out.println("(P) - Ingresar PC);
            System.out.print("Elija opción: );
            opc = lea.next();

            if (opc.equals("T") {
                        System.out.print("Ingresa la referencia del TV: ");
                        ref = lea.nextInt();
                        System.out.print("Ingresa la marca del TV: ");
                        marca = lea.next();
                        System.out.print("Ingresa las Pulgadas del TV: ");
                        pul = lea.nextInt();

                        Televisor tv = new Televisor(ref, marca, pul);
                        System.out.println(listac.insertarNodo(tv));
            }
            else {
                        //Pedir datos de PC
                        //Insertar nodo tipo PC
            }

            System.out.print("¿Desea continuar insertando nodos? Si - No: ");
            opc = lea.next();

        }while(!opc.equalsIgnoreCase("no"));

326
Hola.

A ver, algunas correcciones en la clase Artista.

- No se necesita importar la clase Scanner, porque no se van a pedir datos desde esta clase.
- Hay una llave de cierre equivocada que provoca que la clase se cierre donde no debe, dejando FUERA de ella los métodos que vienen a continuación.
- El método setDNI(), recibe entre paréntesis un argumento llamado "DNI", todo en mayúscula. Pero luego dentro de su cuerpo se usa la palabra "dni", en minúscula.
Por tanto Java considera que no se está haciendo nada con el argumento DNI, porque no se le está nombrando en el código.
Hay que escribirlo exactamente igual, de lo contrario, se consideran variables distintas.
Citar
import java.util.Scanner; //Este import es innecesario

public class Artista {
    private String dni;
    private String nombre;

    public Artista(String dni, String nombre) {
        this.dni = dni;
        this.nombre = nombre;
    }

     
    } //Esta llave está CERRANDO la clase antes de tiempo.

    public String getdni() {
        return dni;
    }

    public void setDNI(String DNI) {
        this.dni = dni; //El argumento DNI es en mayúsucula, no es en minúscula
    }


    public String getnombre() {
        return nombre;
    }

    public void setNombre(String nombre) {
this.nombre = nombre;
    }

   
       
}

Una vez corregido, debería quedar así:
Código: [Seleccionar]
public class Artista {

private String dni;
private String nombre;

public Artista(String dni, String nombre) {
this.dni = dni;
this.nombre = nombre;
}

public String getdni() {
return dni;
}

public void setDNI(String DNI) {
this.dni = DNI;
}

public String getnombre() {
return nombre;
}

public void setNombre(String nombre) {
this.nombre = nombre;
}

}

Sobre la clase Exposicion.
Hablemos de sus atributos.
Para la hora de inicio y fin, has elegido el tipo double.
Existen clase para trabajar con horas, tiempos y fechas.... pero ahora mismo es mejor no usarlas para no complicar más la cosa.
Así que el tipo double puede servir perfectamente, aunque yo incluso optaría por usar el tipo int y así trabajamos con enteros para las horas.
Esta exposición empieza a las 16 y termina a las 18, esta otra empieza a las 7 y acaba a las 10, etc...

Para el artista, he visto que has puesto un ArrayList. Esto podría estar bien si vamos a considerar que una exposición, puede tener muchos artistas.
Pero leyendo el enunciado, parece que lo que vamos a considerar es que una exposición, tiene solo un único artista.
Así que yo optaría por esto último, además simplifica las cosas.

Además, en el constructor de Exposicion ya has puesto que se recibe un Artista de forma externa, aunque luego no haces nada con él.
Aquí tenemos dos opciones:
- el Artista se recibe por constructor, y por tanto, esta clase no es necesario que pida datos para crear un artista.
- el constructor NO recibe ningún Artista, y por tanto, esta clase ha de tener un método para pedir datos mediante Scanner y así construir el artista.

Ambas posibilidades son válidas. Yo, personalmente, prefiero la primera. Porque me gusta más que haya una sola clase encargada de pedir datos, ya sea la clase prinicipal o una clase "gestora" que se encargue expecíficamente de esto.
El resto de clases prefiero que tan solo reciban datos, los guarden, operen con ellos... pero que no tengan que pedirlos.

Si lo hacemos así, ya no necesitamos tampoco importar la clase Scanner, ni tampoco la clase ArrayList porque solo vamos a tener un artista por exposición.

Yo, por ahora, dejaría así la clase Exposicion
Código: [Seleccionar]
public class Exposicion {

private int inicio;
    private int fin;
    private Artista artista; //Una exposicion, solo tiene un artista

    public Exposicion(int inicio, int fin, Artista artista) {
        this.inicio = inicio;
        this.fin = fin;
        this.artista = artista;
    }

    public int getInicio() {
        return inicio;
    }

    public void setInicio(int inicio) {
        this.inicio = inicio;
    }

    public int getFin() {
        return fin;
    }

    public void setFin(int fin) {
        this.fin = fin;
    }
   
    public Artista getArtista() {
return artista;
}

public void setArtista(Artista artista) {
this.artista = artista;
}

}

Aunque insisto en que se podría usar double en lugar de int, y que también se podría hacer que esta clase pidiera datos para crear el Artista. Esto ya es a gusto del programador.

Sobre la clase Galeria (ojo que has escrito mal el nombre).
Una galeria puede tener muchas exposiciones.
Así que en este caso, sí nos vendrá bien usar un ArrayList de exposiciones.
Has añadido dos atributos: código y capacidad.
No los pide el enunciado, pero bueno, son atributos que tienen sentido para una galería, así que podemos usarlos.

Veo que has puesto un método para pedir datos y crear exposiciones. Como ya he dicho, se puede hacer así si lo deseas.
Pero entonces no tiene sentido que el método para crear exposiciones, reciba como argumento una exposición. No la está usando para nada, porque va a crear su propio objeto Exposicion.

Otro fallo en este método es que para crear la Exposicion, llamas a un constructor que solo recibe hora de inicio y fin. Pero el constructor de Exposicion exige recibir también un Artista.

Citar
    public void AgregarExposicionDatos(Exposicion expo){ //NO ha de recibir nada por paréntesis
   
    Scanner in = new Scanner(System.in);
    System.out.print("Ingrese la hora de inicio");
    double inicio = in.nextDouble();
    System.out.print("Ingrese la hora del final");
    double fin = in.nextDouble();
    this.LExposicion.add(new Exposicion (inicio,fin)); //Constructor de exposicion erróneo, falta Artista
   
    System.out.print("Exposicion creada ...");
}


Así que tendrías que cambiar el constructor de Exposicion para que no pida recibir un Artista, o bien, añadirle un segundo constructor donde solo pida las horas de inicio y fin.
Así se podrá crear una Exposición de las dos formas, pero recuerda que luego habrá que pedir los datos del Artista.

Yo, igual que antes, voy a preferir que esta clase no pida datos, tan solo que los reciba.

Pero atención, tanto si recibe Exposiciones ya creadas, como si se encarga ella de crearlas pidiendo datos con Scanner...., antes de añadirlas al ArrayList, se ha de comprobar que sus horas de inicio y fin no se solapan con las de otra Exposicion.

Si existe una Exposicion que empieza a las 16 y acaba a las 18..., no voy a poder añadir otra Exposicion que comience a las 17..., porque de 16 a 18 ya hay otra Exposicion ocupando la Galeria.

Hemos de añadir código para decidir si aceptamos o rechazamos una Exposicion, según su hora de inicio y fin.

Por desgracia se me acaba el tiempo y ahora no puedo seguir con esto.  :(
Luego cuando pueda intentaré seguir avanzando. Ves pensando en una forma de comprobar el tema de las horas de las exposiciones, que no coincidan unas con otras.
De momento, la clase Galeria la tengo así:

Código: [Seleccionar]
import java.util.ArrayList;

public class Galeria {
private int codigo;
private int capacidad;
private ArrayList<Exposicion> LExposicion;

public Galeria(int codigo, int capacidad) {
this.codigo = codigo;
this.capacidad = capacidad;
this.LExposicion = new ArrayList<Exposicion>();
}

public void agregarExposicion(Exposicion expo) {
/*
* Antes de aceptar la exposicion,
* hay que comprobar si sus horas de inicio/fin
* se solapan o no con otras exposiciones ya
* registradas
*/
}

public void ImprimirListaExposicion(){

System.out.println("Lista de exposiciones ");
for ( Exposicion  Expo : this.LExposicion){
System.out.println("Inicio: " + Expo.getInicio() + "Fin: "+ Expo.getFin());
}

}

public int getCodigo() {
return codigo;
}

public void setCodigo(int codigo) {
this.codigo = codigo;
}

public int getCapacidad() {
return capacidad;
}

public void setCapacidad(int capacidad) {
this.capacidad = capacidad;
}

}


327
El tema de "nodos" lo tengo muy verde, así que daré por hecho que la lógica que has usado para crear las listas y los nodos es correcta.

Así que en principio lo único que te falta, es crear la clase PC
Citar
y del tipo PC (de los Pc se conoce: código, marca, procesador, memoria ram y disco duro)
y ofrecer en el menú la posibilidad de elegir entre registrar TV o PC, además de poder listarlos por separado.

328

Al acceder al campo (desde la propia clase) "añosEmerito" podemos acceder con getAñosEmerito o añosEmerito.  Mi duda es si hay alguna diferencia entre las dos formas? ya que las dos hacen lo mismo. Habrá algún motivo para usar una u otra? Disculpen mi ignorancia

Si la operación va a consistir únicamente en cambiar el valor actual por otro, da igual hacerlo de una manera o de otra.

Sin embargo, muchas veces vamos a querer que la operación sea algo más completa, ya se para aplicar alguna regla de seguridad, alguna comprobación, alguna operación intermedia, etc..

Por ejemplo, pensemos en un atributo edad de una clase Persona.

Si le pasamos un valor directamente al atributo .edad , sin pasar por su habitual setter .setEdad(), podremos introducir cualquier valor, incluso alguno que no tenga sentido, como puede ser un -100 negativo.
Porque no tiene sentido que una persona tenga -100 años....

En cambio, si lo hacemos mediante su método .setEdad(), ahí ya podemos aplicar reglas y filtros para asegurar la "calidad" del dato recibido.

Podemos rechazar edades con valor negativo:

Código: [Seleccionar]
public void setEdad(int edad) {

    if (edad < 0)
        System.out.println("ERROR: La edad no puede ser un valor negativo");
    else
        this.edad = edad;
}

O podemos automatizar ciertas operaciones, como actualizar otro atributos en función del valor de la edad:

Código: [Seleccionar]
public void setEdad(int edad) {

    if (edad < 0)
        System.out.println("ERROR: La edad no puede ser un valor negativo");
    else {
        this.edad = edad;
        if (edad > 75)
            this.listoParaJubilarse = true;
        else if (edad >= 18)
            this.aptoParaVotar = true;
    }
}

Y bueno, cualquier otra cosa que podamos necesitar.
Esta es la ventaja de usar métodos set para cambiar el valor de los atributos, que nos permite aplicar código extra para proteger la calidad del dato, automatizar otros procesos, etc...

Algunas veces no ocurrirá nada de esto, y usar el método será prácticamente igual que acceder directamente al atributo, porque serán casos donde no se requiere hacer nada especial al cambiar el valor.
Pero muchas otras veces, la mayoría, vamos a querer establecer reglas y límites para los datos que recibimos y para ello necesitaremos usar los métodos.

329
No lo he probado pero parece que podría servir.


Solo comentar que, otra forma de "eliminar" valores de un arreglo sería dándoles valor null.
De ese modo, no es necesario, mover todos los valores una posición y "eliminar" el de la última posición.

Por eso en mis métodos, tanto para insertar elemento como para mostrar los valores en pantalla, compruebo que posiciones tienen valor null para decidir si puedo insertar ahí un valor o para decidir si no he de mostrarlo en pantalla.

Es otra forma de hacerlo. La tuya también sería correcta.

330
Comunidad / Re: Presentación
« en: 15 de Octubre 2021, 00:25 »
Bienvenido.

Si te sirven de ayuda, en la web hay algunos cursos con los que poder iniciarse.

Esperamos que participes activamente por aquí.
Un saludo.

331
Hola.

Sería necesario que el menú se repita continuamente hasta que el usuario decida terminar el programa.
Se le pide opción al usuario y con un swith evaluamos que opción ha escogido.

Cada opción puede escribirse en un método separado, para facilitar las cosas, el arreglo y el Scanner para pedir datos por teclado pueden declararse como atributos de ámbito global.

Así, todos los métodos que vayamos a crear, tendrán acceso directo a estos atributos y podrán trabajar con ellos.

Pongo un ejemplo rápido, donde solo he creado alguna de las opciones del menú.
Si comprendes la forma en la que he estructurado el programa, intenta tú crear las otras opciones del menú que faltan por escribir.
Y luego cuando tenga más tiempo, te ayudo a corregir o completar lo que sea.

Código: [Seleccionar]
public class Menu {

private static String[] arreglo;
private static Scanner teclado = new Scanner(System.in);

public static void main(String[] args) {

int opcion = 0;

do {
System.out.println("\n\n\t\tMENU");
System.out.println("(1) - Insertar un elemento al arreglo");
System.out.println("(2) - Crear un arreglo");
System.out.println("(3) - actualizar posiciones del arreglo");
System.out.println("(4) - Eliminar un valor del arreglo");
System.out.println("(5) - Visualizar valores del arreglo");
System.out.println("(9) - TERMINAR PROGRAMA");
System.out.print("Elija opción: ");
opcion = Integer.parseInt(teclado.nextLine());

switch(opcion) {
case 1:
insertarElemento();
break;
case 2:
crearArreglo();
break;
case 3:
break;
case 4:
break;
case 5:
visualizarArreglo();
break;
case 9:
System.out.println("\n\t\tFIN DE PROGRAMA");
break;
default:
System.out.println("\nOpcion equivocada");
}

} while (opcion != 9);

}

private static void insertarElemento() {
if (arreglo == null)
System.out.println("\nERROR. Primero ha de crear un arreglo");
else {
//Buscamos primera posición libre
int libre = -1;
for (int i = 0; i < arreglo.length; i++)
if (arreglo[i] == null) {
libre = i;
break; //Fin de búsqueda
}
//Comprobamos si hemos encontrado alguna posicion libre
if (libre == -1)
System.out.println("\nNo hay posiciones libres."
+ "\nTendrá que eliminar valor o actualizar uno existente");
else {
System.out.print("\nIntroduzca valor: ");
arreglo[libre] = teclado.nextLine();
}
}
}

private static void crearArreglo() {
System.out.print("\nIndique tamaño del nuevo arreglo: ");
int tm = Integer.parseInt(teclado.nextLine());
if (tm > 0) {
arreglo = new String[tm];
System.out.println("\nArreglo creado. Ya puede insertar nuevos valores.");
}
else
System.out.println("\nERROR. Ha de indicar un tamaño mayor que 0");
}

private static void visualizarArreglo() {
if (arreglo == null)
System.out.println("\nERROR. Primero ha de crear un arreglo");
else {
System.out.println("\nValores registrados:");
for (String valor: arreglo)
if (valor != null)
System.out.print("[" + valor + "] ");
}
}

}

332
En la clase Doctor has puesto dos métodos (nuevoDoctor() y getDoctor()) que deberían ir en la clase GestorDoctor

Además al método nuevoDoctor() hay que añadir un objeto Scanner para poder leer por teclado:

Citar
    public void nuevoDoctor() {
       Scanner teclado = new Scanner(System.in);
        System.out.println("\nALTA NUEVO DOCTOR");
        System.out.println("---- ----- ------\n");
        System.out.print("ID: ");
        String id = teclado.nextLine();
        System.out.print("Nombre: ");
        String nombre = teclado.nextLine();
        System.out.print("Apellidos: ");
        String apell = teclado.nextLine();
        System.out.print("Especialidad: ");
        String espe = teclado.nextLine();

        doctores.add(new Doctor(id, nombre, apell, espe));
        crearCSV(); //Añadimos nueva línea CSV al archivo en disco
    }

333
Todo depende un poco de como estés escribiendo el código.

Pero como idea general, has de conseguir una forma de poder transferir el ImageIcon que aplicas a las fichas (suponiendo que uses ImageIcon) a las piezas.
Para ello conviene que el ImageIcon sea un atributo de tu clase Ficha, para así tener una referencia que poder transferir.

Pongamos un ejemplo rápido.
No se como estás creando tus fichas, yo por ejemplo, voy a crearlas a partir de la clase JLabel.
El ImageIcon será un atributo, que podré comunicar "hacia fuera" mediante un método getter.
Cada ficha, recibirá por constructor una ruta String a la imagen que ha de mostrar como icono.
Código: [Seleccionar]
import java.awt.Color;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JLabel;

public class Ficha extends JLabel {

private ImageIcon icono;

public Ficha(String rutaImg) {
setOpaque(true);
setBackground(Color.WHITE);
icono = new ImageIcon(Ficha.class.getClassLoader().getResource(rutaImg));
setIcon(icono);
setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createRaisedSoftBevelBorder(),
BorderFactory.createEmptyBorder(10,10,10,10)));
}

public ImageIcon getIcono() {
return icono;
}

public void deSeleccionar() {
setBackground(Color.WHITE);
}

public void seleccionar() {
setBackground(Color.BLUE);
}

}

Los método seleccionar() y deSeleccionar() lo único que hacen es cambiar el color de fondo.
La idea es que la ficha que se seleccione, su fondo visible alrededor del icono cambie de color. Así parece que lo que cambia es su borde, y se puede distinguir en todo momento la ficha actualmente seleccionada.

Ahora, viene la clase Pieza.
Puedo reutilizar la clase que puse como ejemplo en el otro tema. Simplemente la transformo en un JButton, le añado un constructor que no me pida los atributos boolean(ahora no los necesitamos) y hago que se pinten con un icono por defecto.
En este caso, será un interrogante, para indicar que la Pieza/botón está a la espera de recibir una imagen a partir de una ficha.

Código: [Seleccionar]
import javax.swing.ImageIcon;
import javax.swing.JButton;

public class Pieza extends JButton {

public boolean esClara;
public boolean esGrande;
public boolean esRedonda;
public boolean esHueca;

public Pieza() {
setIcon(new ImageIcon(Pieza.class.getClassLoader().getResource("img/interrogante.png")));
}

public Pieza(boolean esClara, boolean esGrande, boolean esRedonda, boolean esHueca) {
this.esClara = esClara;
this.esGrande = esGrande;
this.esRedonda = esRedonda;
this.esHueca = esHueca;
setIcon(new ImageIcon(Pieza.class.getClassLoader().getResource("img/interrogante.png")));
}

}

Y ahora, una clase JFrame para mostrar las piezas y los botones.
En esta clase, usaré dos tipos de MouseListener.
Uno será para las fichas, y lo que hará es que cuando se clicke una ficha, se marcará como seleccionada y se recogerá en un atributo, el ImageIcon asociado a esa ficha.

El otro MouseListener será para los botones. Lo que hará será que cuando se pulse un botón, se le aplicará el ImageIcon que hemos recogido de alguna ficha seleccionada.

Código: [Seleccionar]
import java.awt.GridLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class PruebaImagenes extends JFrame {

private Ficha ficha1; private Ficha ficha2;
private Ficha ficha3; private Ficha ficha4;
private Pieza pieza1; private Pieza pieza2;
private Pieza pieza3; private Pieza pieza4;

private ImageIcon seleccion;

public PruebaImagenes() {

setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));

add(new PanelFichas());
add(new PanelPiezas());

setTitle("Test Imagenes");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setLocationRelativeTo(null);
setVisible(true);
}

private class PanelFichas extends JPanel {

public PanelFichas() {
ficha1 = new Ficha("img/peon1.png");
ficha2 = new Ficha("img/peon2.png");
ficha3 = new Ficha("img/alfil.png");
ficha4 = new Ficha("img/reina.png");
ficha1.addMouseListener(new SeleccionIcono());
ficha2.addMouseListener(new SeleccionIcono());
ficha3.addMouseListener(new SeleccionIcono());
ficha4.addMouseListener(new SeleccionIcono());
setLayout(new GridLayout(1,4,5,5));
add(ficha1); add(ficha2); add(ficha3); add(ficha4);
}
}

private class PanelPiezas extends JPanel {

public PanelPiezas() {
pieza1 = new Pieza();
pieza2 = new Pieza();
pieza3 = new Pieza();
pieza4 = new Pieza();
pieza1.addMouseListener(new AplicarIcono());
pieza2.addMouseListener(new AplicarIcono());
pieza3.addMouseListener(new AplicarIcono());
pieza4.addMouseListener(new AplicarIcono());
setLayout(new GridLayout(2,2));
add(pieza1); add(pieza2); add(pieza3); add(pieza4);
}
}

//MouseListener para las FICHAS
private class SeleccionIcono implements MouseListener {

@Override
public void mouseClicked(MouseEvent e) {
//Deseleccionamos todas las fichas
ficha1.deSeleccionar(); ficha2.deSeleccionar();
ficha3.deSeleccionar(); ficha4.deSeleccionar();
//Detectamos la seleccion actual
Ficha seleccionada = (Ficha) e.getSource();
//Marcamos como seleccionada
seleccionada.seleccionar();
//Capturamos su icono
seleccion = seleccionada.getIcono();
}

@Override
public void mousePressed(MouseEvent e) {}

@Override
public void mouseReleased(MouseEvent e) {}

@Override
public void mouseEntered(MouseEvent e) {}

@Override
public void mouseExited(MouseEvent e) { }

}

//MouseListener para las PIEZAS
private class AplicarIcono implements MouseListener {

@Override
public void mouseClicked(MouseEvent e) {
if (seleccion == null)
JOptionPane.showMessageDialog(null, "Seleccione primero una FICHA",
"Aplicar imagen", JOptionPane.WARNING_MESSAGE);
else {
//Detectamos pieza a la que se aplicará
Pieza seleccionada = (Pieza) e.getSource();
//Aplicamos icono
seleccionada.setIcon(seleccion);
}
}

@Override
public void mousePressed(MouseEvent e) {}

@Override
public void mouseReleased(MouseEvent e) {}

@Override
public void mouseEntered(MouseEvent e) {}

@Override
public void mouseExited(MouseEvent e) { }

}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {

@Override
public void run() {
new PruebaImagenes();
}
});
}

}


En este video puede verse como funciona:
https://www.youtube.com/watch?v=dq6WyiXFSfQ

334
Tienes respuesta en el otro tema

Sin embargo, puede que sea mejor que tu programa tenga su propio tema. Así que corrige lo que te he comentado en el otro tema, y las siguientes dudas que tengas continúa publicándolos en este.
Pero intentemos no duplicar consultas en varios temas, solo servirá para dispersar información.

Mejor tratarlo todo en un único tema.

335
A ver, veo varios problemas.

Primero, la clase GestorPacientes,
Código: [Seleccionar]
public final class GestorPacientes {
En algunas partes del código se la llama en singular: GestorPaciente
Citar
public class GestorCita {

    private ArrayList<Cita> citas;

    //Referencias a las instancias de los gestores de doctores y pacientes
    private GestorDoctor doctores;
    private GestorPaciente pacientes;

    public GestorCita(GestorDoctor gestDoc, GestorPaciente gestPaci) {
        citas = new ArrayList<Cita>();
        doctores = gestDoc;
        pacientes = gestPaci;
    }

Revisa que en todas las clases la estés llamando igual.

Otra cosa, el constructor de la clase GestorCita está declarado como que ha de recibir dos argumentos: un objeto GestorDoctor y un objeto GestorPacientes

Pero luego en la clase Clinica, cuando invocas este constructor no le das esos dos objetos:
Citar
public final class Clinica {

    private static ArrayList<Administrador> administradores = new ArrayList<Administrador>();
    private static Scanner teclado = new Scanner(System.in);
    static GestorPacientes pacientes = new GestorPacientes();
    static GestorCita citas = new GestorCita();
    static GestorDoctor doctores = new GestorDoctor();

Has de propocionarselos, y para poder hacerlo, el gestor de citas tendrá que ser el último gestor en construirse.
Citar
public final class Clinica {

    private static ArrayList<Administrador> administradores = new ArrayList<Administrador>();
    private static Scanner teclado = new Scanner(System.in);
    static GestorPacientes pacientes = new GestorPacientes();
    static GestorDoctor doctores = new GestorDoctor();
    static GestorCita citas = new GestorCita(doctores, pacientes);

Otro fallo en la clase Clinica, es la declaración de los métodos crearAdmins() y validarAcceso().
¡¡Están dentro del método main!!

Citar
    public static void main(String[] args) {//Apertura de main

        crearAdmins();

        if (validarAcceso()) {
            System.out.println("\nUsuario autorizado\n");
            if (validarAcceso()) {
                System.out.println("\nUsuario autorizado\n");
                doctores.nuevoDoctor();
                doctores.modificarDoctor();
                doctores.mostrarDoctores();
                pacientes.nuevoPaciente();
                pacientes.mostrarPacientes();
                pacientes.modificarPaciente();
                pacientes.borrarPaciente();
                citas.nuevoCita();
                citas.mostrarCitas();
            }
            else
                System.out.println("\nUsuario no autorizado.");

            System.out.println("\n\t\tFIN DE PROGRAMA");

        }

        private static void crearAdmins() {
            administradores.add(new Administrador("Kabuto", "1234"));
            administradores.add(new Administrador("EmethP", "5678"));
            administradores.add(new Administrador("AnaT", "0000"));
        }

        private static boolean validarAcceso( ) {

            System.out.println("ACCESO AL SISTEMA");
            System.out.println("------ -- -------\n");
            System.out.print("Nombre: ");
            String nombre = teclado.nextLine();
            System.out.print("Password: ");
            String password = teclado.nextLine();

            Administrador admin = new Administrador(nombre, password);

            return administradores.contains(admin);
        }

    }//Cierre de main

Deben ir FUERA del método main(), puedes ponerlos antes o después, pero siempre fuera del cuerpo del main()
Citar
   public static void main(String[] args) {//Apertura de main

      crearAdmins();

      if (validarAcceso()) {
         System.out.println("\nUsuario autorizado\n");
         if (validarAcceso()) {
            System.out.println("\nUsuario autorizado\n");
            doctores.nuevoDoctor();
            doctores.modificarDoctor();
            doctores.mostrarDoctores();
            pacientes.nuevoPaciente();
            pacientes.mostrarPacientes();
            pacientes.modificarPaciente();
            pacientes.borrarPaciente();
            citas.nuevoCita();
            citas.mostrarCitas();
         }
         else
            System.out.println("\nUsuario no autorizado.");

         System.out.println("\n\t\tFIN DE PROGRAMA");

      }

   }//Cierre de main

   private static void crearAdmins() {
      administradores.add(new Administrador("Kabuto", "1234"));
      administradores.add(new Administrador("EmethP", "5678"));
      administradores.add(new Administrador("AnaT", "0000"));
   }

   private static boolean validarAcceso( ) {

      System.out.println("ACCESO AL SISTEMA");
      System.out.println("------ -- -------\n");
      System.out.print("Nombre: ");
      String nombre = teclado.nextLine();
      System.out.print("Password: ");
      String password = teclado.nextLine();

      Administrador admin = new Administrador(nombre, password);

      return administradores.contains(admin);
   }


Seguimos con la clase Clinica.
Tras validar acceso, invocas a una serie de métodos de los gestores de doctores, pacientes y citas:
nuevoDoctor(), modificarDoctor(), borrarPaciente(), etc...

¡¡Pero esos métodos en realidad no existen!! No han sido escritos, ni en sus respectivas clases ni en ningún sitio.
El único que existe es el de nuevoCita()

Citar
      if (validarAcceso()) {
         System.out.println("\nUsuario autorizado\n");
         if (validarAcceso()) {
            System.out.println("\nUsuario autorizado\n");
            doctores.nuevoDoctor();
            doctores.modificarDoctor();
            doctores.mostrarDoctores();
            pacientes.nuevoPaciente();
            pacientes.mostrarPacientes();
            pacientes.modificarPaciente();
            pacientes.borrarPaciente();
            citas.nuevoCita();//Este es el único método que existe
            citas.mostrarCitas();
         }

No puedes iniciar el programa si estás invocando métodos que no han sido escritos.

Lo mismo ocurre en la clase GestorCita, se están llamando a métodos que no existen:
Citar
        //Pedimos los datos a los gestores que tenemos referenciados
        Doctor doctor = doctores.getDoctor(iDdoctor);
        Paciente paciente = pacientes.getPaciente(iDpaciente);

En la clase GestorDoctor, se nombra a un objeto llamado "doctores", que no existe.
Citar
            //Datos del último Doctor registrado
            int ultimo = doctores.size() - 1;
            escritor.append(doctores.get(ultimo).generaLineaCSV());//Insertamos linea CSV

Supongo que eso tendría que ser un ArrayList<Doctor>, atributo de la clase GestorDoctor, pero no ha sido declarado.


En la clase GestorPacientes, sí que se ha declarado el ArrayList<Paciente>
Citar
public final class GestorPacientes {

    private ArrayList<Paciente> pacientes;

Pero luego, más abajo, supongo que por un error al copiar/pegar código, se llama a un objeto "doctores", en lugar de llamar al objeto "pacientes"
Además la cabecera del archivo CSV parece propia de los "doctores", no de "pacientes" como debería ser en este caso:

Citar
            FileWriter escritor = new FileWriter(archivo, true);
            //Cabecera para datos del CSV, solo si es la primera vez
            if (primeraVez)
                escritor.append("#ID;Nombre;Apellidos;Especialidad\n");

            //Datos del último Doctor registrado
            int ultimo = doctores.size() - 1;
            escritor.append(doctores.get(ultimo).generaLineaCSV());
//Insertamos linea CSV


Corrige todos estos errores y añade los métodos que faltan.
Solo entonces podrás poner en marcha el programa y así seguir depurándolo.

Un saludo.

336
Comunidad / Re: Presentación
« en: 12 de Octubre 2021, 13:23 »
Hola Paula y bienvenida.

Espero que te animes a compartir, aprender y enseñar aquí en el foro.

Un saludo.

337
Buff.. Interesante pero complicado.

Tengo una duda. Si tengo una fila de por ejemplo dos piezas redondas y dos cuadradas, pero las cuatro son claras... ¿sería una combinación ganadora?

Es decir, ¿basta con que coincidan todas en una sola característica?


En ese caso podemos crear una clase Pieza donde cada característica sea un atributo.

En ese enunciado se mencionan 8 características, pero en realidad serían solo 4 porque son características opuestas.
Una pieza o es redonda, o es cuadrada, no puede ser ambas cosas a la vez.
O es grande, o es pequeña.
O es clara, o es oscura.
etc...

Así que la clase Pieza, para comenzar, solo tendría 4 atributos que pueden ser de tipo boolean.
Código: [Seleccionar]
public class Pieza {

public boolean esClara;
public boolean esGrande;
public boolean esRedonda;
public boolean esHueca;

public Pieza(boolean esClara, boolean esGrande, boolean esRedonda, boolean esHueca) {
this.esClara = esClara;
this.esGrande = esGrande;
this.esRedonda = esRedonda;
this.esHueca = esHueca;
}

}

Si por ejemplo el atributo esClara tiene valor true, pues que la pieza es clara. Si tiene valor false, es que es oscura.
Es muy simple, no tiene mayor misterio.

Ahora hay que pensar en como modelar una combinación de 4 piezas, y poder discernir si es una combinación GANADORA o no.
Será GANADORA si todas las piezas coinciden en al menos uno de esos cuatro atributos.

Podemos hacer una clase llamada Combinacion con un array de 4 piezas.
Este array lo recibe por el constructor. Luego según la necesidades del programa, se puede hacer que las piezas se reciban por algún setter, eso ya verás tú lo que necesites..

Una vez tenemos ese array, podemos hacer distintos métodos, uno por cada atributo, que se encarguen de comprobar si las piezas coinciden en ese atributo en concreto.
Serán métodos boolean, que devolverán true si todas coinciden en su atributo o false si no es así.

Un último método comprobará si alguno de estos métodos devuelve true, lo cuál significará que la combinación es GANADORA.

A esta clase le pongo un main() para poder testear combinaciones de piezas a a ver si funciona bien la clase:
Código: [Seleccionar]
public class Combinacion {

private Pieza[] piezas;

public Combinacion(Pieza[] piezas) {
this.piezas = piezas;
}

/**
* Indica si esta combinación de piezas es <u>Ganadora</u>.<br>
* Una combinación es <u>Ganadora</u> si todas las piezas tiene al menos
* una característica en común.
* @return <i>True</i> si es Ganadora, <i>False</i> en caso contrario.
*/
public boolean esGanadora() {
return compruebaPrimerAtrib() || compruebaSegundoAtrib()
|| compruebaTercerAtrib() || compruebaCuartoAtrib();
}

/**
* Comprueba si todas las piezas coinciden en el primer
* atributo, es decir, si todas son <b>CLARAS</b> o
* si todas son <b>OSCURAS</b>.
* @return <i>True</i> si todas coinciden en el primer
* atributo, <i>False</i> en caso contrario.
*/
private boolean compruebaPrimerAtrib() {
//La primera pieza establece el valor con el que debemos comparar.
boolean primera = piezas[0].esClara;
//Recorremos resto de piezas
for (int i = 1; i < piezas.length; i++)
if (piezas[i].esClara != primera)
return false; //Hemos encontrado una diferencia, retornamos false

/*
* Si el bucle FOR termina sin haber retornado false, es que
* todas las piezas coinciden en el primer atributo.
* Por tanto, retornamos true.
*/
return true;
}

/**
* Comprueba si todas las piezas coinciden en el segundo
* atributo, es decir, si todas son <b>GRANDES</b> o
* si todas son <b>PEQUEÑAS</b>.
* @return <i>True</i> si todas coinciden en el segundo
* atributo, <i>False</i> en caso contrario.
*/
private boolean compruebaSegundoAtrib() {

boolean primera = piezas[0].esGrande;

for (int i = 1; i < piezas.length; i++)
if (piezas[i].esGrande != primera)
return false;

return true;
}

/**
* Comprueba si todas las piezas coinciden en el tercer
* atributo, es decir, si todas son <b>REDONDAS</b> o
* si todas son <b>CUADRADAS</b>.
* @return <i>True</i> si todas coinciden en el tercer
* atributo, <i>False</i> en caso contrario.
*/
private boolean compruebaTercerAtrib() {

boolean primera = piezas[0].esRedonda;

for (int i = 1; i < piezas.length; i++)
if (piezas[i].esRedonda != primera)
return false;

return true;
}

/**
* Comprueba si todas las piezas coinciden en el cuarto
* atributo, es decir, si todas son <b>HUECAS</b> o
* si todas son <b>RELLENAS</b>.
* @return <i>True</i> si todas coinciden en el cuarto
* atributo, <i>False</i> en caso contrario.
*/
private boolean compruebaCuartoAtrib() {

boolean primera = piezas[0].esHueca;

for (int i = 1; i < piezas.length; i++)
if (piezas[i].esHueca != primera)
return false;

return true;
}

//Para testear combinaciones
public static void main(String[] args) {
//Array de piezas
Pieza[] pzs = new Pieza[4];
pzs[0] = new Pieza(true, false, false, true);
pzs[1] = new Pieza(false, false, false, true);
pzs[2] = new Pieza(true, true, false, true);
pzs[3] = new Pieza(true, false, true, false);

Combinacion combi = new Combinacion(pzs);

System.out.println(combi.esGanadora()?"Ganadora":"No ganadora");

}

}

En ese main he creado una combinación que NO es GANADORA, y así lo detecta el programa.

Si probamos a cambiarla por esta otra, donde todas son HUECAS, entonces sí declara la combinación como GANADORA:
Código: [Seleccionar]
Pieza[] pzs = new Pieza[4];
pzs[0] = new Pieza(true, false, false, true);
pzs[1] = new Pieza(false, false, false, true);
pzs[2] = new Pieza(true, true, false, true);
pzs[3] = new Pieza(true, false, true, true);


Creo que así hemos encontrado una forma de comparar piezas para decidir si una combinación de 4 de ellas, es ganadora.

Esto sería a nivel de "Modelo", es decir, modelando objetos que no se ven en pantalla.

Ya tendrás que adaptarlo a lo que tu estés haciendo a nivel de "Vista". No se como estarás representando las piezas en pantalla, aunque no importa demasiado, esta parte del "Modelo" vendría a ser igual.

338
Hola EmethP.

Échale un ojo a este tema del año pasado donde con otro forero resolvimos exactamente el mismo ejercicio que propones.

Mira a ver si te resulta útil, si hay cosas que prefieres cambiar, si hay cosas que no entiendes del todo..., sea lo que sea, consúltalo y lo vemos.

Un saludo.

339
El método cuentaVocales(), lo has definido indicando que va a recibir una cadena por parámetros:

Citar
public  void cuentaVocales(String cadena){
      int vocal = 0;
      String vol;
     
      for(int i=0; i<cadena.length();  i++){

Pero luego al invocarlo no le pasas ninguna cadena:
Código: [Seleccionar]
objc.cuentaVocales();
Y no es necesario pasársela, porque la clase ya tiene un atributo llamado cadena:
Citar
public class Contador{
String cadena;

Pero como a ese método le has dicho que recibirá un String, pues es lo que está esperando.
Has de cambiar su definición, dejando el paréntesis vacío, para que sepa que no va a recibir ninguna cadena, si no que ha de trabajar con la que se ha declarado como atributo de clase.
Citar
public  void cuentaVocales(String cadena){

Sin embargo, aún veo dos errores más que conviene corregir.

En ese método cuentaVocales(), usas un String llamado vol para, aparentemente, guardar un mensaje con el resultado del conteo de vocales.
Pero luego ese String no se retorna, ni se muestra en pantalla, ni nada.
Así que no sirve para nada, ni tendrá ningún impacto en pantalla. El conteo se hará, pero no se verá ningún resultado.

No necesitas ningún String, simplemente hay que contar vocales y al terminar lanzar el mensaje a la pantalla con un println().

Citar
   public  void cuentaVocales(){
      int vocal = 0;
     
      for(int i=0; i<cadena.length();  i++){
         
         if((cadena.charAt(i) == 'a') || (cadena.charAt(i) == 'A') ||
           (cadena.charAt(i) == 'e') || (cadena.charAt(i) == 'E') ||
           (cadena.charAt(i) == 'i') || (cadena.charAt(i) == 'I') ||
           (cadena.charAt(i) == 'o') || (cadena.charAt(i) == 'O') ||
           (cadena.charAt(i) == 'u') || (cadena.charAt(i) == 'U') ){
           vocal++;

           }
     
      }
          System.out.println("La cadena tiene: " + vocal + " vocales");   
         
   }


Bien, con esto parece que el método cuentaVocales() ya estaría listo para cumplir con lo que esperamos. Pero me temo que no va conseguir dar buenos resultados.

Y esto se debe a un error en el otro método, en leerCadena().
Este método debería leer una cadena por teclado y guardarla en el String declarado como atributo de clase.
Pero dentro del método, has declarado otro String con el mismo nombre que el atributo.

Citar
   public void leerCadena(){   
      String cadena;
      int longitudCadena;
     


Por consiguiente, el método NO trabajará con el atributo, si no con este otro String.
Y esto implica que cuando el método cuentaVocales() quiera cumplir con su cometido, se va a encontrar con que el atributo String cadena, no tiene ningún valor. Porque la cadena leída por teclado no se ha guardado en este atributo.

Así que hay que eliminar esa declaración del String que está dentro del método. De este modo, se trabajará con el atributo de clase, que es lo que necesitamos.
Citar
   public void leerCadena(){   
      String cadena;
      int longitudCadena;
     
      Scanner sc = new Scanner(System.in);
      System.out.println("Ingrese cualquier cadena para contar sus vocales");
      cadena= sc.nextLine();
      longitudCadena = cadena.length();
       System.out.println("La cadena tiene: " + longitudCadena + " caracteres");   
      }

Por cierto, aunque en este ejercicio creo que no es estrictamente necesario, no estaría de más incluir un constructor de clase.
Siempre que una clase tenga atributos (o sea, casi siempre), es conveniente crear un constructor para dar un valor inicial a dichos atributos.

Citar
import java.util.Scanner;
public class Contador{
String cadena;

   //Constructor de clase
   public Contador() {
      cadena = ""; //Inicializamos con una cadena vacía
   }

   
   public void leerCadena(){   
      String cadena;
      int longitudCadena;
     
      Scanner sc = new Scanner(System.in);
      System.out.println("Ingrese cualquier cadena para contar sus vocales");
      cadena= sc.nextLine();
      longitudCadena = cadena.length();
       System.out.println("La cadena tiene: " + longitudCadena + " caracteres");   
      }

De esta manera, nos aseguramos de que los atributos no se quedan con valores nulos (null).

En tu ejercicio, en principio no pasaría nada, porque primero llamas al método de leerCadena(), que ya se encarga de dar un valor a la cadena y deja de ser null

Pero supón que alguien escribe su propio programa usando tu clase, y ofrece un menú de opciones donde el usuario puede elegir llamar al método de cuentaVocales() sin haber leído ninguna cadena previamente.

Si no le damos un valor inicial al atributo "cadena", el método de contar vocales intentará contar vocales en un atributo con valor null, lo cuál producirá una excepción (un error) y el programa romperá su ejecución.

En cambio, si nos aseguramos de dar un valor inicial en el constructor, ya no tendremos valores null y el programa no se romperá si se intenta contar vocales sin haber leído una cadena.
Simplemente obtendremos el mensaje de que la cadena tiene 0 vocales, lo cuál sería correcto ya que aún no se ha leído ninguna cadena.


Realizar todos estos cambios y prueba ahora a ver si funciona bien.
Si alguna explicación no te ha quedado clara, solo tienes que volver a preguntar.
Un saludo.

340
Hola
Lo primero es crear una clase Fibonacci, pensando que atributo podemos necesitar.

Una sucesión de números (Fibonacci o no...) tiene una longitud, es decir, la cantidad de números que van a componer esa sucesión.
Así que se podría ser su atributo.

Luego, obviamente, uno de sus métodos será un código para calcular los valores de la sucesión.
Hay una forma de hacerlo mediante una función recursiva que recibe una posición de la sucesión y devuelve el valor que corresponde.

Así luego en otro método con un bucle for que se repita tantas veces como indica la longitud, nos dará cada valor correspondiente a cada posición de la sucesión y la podremos mostrar en pantalla.

Esta podría ser la clase Fibonacci:
Código: [Seleccionar]
public class Fibonacci {

private int longitud;

public Fibonacci(int longitud) {
this.longitud = longitud;
}

public int getLongitud() {
return longitud;
}

public void setLongitud(int longitud) {
this.longitud = longitud;
}

public void mostrarSucesion() {
System.out.println("\nSucesión de longitud "+ longitud +":");
for (int i = 0; i < longitud; i++) {
System.out.print(fibonacci(i) + " ");
}
}

/*
* Función recursiva para calcular el valor correspondiente
* según la posición indicada
*
*/
private int fibonacci(int posicion) {

if (posicion > 1)
return fibonacci(posicion-1) + fibonacci(posicion-2);
else if (posicion == 1)
return 1;
else if (posicion == 0)
return 0;
else {
System.out.println("ERROR: Posición no puede ser valor negativo");
return -1;
}
}

}

Luego en otra clase con método main(), podemos declarar un objeto de la clase Fibonacci y con un pequeño menú dar opción de mostrar la sucesión y de cambiar el valor de la longitud.
Algo como esto:
Código: [Seleccionar]
public class PruebaFibonacci {

public static void main(String[] args) {

Scanner teclado = new Scanner(System.in);
Fibonacci fibo = new Fibonacci(10);
int seleccion = 0;

while (seleccion != 3) {
System.out.println("\n\n\t\tSUCESION FIBONACCI");
System.out.println("\t\t-------- ---------");
System.out.println("Longitud actual: " + fibo.getLongitud());
System.out.println("\n[1] -- Mostrar sucesión");
System.out.println("[2] -- Cambiar longitud");
System.out.println("[3] -- SALIR");
System.out.print("Elija opción: ");
seleccion = teclado.nextInt();

switch(seleccion) {
case 1:
fibo.mostrarSucesion();
break;
case 2:
System.out.print("\nNueva longitud: ");
fibo.setLongitud(teclado.nextInt());
break;
case 3:
System.out.println("\n\t\tFIN DE PROGRAMA");
break;
default:
System.out.println("\nOpción equivocada");
}
}

teclado.close();

}

}

Si lo probamos, en pantalla tenemos este resultado:
Citar

      SUCESION FIBONACCI
      -------- ---------
Longitud actual: 10

[1] -- Mostrar sucesión
[2] -- Cambiar longitud
[3] -- SALIR
Elija opción: 1

Sucesión de longitud 10:
0 1 1 2 3 5 8 13 21 34

      SUCESION FIBONACCI
      -------- ---------
Longitud actual: 10

[1] -- Mostrar sucesión
[2] -- Cambiar longitud
[3] -- SALIR
Elija opción: 2

Nueva longitud: 30


      SUCESION FIBONACCI
      -------- ---------
Longitud actual: 30

[1] -- Mostrar sucesión
[2] -- Cambiar longitud
[3] -- SALIR
Elija opción: 1

Sucesión de longitud 30:
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 121393 196418 317811 514229

      SUCESION FIBONACCI
      -------- ---------
Longitud actual: 30

[1] -- Mostrar sucesión
[2] -- Cambiar longitud
[3] -- SALIR
Elija opción: 3

      FIN DE PROGRAMA

Páginas: 1 ... 12 13 14 15 16 [17] 18 19 20 21 22 ... 50

Sobre la educación, sólo puedo decir que es el tema más importante en el que nosotros, como pueblo, debemos involucrarnos.

Abraham Lincoln (1808-1865) Presidente estadounidense.

aprenderaprogramar.com: Desde 2006 comprometidos con la didáctica y divulgación de la programación

Preguntas y respuestas

¿Cómo establecer o cambiar la imagen asociada (avatar) de usuario?
  1. Inicia sesión con tu nombre de usuario y contraseña.
  2. Pulsa en perfil --> perfil del foro
  3. Elige la imagen personalizada que quieras usar. Puedes escogerla de una galería de imágenes o subirla desde tu ordenador.
  4. En la parte final de la página pulsa el botón "cambiar perfil".