/**
* Representa una nave espacial dentro del universo de The Expanse.
*
* Conceptos que se trabajan aquí:
* - Encapsulamiento (atributos privados + getters/setters)
* - Constructor completo
* - toString() para imprimir bonito el objeto
*/
public class Nave {
// -------------------------
// Atributos (siempre privados)
// -------------------------
private String nombre;
private String faccion; // "Tierra", "Marte", "Cinturon"
private int misiles;
private boolean necesitaReparacion;
// -------------------------
// Constructores
// -------------------------
/**
* Constructor completo exigido por el enunciado.
*/
public Nave(String nombre, String faccion, int misiles, boolean necesitaReparacion) {
this.nombre = nombre;
this.faccion = faccion;
this.misiles = misiles;
this.necesitaReparacion = necesitaReparacion;
}
/**
* Constructor opcional de conveniencia (por si quieres crear naves “rápido”).
* Por ejemplo: misiles = 0 y no necesita reparación por defecto.
*/
public Nave(String nombre, String faccion) {
this(nombre, faccion, 0, false);
}
// -------------------------
// Getters y Setters
// -------------------------
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public String getFaccion() {
return faccion;
}
public void setFaccion(String faccion) {
this.faccion = faccion;
}
public int getMisiles() {
return misiles;
}
public void setMisiles(int misiles) {
this.misiles = misiles;
}
public boolean isNecesitaReparacion() {
return necesitaReparacion;
}
public void setNecesitaReparacion(boolean necesitaReparacion) {
this.necesitaReparacion = necesitaReparacion;
}
// -------------------------
// toString() (muy útil para listar)
// -------------------------
@Override
public String toString() {
return "Nave{" +
"nombre='" + nombre + '\'' +
", faccion='" + faccion + '\'' +
", misiles=" + misiles +
", necesitaReparacion=" + (necesitaReparacion ? "Sí" : "No") +
'}';
}
}
2) Flota.java
import java.util.ArrayList;
import java.util.Scanner;
/**
* Flota = conjunto de naves.
*
* Conceptos que se trabajan:
* - ArrayList con objetos (ArrayList<Nave>)
* - Métodos para recorrer y filtrar
* - Métodos con Scanner para crear objetos desde teclado
*/
public class Flota {
// Lista privada: nadie fuera debería tocarla directamente
private ArrayList<Nave> naves;
// -------------------------
// Constructor
// -------------------------
public Flota() {
// Inicializamos la lista vacía (obligatorio)
this.naves = new ArrayList<>();
}
// -------------------------
// Agregar nave ya creada
// -------------------------
public void agregarNave(Nave nave) {
if (nave == null) {
System.out.println("No se puede añadir una nave nula.");
return;
}
naves.add(nave);
System.out.println("✅ Nave añadida a la flota: " + nave.getNombre());
}
// -------------------------
// Crear nave por teclado
// -------------------------
public void crearNaveDesdeTeclado(Scanner sc) {
System.out.println("=== CREAR NUEVA NAVE ===");
// Nombre
System.out.print("Nombre de la nave: ");
String nombre = sc.nextLine().trim();
// Facción (validada)
String faccion = leerFaccionValida(sc);
// Misiles (entero >= 0)
int misiles = leerEnteroNoNegativo(sc, "Número de misiles: ");
// Reparación (S/N)
boolean necesitaReparacion = leerBooleanSN(sc, "¿Necesita reparación? (S/N): ");
// Creamos el objeto Nave con los datos recogidos
Nave nave = new Nave(nombre, faccion, misiles, necesitaReparacion);
// La añadimos al ArrayList
naves.add(nave);
System.out.println("✅ Nave creada y añadida: " + nave);
}
// -------------------------
// Número de naves
// -------------------------
public int getNumeroNaves() {
return naves.size();
}
// -------------------------
// Listar todas
// -------------------------
public void listarTodas() {
System.out.println("=== LISTADO COMPLETO DE NAVES ===");
if (naves.isEmpty()) {
System.out.println("La flota está vacía.");
return;
}
for (Nave n : naves) {
System.out.println(n); // llama a toString()
}
}
// -------------------------
// Listar naves para reparar
// -------------------------
public void listarNavesParaReparar() {
System.out.println("=== NAVES QUE NECESITAN REPARACIÓN ===");
boolean hay = false;
for (Nave n : naves) {
if (n.isNecesitaReparacion()) {
System.out.println(n);
hay = true;
}
}
if (!hay) {
System.out.println("No hay naves marcadas para reparación.");
}
}
// -------------------------
// Total de misiles
// -------------------------
public int getTotalMisiles() {
int total = 0;
for (Nave n : naves) {
total += n.getMisiles();
}
return total;
}
// -------------------------
// Listar por facción
// -------------------------
public void listarPorFaccion(String faccion) {
System.out.println("=== NAVES DE LA FACCIÓN: " + faccion + " ===");
boolean hay = false;
for (Nave n : naves) {
// equalsIgnoreCase = compara ignorando mayúsculas/minúsculas
if (n.getFaccion().equalsIgnoreCase(faccion)) {
System.out.println(n);
hay = true;
}
}
if (!hay) {
System.out.println("No se encontraron naves de esa facción.");
}
}
// -------------------------
// Contar por facción
// -------------------------
public int contarPorFaccion(String faccion) {
int contador = 0;
for (Nave n : naves) {
if (n.getFaccion().equalsIgnoreCase(faccion)) {
contador++;
}
}
return contador;
}
// ==========================================================
// Métodos auxiliares (para que el código quede limpio y robusto)
// ==========================================================
/**
* Pide al usuario una facción válida: Tierra / Marte / Cinturon.
*/
private String leerFaccionValida(Scanner sc) {
while (true) {
System.out.print("Facción (Tierra/Marte/Cinturon): ");
String faccion = sc.nextLine().trim();
if (esFaccionValida(faccion)) {
// Normalizamos para que quede bonito y consistente
return normalizarFaccion(faccion);
}
System.out.println("❌ Facción no válida. Usa: Tierra, Marte o Cinturon.");
}
}
private boolean esFaccionValida(String faccion) {
String f = faccion.trim().toLowerCase();
return f.equals("tierra") || f.equals("marte") || f.equals("cinturon");
}
private String normalizarFaccion(String faccion) {
String f = faccion.trim().toLowerCase();
if (f.equals("tierra")) return "Tierra";
if (f.equals("marte")) return "Marte";
return "Cinturon";
}
/**
* Lee un entero >= 0, repitiendo hasta que sea válido.
*/
private int leerEnteroNoNegativo(Scanner sc, String mensaje) {
while (true) {
System.out.print(mensaje);
String linea = sc.nextLine().trim();
try {
int valor = Integer.parseInt(linea);
if (valor < 0) {
System.out.println("❌ No puede ser negativo.");
} else {
return valor;
}
} catch (NumberFormatException e) {
System.out.println("❌ Introduce un número entero válido.");
}
}
}
/**
* Lee una respuesta tipo S/N y la convierte a boolean.
* S -> true, N -> false
*/
private boolean leerBooleanSN(Scanner sc, String mensaje) {
while (true) {
System.out.print(mensaje);
String resp = sc.nextLine().trim().toLowerCase();
if (resp.equals("s") || resp.equals("si") || resp.equals("sí")) return true;
if (resp.equals("n") || resp.equals("no")) return false;
System.out.println("❌ Respuesta no válida. Escribe S o N.");
}
}
}
3) ControlFlota.java (main + menú)
import java.util.Scanner;
/**
* Controlador principal.
*
* Conceptos que se trabajan:
* - Menú por consola repetitivo (do-while)
* - switch para ejecutar opciones
* - Reutilización de Scanner y validación de enteros
*/
public class ControlFlota {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Flota flota = new Flota();
// Naves iniciales opcionales (ambiente The Expanse)
flota.agregarNave(new Nave("Rocinante", "Cinturon", 24, false));
flota.agregarNave(new Nave("Donnager", "Marte", 60, true));
flota.agregarNave(new Nave("Agatha King", "Tierra", 40, true));
int opcion;
do {
mostrarMenu();
opcion = leerEnteroSeguro(sc);
switch (opcion) {
case 1:
// Crear nave desde teclado
flota.crearNaveDesdeTeclado(sc);
break;
case 2:
// Crear nave desde el main (valores fijos)
Nave n = new Nave("Nauvoo", "Cinturon", 80, false);
flota.agregarNave(n);
System.out.println("Nave creada desde main y añadida: " + n);
break;
case 3:
flota.listarTodas();
break;
case 4:
flota.listarNavesParaReparar();
break;
case 5:
System.out.println("Número total de naves: " + flota.getNumeroNaves());
break;
case 6:
System.out.println("Misiles totales en la flota: " + flota.getTotalMisiles());
break;
case 7:
System.out.print("Introduce la facción (Tierra/Marte/Cinturon): ");
String fac = sc.nextLine().trim();
flota.listarPorFaccion(fac);
break;
case 8:
System.out.print("Introduce la facción (Tierra/Marte/Cinturon): ");
String fac2 = sc.nextLine().trim();
int num = flota.contarPorFaccion(fac2);
System.out.println("Número de naves de la facción " + fac2 + ": " + num);
break;
case 0:
System.out.println("Saliendo del sistema de control de flota...");
break;
default:
System.out.println("Opción no válida.");
}
System.out.println(); // línea en blanco para separar “vueltas” del menú
} while (opcion != 0);
sc.close();
}
// -------------------------
// Menú
// -------------------------
private static void mostrarMenu() {
System.out.println("=== CONTROL DE FLOTA - GUERRA DEL SISTEMA SOLAR ===");
System.out.println("1. Añadir nave (datos por teclado)");
System.out.println("2. Añadir nave (creada en el main)");
System.out.println("3. Listar todas las naves");
System.out.println("4. Listar naves que necesitan reparación");
System.out.println("5. Mostrar número total de naves");
System.out.println("6. Mostrar número total de misiles");
System.out.println("7. Listar naves por facción");
System.out.println("8. Contar naves por facción");
System.out.println("0. Salir");
System.out.print("Elige una opción: ");
}
/**
* Lee un entero de forma segura usando nextLine() + parseInt.
* Ventaja: evita problemas típicos de Scanner con nextInt() y saltos de línea.
*/
private static int leerEnteroSeguro(Scanner sc) {
while (true) {
try {
return Integer.parseInt(sc.nextLine().trim());
} catch (NumberFormatException e) {
System.out.print("Introduce un número válido: ");
}
}
}
}