POO Gamer · Clases & Asociación
🎮 40 Desafíos · Ruta GuiadaDesafíos de POO Game — Asociación y Combate por Turnos
Aprende a modelar asociación y composición pura entre clases (sin herencia) con temática de videojuegos. Empieza por los 20 retos nuevos ordenados por dificultad: asociación de 2 clases (1–10),3 clases sin usar listas (11–15) y 4 clases (16–20); después salta a los20 combates por turnos 1v1 (21–40) con armas, escudos, habilidades y listas de ítems consumibles.
Ruta canónica: /challenges/poo-game · Módulos relacionados: /challenges/poo (clases básicas), /challenges/inheritance (herencia) y /challenges/interface (interfaces).
🗺️ Ruta de aprendizaje — elige un nivel para filtrar
- 🟢 Nivel 1 · Asociación básica10 retosUna clase principal asociada a una sola clase. Indicaciones de los métodos que puedes hacer.Desafíos 01 – 10
- 🟡 Nivel 2 · Asociación intermedia5 retosTres clases conectadas entre sí, resolviendo la relación con atributos de referencia (sin usar List).Desafíos 11 – 15
- 🟠 Nivel 3 · Asociación avanzada5 retosCuatro clases que forman un mini-motor de juego con cadena de asociaciones.Desafíos 16 – 20
- 🔴 Nivel 4 · Combate por turnos20 retosCombates 1v1 completos con armas, escudos, listas de ítems y simulaciones por turnos.Desafíos 21 – 40
40 desafíos · Selecciona o expande para ver el diagrama de asociación UML y probar la lógica:
011. Pac-Man y los puntos del laberinto
🕹️ Pac-Man (clásico de arcade)🟢 2 clasesClase Principal: Pacman · 2 clases en total · 1 conexiones (o-- / *--)0 / 4
1. Pac-Man y los puntos del laberinto
🕹️ Pac-Man (clásico de arcade)🟢 2 clasesPac-Man recorre el laberinto celda a celda. Cada celda puede contener un punto con un valor de 10 puntos. Cuando Pac-Man pisa un punto, se lo come y suma su valor a su marcador; si vuelve a pasar por la misma celda, el punto ya no vale nada.
🎯 Misión POO: Crea la clase Punto (el objeto que está en el mapa) y la clase Pacman (el personaje). En el constructor de Pacman NO crees el punto: lo recibes como argumento en comer(punto). Completa todos los métodos del diagrama y prueba en Main que solo puede comer el punto que tiene debajo.
💡 Métodos que puedes implementar
Punto.estaComido(): devuelve true si el punto ya fue recolectadoPunto.comer(): cambia el punto a comido = truePunto.coincide(fila, columna): compara la posición del punto con la del personajePacman.mover(fila, columna, direccion): actualiza la posición actualPacman.estaEnPunto(punto): devuelve true si comparte celda con un punto sin comerPacman.comer(punto): si está encima del punto, lo marca como comido y suma el valor
💡 Simulación Java Completa:Pacman (Asociación básica)
Código Java funcional listo para compilar y ejecutar con la simulación en consola:
class Punto {
private int fila;
private int columna;
private int valor;
private boolean comido;
public Punto(int fila, int columna, int valor) {
this.fila = fila;
this.columna = columna;
this.valor = valor;
this.comido = false;
}
public void comer() {
this.comido = true;
}
public boolean estaComido() {
return this.comido;
}
public boolean coincide(int fila, int columna) {
return this.fila == fila && this.columna == columna;
}
public String getPosicion() {
return "(" + fila + "," + columna + ")";
}
public int getValor() {
return valor;
}
}
class Pacman {
private String nombre;
private int fila;
private int columna;
private String direccion;
private int puntosComidos;
private int marcador;
public Pacman(String nombre, int fila, int columna, String direccion) {
this.nombre = nombre;
this.fila = fila;
this.columna = columna;
this.direccion = direccion;
this.puntosComidos = 0;
this.marcador = 0;
}
public void mover(int nuevaFila, int nuevaColumna, String nuevaDireccion) {
this.fila = nuevaFila;
this.columna = nuevaColumna;
this.direccion = nuevaDireccion;
System.out.println("🕹️ " + nombre + " se mueve " + nuevaDireccion + " hasta la celda " + nuevaFila + "," + nuevaColumna);
}
public boolean estaEnPunto(Punto punto) {
return !punto.estaComido() && punto.coincide(this.fila, this.columna);
}
public void comer(Punto punto) {
if (estaEnPunto(punto)) {
punto.comer();
this.puntosComidos++;
this.marcador += punto.getValor();
System.out.println("😋 " + nombre + " come el punto de " + punto.getPosicion() + " (+" + punto.getValor() + ")");
} else {
System.out.println(nombre + " está en " + this.fila + "," + this.columna + " y ese punto ya no está disponible.");
}
}
public void mostrarEstado() {
System.out.println(nombre + " -> " + direccion + " | puntos comidos: " + puntosComidos + " | marcador: " + marcador);
}
public String getNombre() {
return nombre;
}
}
public class Main {
public static void main(String[] args) {
Punto puntoRojo = new Punto(3, 4, 10);
Punto puntoAzul = new Punto(3, 5, 20);
Pacman pacman = new Pacman("Pac-Man", 3, 3, "DERECHA");
pacman.mostrarEstado();
pacman.mover(3, 4, "DERECHA");
pacman.comer(puntoRojo);
pacman.comer(puntoRojo);
pacman.mover(3, 5, "DERECHA");
pacman.comer(puntoAzul);
pacman.mostrarEstado();
}
}022. La pieza de Tetris que cae en el tablero
🧱 Tetris (clásico de bloques)🟢 2 clasesClase Principal: Tablero · 2 clases en total · 1 conexiones (o-- / *--)0 / 4
2. La pieza de Tetris que cae en el tablero
🧱 Tetris (clásico de bloques)🟢 2 clasesEn Tetris el tablero tiene filas y columnas fijas y en todo momento hay una sola pieza activa cayendo. Cuando la pieza deja de bajar, se completa una línea y el tablero genera una pieza nueva automáticamente.
🎯 Misión POO: Crea la clase Pieza y la clase Tablero. Esta vez la relación es de COMPOSICIÓN: el Tablero crea la Pieza en su propio constructor (new Pieza(...)), por lo que nunca se le pasa una pieza desde afuera. Implementa soltarPieza() para que el tablero genere una pieza nueva cuando la anterior queda quieta.
💡 Métodos que puedes implementar
Pieza.moverAbajo(filasMaximas): baja una fila y devuelve false si toca el límitePieza.moverIzquierda() / moverDerecha(): desplazan la pieza y devuelven si sigue dentro del tableroPieza.estaQuieta(): true cuando la pieza ya no puede bajar másTablero.cabe(pieza): pregunta si la pieza sigue dentro de los límites del tableroTablero.soltarPieza(): si la pieza está quieta, cuenta la línea y genera una pieza nueva
💡 Simulación Java Completa:Tablero (Asociación básica)
Código Java funcional listo para compilar y ejecutar con la simulación en consola:
class Pieza {
private String forma;
private int fila;
private int columna;
private boolean quieta;
public Pieza(String forma, int fila, int columna) {
this.forma = forma;
this.fila = fila;
this.columna = columna;
this.quieta = false;
}
public boolean moverAbajo(int filasTablero) {
if (this.fila + 1 >= filasTablero) {
this.quieta = true;
return false;
}
this.fila++;
return true;
}
public void moverIzquierda() {
if (this.columna > 0) {
this.columna--;
}
}
public void moverDerecha() {
this.columna++;
}
public boolean estaQuieta() {
return this.quieta;
}
public String getPosicion() {
return forma + " en (" + fila + "," + columna + ")";
}
public int getColumna() {
return columna;
}
public int getFila() {
return fila;
}
}
class Tablero {
private int filas;
private int columnas;
private Pieza piezaActiva;
private int lineasCompletadas;
// Composicion: el tablero crea su propia pieza, no la recibe.
public Tablero(int filas, int columnas) {
this.filas = filas;
this.columnas = columnas;
this.lineasCompletadas = 0;
this.piezaActiva = new Pieza("T", 0, 3);
}
public boolean cabe(Pieza pieza) {
return pieza.getColumna() >= 0 && pieza.getColumna() < this.columnas && pieza.getFila() < this.filas;
}
public void soltarPieza() {
if (piezaActiva.estaQuieta()) {
lineasCompletadas++;
System.out.println("🧱 Línea completada por la pieza " + piezaActiva.getPosicion());
piezaActiva = new Pieza("L", 0, 2);
}
}
public void mostrar() {
System.out.println("Tablero " + filas + "x" + columnas + " | líneas: " + lineasCompletadas + " | activa: " + piezaActiva.getPosicion());
}
}
public class Main {
public static void main(String[] args) {
Tablero tablero = new Tablero(20, 10);
tablero.mostrar();
for (int i = 0; i < 19; i++) {
tablero.soltarPieza();
}
tablero.soltarPieza();
tablero.mostrar();
}
}033. La rana que cruza los carriles
🐸 Frogger (clásico de arcade)🟢 2 clasesClase Principal: Rana · 2 clases en total · 1 conexiones (o-- / *--)0 / 4
3. La rana que cruza los carriles
🐸 Frogger (clásico de arcade)🟢 2 clasesFrogger es una rana que debe cruzar la calle. Cada carril tiene su propio coche que avanza a una velocidad distinta. Si el coche de ese carril alcanza la columna donde está la rana, pierde una vida.
🎯 Misión POO: Crea la clase Coche (un carril) y la clase Rana (el jugador). La rana recibe el coche como argumento en saltar(coche), no como atributo: la asociación se resuelve por parámetro. Implementa avanzar(), saltar() y estaViva().
💡 Métodos que puedes implementar
Coche.avanzar(): suma la velocidad a la columna y vuelve a 0 al salir de la pantallaCoche.estaEn(columna): true si el coche sigue activo y ocupa esa columnaCoche.frenar(): desactiva el coche (coche parado en el semáforo)Rana.avanzar(): sube un carril y suma puntos, hasta un máximoRana.saltar(coche): si el coche está en su columna pierde una vida, si no gana puntosRana.estaViva(): devuelve si todavía le quedan vidas
💡 Simulación Java Completa:Rana (Asociación básica)
Código Java funcional listo para compilar y ejecutar con la simulación en consola:
class Coche {
private String color;
private int carril;
private int columna;
private int velocidad;
private boolean activo;
public Coche(String color, int carril, int velocidad) {
this.color = color;
this.carril = carril;
this.columna = 0;
this.velocidad = velocidad;
this.activo = true;
}
public void avanzar() {
if (!activo) {
return;
}
this.columna += this.velocidad;
if (this.columna > 20) {
this.columna = 0;
}
}
public boolean estaEn(int columnaRana) {
return this.activo && this.columna == columnaRana;
}
public void frenar() {
this.activo = false;
}
public int getColumna() {
return columna;
}
public String getColor() {
return color + " (carril " + carril + ", col " + columna + ")";
}
}
class Rana {
private String nombre;
private int carril;
private int columna;
private int vidas;
private int puntos;
private int carrilMaximo;
public Rana(String nombre, int columna, int vidas, int carrilMaximo) {
this.nombre = nombre;
this.carril = 0;
this.columna = columna;
this.vidas = vidas;
this.puntos = 0;
this.carrilMaximo = carrilMaximo;
}
public void avanzar() {
if (this.carril < this.carrilMaximo) {
this.carril++;
this.puntos += 10;
}
}
public boolean saltar(Coche coche) {
if (coche.estaEn(this.columna)) {
this.vidas--;
System.out.println("💥 " + nombre + " fue atropellado por el " + coche.getColor() + ". Vidas: " + this.vidas);
return false;
}
this.puntos += 5;
System.out.println("🐸 " + nombre + " saltó el carril con éxito (+5)");
return true;
}
public boolean estaViva() {
return this.vidas > 0;
}
public void mostrarEstado() {
System.out.println(nombre + " | carril: " + this.carril + "/" + this.carrilMaximo + " | puntos: " + puntos + " | vidas: " + vidas);
}
}
public class Main {
public static void main(String[] args) {
Coche cocheRojo = new Coche("ROJO", 1, 3);
Coche cocheAzul = new Coche("AZUL", 2, 5);
Rana rana = new Rana("Rana Pepe", 10, 3, 5);
rana.mostrarEstado();
rana.avanzar();
cocheRojo.avanzar();
cocheRojo.avanzar();
cocheRojo.avanzar();
rana.saltar(cocheRojo);
cocheAzul.frenar();
rana.saltar(cocheAzul);
rana.mostrarEstado();
}
}044. El rebote de la pelota en Pong
🏓 Pong (clásico de arcade)🟢 2 clasesClase Principal: Jugador · 2 clases en total · 1 conexiones (o-- / *--)0 / 4
4. El rebote de la pelota en Pong
🏓 Pong (clásico de arcade)🟢 2 clasesEn Pong la pelota rebota en las paredes y en la pala del jugador. El jugador mueve su pala con una velocidad y marca un punto cada vez que la pelota pasa de largo su lado del campo.
🎯 Misión POO: Crea la clase Pelota (x, y, velocidadX, velocidadY, rebotes) y la clase Jugador (nombre, posicionY, puntos, velocidad). La pelota llama a los métodos del jugador para comprobar el rebote: así una clase trabaja con la otra sin conocerla por dentro. Prueba un saque y dos rebotes.
💡 Métodos que puedes implementar
Pelota.mover(anchoCampo, altoCampo): avanza según su velocidad e invierte la vertical en los bordesPelota.rebotarEnJugador(jugador, anchoCampo): invierte la velocidad horizontal y centra la pelota en la palaPelota.superaJugador(jugador, anchoCampo): true si la pelota ya pasó la zona de la palaJugador.mover(delta): sube o baja la pala sin salirse del campoJugador.cubre(pelota, anchoCampo): true si la pala está a la altura de la pelotaJugador.marcarPunto(): suma un punto y reinicia el saque
💡 Simulación Java Completa:Jugador (Asociación básica)
Código Java funcional listo para compilar y ejecutar con la simulación en consola:
class Pelota {
private double posicionX;
private double posicionY;
private double velocidadX;
private double velocidadY;
private int rebotes;
public Pelota(double posicionX, double posicionY, double velocidadX, double velocidadY) {
this.posicionX = posicionX;
this.posicionY = posicionY;
this.velocidadX = velocidadX;
this.velocidadY = velocidadY;
this.rebotes = 0;
}
public void mover(int anchoCampo, int altoCampo) {
this.posicionX += this.velocidadX;
this.posicionY += this.velocidadY;
if (this.posicionY <= 0 || this.posicionY >= altoCampo) {
this.velocidadY = -this.velocidadY;
this.rebotes++;
System.out.println("🟡 Rebote en el borde superior/inferior (rebote " + this.rebotes + ")");
}
if (this.posicionX <= 0 || this.posicionX >= anchoCampo) {
this.velocidadX = -this.velocidadX;
}
}
public void rebotarEnJugador(Jugador jugador, int anchoCampo) {
this.posicionX = anchoCampo - 1;
this.velocidadX = -Math.abs(this.velocidadX);
this.posicionY = jugador.getPosicionY();
this.rebotes++;
System.out.println("🏓 " + jugador.getNombre() + " devuelve la pelota (rebote " + this.rebotes + ")");
}
public boolean superaJugador(Jugador jugador, int anchoCampo) {
return this.posicionX <= 1 && jugador.getPosicionY() + 12 < this.posicionY - 12;
}
public double getPosicionY() {
return posicionY;
}
public double getPosicionX() {
return posicionX;
}
}
class Jugador {
private String nombre;
private int posicionY;
private int puntos;
private int velocidad;
private int alturaCampo;
public Jugador(String nombre, int posicionY, int velocidad, int alturaCampo) {
this.nombre = nombre;
this.posicionY = posicionY;
this.puntos = 0;
this.velocidad = velocidad;
this.alturaCampo = alturaCampo;
}
public void mover(int delta) {
int nuevaPosicion = this.posicionY + delta * this.velocidad;
if (nuevaPosicion < 0) {
nuevaPosicion = 0;
}
if (nuevaPosicion > this.alturaCampo - 40) {
nuevaPosicion = this.alturaCampo - 40;
}
this.posicionY = nuevaPosicion;
}
public boolean cubre(Pelota pelota, int anchoCampo) {
return Math.abs(pelota.getPosicionY() - this.posicionY) < 20 && pelota.getPosicionX() <= 2;
}
public void marcarPunto() {
this.puntos++;
System.out.println("🏆 Punto para " + this.nombre + ". Marcador: " + this.puntos);
}
public int getPosicionY() {
return posicionY;
}
public String getNombre() {
return nombre;
}
}
public class Main {
public static void main(String[] args) {
int anchoCampo = 60;
int altoCampo = 30;
Jugador jugador = new Jugador("Jugador 1", 15, 2, altoCampo);
Pelota pelota = new Pelota(5, 15, 3, 1);
for (int i = 0; i < 3; i++) {
pelota.mover(anchoCampo, altoCampo);
if (jugador.cubre(pelota, anchoCampo)) {
pelota.rebotarEnJugador(jugador, anchoCampo);
}
}
jugador.mover(1);
jugador.marcarPunto();
}
}055. La nave que dispara a los aliens
👾 Space Invaders (clásico de arcade)🟢 2 clasesClase Principal: Nave · 2 clases en total · 1 conexiones (o-- / *--)0 / 4
5. La nave que dispara a los aliens
👾 Space Invaders (clásico de arcade)🟢 2 clasesSpace Invaders tiene una nave que se desplaza de lado a lado y dispara proyectiles. Cada alien tiene un tipo, una posición y su propia vida, así que un mismo disparo puede destruir a un calamar pero solo rasguñar a un pulpo gigante.
🎯 Misión POO: Crea la clase Alien (tipo, posicionX, vida) y la clase Nave (nombre, posicionX, posicionY, puntos). Implementa disparar(alien) y recibirDisparo(danio). La nave gana puntos distintos según el tipo de alien que destruye.
💡 Métodos que puedes implementar
Alien.recibirDisparo(danio): descuenta vida y devuelve true si muere en ese impactoAlien.getTipo() / getVida(): el tipo decide los puntos y la vida avisa si sigue vivoAlien.mover(delta): desplaza la horda lateralmenteNave.mover(delta): mueve la nave y no permite salir del campoNave.disparar(alien): llama a alien.recibirDisparo(...) y suma puntos según el tipoNave.estaViva() / mostrarEstado(): estado de la nave y marcador
💡 Simulación Java Completa:Nave (Asociación básica)
Código Java funcional listo para compilar y ejecutar con la simulación en consola:
class Alien {
private String tipo;
private int posicionX;
private int posicionY;
private int vida;
private int velocidad;
public Alien(String tipo, int posicionX, int posicionY, int vida, int velocidad) {
this.tipo = tipo;
this.posicionX = posicionX;
this.posicionY = posicionY;
this.vida = vida;
this.velocidad = velocidad;
}
public boolean recibirDisparo(int danio) {
this.vida -= danio;
if (this.vida <= 0) {
System.out.println("💥 Alien " + tipo + " destruido en x=" + posicionX);
return true;
}
System.out.println("🛡️ Alien " + tipo + " resistió el disparo (vida: " + this.vida + ")");
return false;
}
public boolean estaVivo() {
return this.vida > 0;
}
public void mover(int delta) {
this.posicionX += delta * this.velocidad;
}
public String getTipo() {
return tipo;
}
public int getPosicionX() {
return posicionX;
}
}
class Nave {
private String nombre;
private int posicionX;
private int posicionY;
private int puntos;
private int anchoCampo;
private int danioDisparo;
public Nave(String nombre, int posicionX, int posicionY, int anchoCampo) {
this.nombre = nombre;
this.posicionX = posicionX;
this.posicionY = posicionY;
this.puntos = 0;
this.anchoCampo = anchoCampo;
this.danioDisparo = 2;
}
public void mover(int delta) {
int nuevaPosicion = this.posicionX + delta;
if (nuevaPosicion >= 0 && nuevaPosicion <= this.anchoCampo) {
this.posicionX = nuevaPosicion;
}
}
public void disparar(Alien alien) {
System.out.println("🚀 " + nombre + " dispara en x=" + this.posicionX + " hacia el alien " + alien.getTipo());
if (alien.recibirDisparo(this.danioDisparo)) {
this.puntos += puntosPorTipo(alien.getTipo());
System.out.println(" +" + puntosPorTipo(alien.getTipo()) + " puntos");
}
}
private int puntosPorTipo(String tipo) {
if (tipo.equals("Calamar")) {
return 30;
}
if (tipo.equals("Cangrejo")) {
return 20;
}
return 10;
}
public void mostrarEstado() {
System.out.println(nombre + " | x=" + posicionX + " | puntos: " + this.puntos);
}
}
public class Main {
public static void main(String[] args) {
Nave nave = new Nave("Nave Interceptora", 10, 20, 30);
Alien calamar = new Alien("Calamar", 10, 5, 2, 1);
Alien pulpo = new Alien("Cangrejo", 14, 5, 5, 1);
nave.mostrarEstado();
nave.disparar(calamar);
nave.mover(2);
nave.disparar(calamar);
nave.disparar(pulpo);
pulpo.mover(1);
nave.mostrarEstado();
}
}066. El vuelo de Flappy entre los tubos
🐦 Flappy Bird (móvil)🟢 2 clasesClase Principal: Pajaro · 2 clases en total · 1 conexiones (o-- / *--)0 / 4
6. El vuelo de Flappy entre los tubos
🐦 Flappy Bird (móvil)🟢 2 clasesEl pájaro sube al tocar la pantalla y cae solo por gravedad. Los tubos son obstáculos: cada tubo tiene un hueco vertical por el que hay que pasar. Si el pájaro choca con un tubo o se sale del suelo, pierde.
🎯 Misión POO: Crea la clase Tubo (columna, huecoCentro, huecoTamano) y la clase Pajaro (nombre, altura, velocidad, vivo). Implementa caer(), volar() y choca(tubo). El Pajaro consulta al Tubo para saber si la columna ya pasó y si hubo colisión.
💡 Métodos que puedes implementar
Tubo.pasoSeguro(alturaPajaro): true si el pájaro está dentro del hueco o la columna aún no llegóTubo.alturaBordeSuperior(): límite de arriba que el pájaro no puede tocarTubo.alturaBordeInferior(): límite de abajo del huecoTubo.getColumna(): para saber si el tubo ya pasó y se puede eliminarPajaro.volar(): impulso hacia arribaPajaro.caer(): baja según la gravedad y detecta si toca el sueloPajaro.choca(tubo): usa los bordes del tubo para decidir si el vuelo termina
💡 Simulación Java Completa:Pajaro (Asociación básica)
Código Java funcional listo para compilar y ejecutar con la simulación en consola:
class Tubo {
private int columna;
private int huecoCentro;
private int huecoTamano;
private int altoPantalla;
public Tubo(int columna, int huecoCentro, int huecoTamano, int altoPantalla) {
this.columna = columna;
this.huecoCentro = huecoCentro;
this.huecoTamano = huecoTamano;
this.altoPantalla = altoPantalla;
}
public int alturaBordeSuperior() {
return this.huecoCentro - (this.huecoTamano / 2);
}
public int alturaBordeInferior() {
return this.huecoCentro + (this.huecoTamano / 2);
}
public boolean pasoSeguro(int alturaPajaro) {
if (this.columna > 0) {
return true;
}
return alturaPajaro > this.alturaBordeSuperior() && alturaPajaro < this.alturaBordeInferior();
}
public int getColumna() {
return columna;
}
}
class Pajaro {
private String nombre;
private int altura;
private int velocidad;
private int gravedad;
private int altoPantalla;
private int columnasAvanzadas;
private boolean vivo;
public Pajaro(String nombre, int alturaInicial, int altoPantalla) {
this.nombre = nombre;
this.altura = alturaInicial;
this.altoPantalla = altoPantalla;
this.velocidad = 0;
this.gravedad = 1;
this.columnasAvanzadas = 0;
this.vivo = true;
}
public void volar() {
this.velocidad = -2;
this.altura += this.velocidad;
}
public void caer() {
this.velocidad += this.gravedad;
this.altura += this.velocidad;
this.columnasAvanzadas++;
if (this.altura >= this.altoPantalla) {
this.altura = this.altoPantalla;
this.vivo = false;
System.out.println("💥 " + nombre + " cayó al suelo.");
}
}
public boolean choca(Tubo tubo) {
if (tubo.getColumna() != 0) {
return false;
}
boolean seguro = tubo.pasoSeguro(this.altura);
if (!seguro) {
this.vivo = false;
System.out.println("💥 " + nombre + " chocó con el tubo en la columna " + tubo.getColumna());
}
return seguro;
}
public boolean estaVivo() {
return vivo;
}
public void mostrarEstado() {
System.out.println(nombre + " | altura: " + altura + " | velocidad: " + velocidad + " | vivo: " + vivo);
}
}
public class Main {
public static void main(String[] args) {
int altoPantalla = 40;
Pajaro pajaro = new Pajaro("Flappy", 20, altoPantalla);
Tubo tuboRojo = new Tubo(0, 20, 16, altoPantalla);
pajaro.mostrarEstado();
pajaro.volar();
pajaro.caer();
pajaro.mostrarEstado();
pajaro.caer();
pajaro.caer();
pajaro.volar();
pajaro.caer();
pajaro.mostrarEstado();
pajaro.choca(tuboRojo);
System.out.println("¿Sobrevivió? " + pajaro.estaVivo());
}
}077. El kart y su piloto
🏎️ Mario Kart🟢 2 clasesClase Principal: Kart · 2 clases en total · 1 conexiones (o-- / *--)0 / 4
7. El kart y su piloto
🏎️ Mario Kart🟢 2 clasesEn Mario Kart el kart es el vehículo y el piloto es quien lo conduce. El kart guarda su velocidad, desgaste y color, y el piloto aporta su nombre, su equipo y su pericia al manejarlo.
🎯 Misión POO: Este es el ejemplo clásico de asociación: Vehículo tiene Piloto. Crea la clase Piloto (nombre, equipo, pericia) y la clase Kart (modelo, color, velocidad, piloto). El kart recibe al piloto en el constructor y expone asignarPiloto(piloto) para los cambios de equipo.
💡 Métodos que puedes implementar
Kart.acelerar(): sube la velocidad dentro del límite del motorKart.frenar(): baja la velocidad hasta 0Kart.desgaste(puntos): consume la resistencia del kartKart.asignarPiloto(piloto): reemplaza al piloto que conduce (asociación por setter)Kart.getNombrePiloto(): delega en el piloto para mostrar quién conducePiloto.getExperto(): el kart mejora su velocidad si el piloto es experto
💡 Simulación Java Completa:Kart (Asociación básica)
Código Java funcional listo para compilar y ejecutar con la simulación en consola:
class Piloto {
private String nombre;
private String equipo;
private int pericia;
private int carrerasGanadas;
public Piloto(String nombre, String equipo, int pericia) {
this.nombre = nombre;
this.equipo = equipo;
this.pericia = pericia;
this.carrerasGanadas = 0;
}
public String getNombre() {
return nombre;
}
public String getEquipo() {
return equipo;
}
public boolean esExperto() {
return this.pericia >= 8;
}
public void ganarCarrera() {
this.carrerasGanadas++;
}
}
class Kart {
private String modelo;
private String color;
private int velocidad;
private int velocidadMaxima;
private int resistencia;
private Piloto piloto;
public Kart(String modelo, String color, int velocidadMaxima, int resistencia, Piloto piloto) {
this.modelo = modelo;
this.color = color;
this.velocidadMaxima = velocidadMaxima;
this.resistencia = resistencia;
this.piloto = piloto;
this.velocidad = 0;
}
public void acelerar() {
int tope = this.piloto.esExperto() ? this.velocidadMaxima : this.velocidadMaxima - 10;
this.velocidad += 5;
if (this.velocidad > tope) {
this.velocidad = tope;
}
System.out.println("🏎️ " + this.piloto.getNombre() + " acelera el " + modelo + " (" + this.velocidad + "/" + tope + ")");
}
public void frenar() {
this.velocidad = 0;
System.out.println("🛑 Kart detenido en boxes.");
}
public void asignarPiloto(Piloto nuevoPiloto) {
this.piloto = nuevoPiloto;
System.out.println("🔁 El " + modelo + " ahora lo conduce " + nuevoPiloto.getNombre() + " (" + nuevoPiloto.getEquipo() + ")");
}
public void desgaste(int puntos) {
this.resistencia -= puntos;
System.out.println("🔧 " + modelo + " (" + color + ") sufre " + puntos + " de desgaste. Resistencia: " + this.resistencia);
}
}
public class Main {
public static void main(String[] args) {
Piloto mario = new Piloto("Mario", "Equipo Champiñón", 9);
Kart kartRojo = new Kart("Kart Fénix", "ROJO", 100, 80, mario);
kartRojo.acelerar();
kartRojo.acelerar();
kartRojo.desgaste(25);
kartRojo.frenar();
Piloto rosalina = new Piloto("Rosalina", "Equipo Estrella", 5);
kartRojo.asignarPiloto(rosalina);
kartRojo.acelerar();
kartRojo.acelerar();
}
}088. Sonic y los anillos que recoge
💍 Sonic the Hedgehog🟢 2 clasesClase Principal: Sonic · 2 clases en total · 1 conexiones (o-- / *--)0 / 4
8. Sonic y los anillos que recoge
💍 Sonic the Hedgehog🟢 2 clasesSonic corre por el escenario y recoge anillos de oro. Cada anillo vale una cantidad distinta, y si Sonic ya recogió ese anillo no puede sumarlo otra vez. Además, correr mucho consume la energía de la rueda de la locomoción.
🎯 Misión POO: Crea la clase Anillo (valor, recogido) y la clase Sonic (nombre, anillos, velocidad, energia). El anillo se pasa por parámetro, nunca se guarda como atributo del personaje. Implementa correr(), recoger() y saltar si le queda energía.
💡 Métodos que puedes implementar
Anillo.recoger(): marca el anillo como recogidoAnillo.estaRecogido(): evita sumar dos veces el mismo anilloSonic.correr(distancia): consume energía proporcional a la distanciaSonic.recoger(anillo): si el anillo está libre, lo marca y suma su valorSonic.puedeSaltar(): true si tiene energía suficiente para el saltoSonic.getAnillos(): total de anillos acumulados
💡 Simulación Java Completa:Sonic (Asociación básica)
Código Java funcional listo para compilar y ejecutar con la simulación en consola:
class Anillo {
private int valor;
private boolean recogido;
private int posicionX;
public Anillo(int valor, int posicionX) {
this.valor = valor;
this.posicionX = posicionX;
this.recogido = false;
}
public void recoger() {
this.recogido = true;
}
public boolean estaRecogido() {
return this.recogido;
}
public int getValor() {
return valor;
}
public int getPosicionX() {
return posicionX;
}
}
class Sonic {
private String nombre;
private int anillos;
private int velocidad;
private int energia;
private int distancia;
public Sonic(String nombre, int velocidad, int energia) {
this.nombre = nombre;
this.anillos = 0;
this.velocidad = velocidad;
this.energia = energia;
this.distancia = 0;
}
public void correr(int distancia) {
this.distancia += distancia;
this.energia -= distancia / 10;
System.out.println("💨 " + nombre + " corre " + distancia + " m a " + this.velocidad + " km/h. Energía: " + this.energia);
}
public void recoger(Anillo anillo) {
if (anillo.estaRecogido()) {
System.out.println("El anillo de x=" + anillo.getPosicionX() + " ya estaba recogido.");
return;
}
anillo.recoger();
this.anillos += anillo.getValor();
System.out.println("💍 " + nombre + " recoge un anillo (+" + anillo.getValor() + "). Total: " + this.anillos);
}
public boolean puedeSaltar() {
return this.energia > 20;
}
public void mostrarEstado() {
System.out.println(nombre + " | distancia: " + distancia + " m | anillos: " + anillos + " | energía: " + energia);
}
}
public class Main {
public static void main(String[] args) {
Anillo chico = new Anillo(1, 120);
Anillo grande = new Anillo(10, 350);
Sonic sonic = new Sonic("Sonic", 40, 100);
sonic.correr(60);
sonic.recoger(chico);
sonic.recoger(chico);
sonic.correr(120);
sonic.recoger(grande);
sonic.mostrarEstado();
System.out.println("Puede saltar: " + sonic.puedeSaltar());
}
}099. Mario esquivando los barriles de Donkey Kong
🍌 Donkey Kong (clásico de arcade)🟢 2 clasesClase Principal: Mario · 2 clases en total · 1 conexiones (o-- / *--)0 / 4
9. Mario esquivando los barriles de Donkey Kong
🍌 Donkey Kong (clásico de arcade)🟢 2 clasesDonkey Kong lanza barriles por la escalera y Mario tiene que subir esquivándolos. Cada barril baja por una columna con una velocidad distinta; si coincide con la posición de Mario, Mario pierde una vida.
🎯 Misión POO: Crea la clase Barril (columna, velocidad, activo) y la clase Mario (nombre, posicionX, vidas, puntuacion). Implementa subir() y esquivar(barril). Piensa en quién llama a quién: Mario consulta al Barril para saber si le toca.
💡 Métodos que puedes implementar
Barril.caer(): baja una posición y se desactiva al llegar abajoBarril.estaEn(posicionMario): true si el barril activo está en la misma columnaMario.subir(pisos): sube en la escalera y suma puntuaciónMario.esquivar(barril): si el barril está en su columna pierde una vidaMario.estaVivo(): true si todavía tiene vidasMario.mostrarEstado(): piso actual, vidas y puntos
💡 Simulación Java Completa:Mario (Asociación básica)
Código Java funcional listo para compilar y ejecutar con la simulación en consola:
class Barril {
private int columna;
private int velocidad;
private int posicion;
private int posicionMaxima;
private boolean activo;
public Barril(int columna, int velocidad, int posicionMaxima) {
this.columna = columna;
this.velocidad = velocidad;
this.posicionMaxima = posicionMaxima;
this.posicion = 0;
this.activo = true;
}
public void caer() {
if (!activo) {
return;
}
this.posicion += this.velocidad;
if (this.posicion >= this.posicionMaxima) {
this.posicion = 0;
this.activo = false;
}
}
public boolean estaEn(int posicionMario) {
return this.activo && this.columna == posicionMario && this.posicion > this.posicionMaxima / 2;
}
public boolean estaActivo() {
return activo;
}
}
class Mario {
private String nombre;
private int posicionX;
private int piso;
private int vidas;
private int puntuacion;
private int pisoMaximo;
public Mario(String nombre, int posicionX, int vidas, int pisoMaximo) {
this.nombre = nombre;
this.posicionX = posicionX;
this.piso = 0;
this.vidas = vidas;
this.puntuacion = 0;
this.pisoMaximo = pisoMaximo;
}
public void subir(int pisos) {
int nuevoPiso = this.piso + pisos;
if (nuevoPiso > this.pisoMaximo) {
nuevoPiso = this.pisoMaximo;
}
this.piso = nuevoPiso;
this.puntuacion += pisos * 100;
}
public boolean esquivar(Barril barril) {
if (barril.estaEn(this.posicionX)) {
this.vidas--;
System.out.println("💥 ¡Barril en la columna " + this.posicionX + "! Vidas: " + this.vidas);
return false;
}
System.out.println("🍌 " + this.nombre + " esquivó el barril de la columna " + this.posicionX);
return true;
}
public boolean estaVivo() {
return this.vidas > 0;
}
public void mostrarEstado() {
System.out.println(nombre + " | piso: " + piso + "/" + pisoMaximo + " | vidas: " + vidas + " | puntos: " + puntuacion);
}
}
public class Main {
public static void main(String[] args) {
Mario mario = new Mario("Mario", 4, 3, 8);
Barril barrilRapido = new Barril(4, 3, 12);
Barril barrilLento = new Barril(7, 1, 12);
mario.mostrarEstado();
barrilRapido.caer();
barrilRapido.caer();
barrilRapido.caer();
barrilRapido.caer();
mario.esquivar(barrilRapido);
mario.subir(3);
barrilLento.caer();
mario.esquivar(barrilLento);
mario.mostrarEstado();
}
}1010. El skater y su tabla en el skatepark
🛹 Tony Hawk’s Pro Skater🟢 2 clasesClase Principal: Skater · 2 clases en total · 1 conexiones (o-- / *--)0 / 4
10. El skater y su tabla en el skatepark
🛹 Tony Hawk’s Pro Skater🟢 2 clasesEn el skatepark el skater hace tricks sobre los rieles. La tabla tiene una vida útil: cada trick la desgasta, y cuando se rompe el skater deja de poder hacer piruetas.
🎯 Misión POO: Crea la clase Tabla (modelo,color, desgaste) y la clase Skater (nombre, tabla, trucoActual). Implementa hacerTruco(nombreTruco) y deslizarse(). La tabla limita los trucos: pásala siempre como atributo del skater.
💡 Métodos que puedes implementar
Tabla.desgastarse(factor): suma desgaste según la dificultad del trucoTabla.estaRota(): true cuando el desgaste supera el 100 %Tabla.getModelo(): para mostrar qué tabla usa el skaterSkater.hacerTruco(nombre): si la tabla no está rota, desgasta y sube el puntajeSkater.deslizarse(distancia): avanza y consume desgaste mínimoSkater.getTabla(): devuelve el objeto tabla para poder consultarlo desde afuera
💡 Simulación Java Completa:Skater (Asociación básica)
Código Java funcional listo para compilar y ejecutar con la simulación en consola:
class Tabla {
private String modelo;
private String color;
private int desgaste;
private String nivel;
public Tabla(String modelo, String color, String nivel) {
this.modelo = modelo;
this.color = color;
this.nivel = nivel;
this.desgaste = 0;
}
public void desgastarse(int factor) {
this.desgaste += factor;
if (this.desgaste > 100) {
this.desgaste = 100;
System.out.println("💔 La tabla " + modelo + " se rompió en dos.");
}
}
public boolean estaRota() {
return this.desgaste >= 100;
}
public String getModelo() {
return modelo;
}
public int getDesgaste() {
return desgaste;
}
}
class Skater {
private String nombre;
private Tabla tabla;
private int puntaje;
private String trucoActual;
private int distancia;
public Skater(String nombre, Tabla tabla) {
this.nombre = nombre;
this.tabla = tabla;
this.puntaje = 0;
this.trucoActual = "ninguno";
this.distancia = 0;
}
public void hacerTruco(String nombreTruco, int dificultad) {
if (tabla.estaRota()) {
System.out.println(nombre + " no puede hacer " + nombreTruco + ": la tabla está rota.");
return;
}
this.trucoActual = nombreTruco;
this.puntaje += dificultad * 100;
tabla.desgastarse(dificultad * 8);
System.out.println("🛹 " + nombre + " hizo " + nombreTruco + " (+" + (dificultad * 100) + ") con la tabla " + tabla.getModelo());
}
public void deslizarse(int distancia) {
this.distancia += distancia;
tabla.desgastarse(2);
}
public Tabla getTabla() {
return tabla;
}
public void mostrarEstado() {
System.out.println(nombre + " | truco: " + trucoActual + " | puntaje: " + puntaje + " | tabla " + tabla.getModelo() + " (" + tabla.getDesgaste() + "% desgaste)");
}
}
public class Main {
public static void main(String[] args) {
Tabla tablaPatineta = new Tabla("Patineta Neón", "VERDE", "pro");
Skater skater = new Skater("Tony", tablaPatineta);
skater.deslizarse(50);
skater.hacerTruco("Ollie", 2);
skater.hacerTruco("Kickflip", 4);
skater.hacerTruco("Grind en el riel", 6);
skater.mostrarEstado();
skater.hacerTruco("900", 9);
skater.mostrarEstado();
}
}1111. Kirby copia el poder de su enemigo
🍑 Kirby (Nintendo)🟡 3 clasesClase Principal: Kirby · 3 clases en total · 2 conexiones (o-- / *--)0 / 4
11. Kirby copia el poder de su enemigo
🍑 Kirby (Nintendo)🟡 3 clasesKirby no tiene poderes propios: cuando derrota a un enemigo copia su habilidad y la guarda como un poder. El poder copiado determina el daño que hace y se puede usar varias veces antes de perderlo.
🎯 Misión POO: Crea las clases Poder (nombre, tipo, dano), Enemigo (nombre, tipo, vida, poderQueOtorga) y Kirby (nombre, vida, poderCopiado). SIN usar List: el poder copiado se guarda en un atributo simple. Implementa copiarPoder(enemigo) y usarPoder(objetivo).
💡 Métodos que puedes implementar
Poder.getDano(): el daño real depende del tipo (fuego, hielo, jet)Enemigo.otorgarPoder(): devuelve el poder que deja al ser derrotadoEnemigo.recibirDanio(danio): descuenta vida y avisa si murióKirby.copiarPoder(enemigo): pide el poder al enemigo y lo guarda como atributoKirby.usarPoder(objetivo): usa el poder copiado contra un enemigoKirby.tienePoder(): false cuando todavía no copió nada
💡 Simulación Java Completa:Kirby (Asociación intermedia)
Código Java funcional listo para compilar y ejecutar con la simulación en consola:
class Poder {
private String nombre;
private String tipo;
private int dano;
private int usos;
public Poder(String nombre, String tipo, int dano) {
this.nombre = nombre;
this.tipo = tipo;
this.dano = dano;
this.usos = 0;
}
public int usar() {
this.usos++;
if (this.tipo.equals("FUEGO")) {
return this.dano * 2;
}
return this.dano;
}
public boolean estaAgotado() {
return this.usos >= 3;
}
public String getNombre() {
return nombre;
}
}
class Enemigo {
private String nombre;
private int vida;
private String poderQueOtorga;
private String tipo;
public Enemigo(String nombre, String tipo, int vida, String poderQueOtorga) {
this.nombre = nombre;
this.tipo = tipo;
this.vida = vida;
this.poderQueOtorga = poderQueOtorga;
}
public boolean recibirDanio(int danio) {
this.vida -= danio;
if (this.vida <= 0) {
System.out.println("💫 Enemigo " + nombre + " derrotado.");
return true;
}
return false;
}
public String otorgarPoder() {
return this.poderQueOtorga;
}
public String getNombre() {
return nombre;
}
public int getVida() {
return vida;
}
}
class Kirby {
private String nombre;
private int vida;
private Poder poderCopiado;
private int poderesUsados;
public Kirby(String nombre, int vida) {
this.nombre = nombre;
this.vida = vida;
this.poderCopiado = null;
this.poderesUsados = 0;
}
public boolean tienePoder() {
return this.poderCopiado != null && !this.poderCopiado.estaAgotado();
}
public void copiarPoder(Enemigo enemigo) {
String nombrePoder = enemigo.otorgarPoder();
this.poderCopiado = new Poder(nombrePoder, nombrePoder, 4);
System.out.println("🍑 " + nombre + " copió el poder " + nombrePoder + " de " + enemigo.getNombre());
}
public void usarPoder(Enemigo objetivo) {
if (!tienePoder()) {
System.out.println(nombre + " todavía no tiene ningún poder copiado.");
return;
}
int danio = this.poderCopiado.usar();
this.poderesUsados++;
System.out.println("💥 " + nombre + " usa " + this.poderCopiado.getNombre() + " y hace " + danio + " de daño");
objetivo.recibirDanio(danio);
}
public void mostrarEstado() {
String poder = this.poderCopiado == null ? "ninguno" : this.poderCopiado.getNombre();
System.out.println(nombre + " | vida: " + vida + " | poder: " + poder + " | usos: " + poderesUsados);
}
}
public class Main {
public static void main(String[] args) {
Kirby kirby = new Kirby("Kirby", 100);
Enemigo waddle = new Enemigo("Waddle Dee", "MARTILLO", 6, "MARTILLO");
kirby.mostrarEstado();
kirby.copiarPoder(waddle);
kirby.usarPoder(waddle);
kirby.usarPoder(waddle);
kirby.mostrarEstado();
}
}1212. Samus y su cañón de protones
🎮 Metroid (Nintendo)🟡 3 clasesClase Principal: Samus · 3 clases en total · 2 conexiones (o-- / *--)0 / 4
12. Samus y su cañón de protones
🎮 Metroid (Nintendo)🟡 3 clasesSamus explora la nave y dispara con un cañón de protones. Cada misil sale de la mochila con un daño y un radio de explosión, y los Metroides se dividen en dos si uno de tamaño grande recibe un golpe fuerte.
🎯 Misión POO: Crea las clases Misil (dano, radioExplosion), Metroide (tipo, vida, tamaño) y Samus (nombre, vida, municion). SIN List ni arrays: guarda un solo Misil como atributo. Implementa disparar(metroide) y Samus no puede disparar sin munición.
💡 Métodos que puedes implementar
Misil.explota(): devuelve el daño según el radio de explosión (radio grande = más daño)Metroide.recibirDanio(danio): si es de tamaño grande y recibe un crítico, se parte en dosMetroide.sePartio(): indica que el metroide se dividióSamus.disparar(metroide): usa el misil de la mochila, resta munición y aplica el dañoSamus.tieneMunicion(): false cuando se quedó sin municiónSamus.mostrarEstado(): vida, munición y estado del misil
💡 Simulación Java Completa:Samus (Asociación intermedia)
Código Java funcional listo para compilar y ejecutar con la simulación en consola:
class Misil {
private int dano;
private int radioExplosion;
private boolean usado;
public Misil(int dano, int radioExplosion) {
this.dano = dano;
this.radioExplosion = radioExplosion;
this.usado = false;
}
public int explota() {
this.usado = true;
return this.dano + (this.radioExplosion * 2);
}
public int getDano() {
return dano;
}
public boolean estaUsado() {
return usado;
}
}
class Metroide {
private String tipo;
private int vida;
private String tamano;
private boolean partido;
public Metroide(String tipo, int vida, String tamano) {
this.tipo = tipo;
this.vida = vida;
this.tamano = tamano;
this.partido = false;
}
public boolean recibirDanio(int danio) {
this.vida -= danio;
if (this.vida <= 0) {
System.out.println("☠️ Metroide " + tipo + " destruido (" + tamano + ")");
return true;
}
if (this.tamano.equals("GRANDE") && danio > 10) {
this.partido = true;
System.out.println("🧬 El Metroide " + tipo + " se ha partido en dos!");
}
return false;
}
public boolean sePartio() {
return this.partido;
}
public int getVida() {
return vida;
}
}
class Samus {
private String nombre;
private int vida;
private int municion;
private Misil misilActual;
private int metroidesDerrotados;
public Samus(String nombre, int vida, int municion, Misil misil) {
this.nombre = nombre;
this.vida = vida;
this.municion = municion;
this.misilActual = misil;
this.metroidesDerrotados = 0;
}
public boolean tieneMunicion() {
return this.municion > 0 && this.misilActual != null;
}
public void recogerMisil(Misil misil) {
this.misilActual = misil;
this.municion += 5;
System.out.println("🧨 " + nombre + " recogió un misil nuevo (daño " + misil.getDano() + ")");
}
public void disparar(Metroide metroide) {
if (!tieneMunicion()) {
System.out.println("🔫 " + nombre + " no tiene munición disponible.");
return;
}
int danio = this.misilActual.explota();
this.municion--;
System.out.println("💥 " + nombre + " dispara un misil de daño " + danio);
if (metroide.recibirDanio(danio)) {
this.metroidesDerrotados++;
}
this.misilActual = new Misil(4, 1);
}
public void mostrarEstado() {
System.out.println(nombre + " | vida: " + vida + " | munición: " + municion + " | metroides derrotados: " + metroidesDerrotados);
}
}
public class Main {
public static void main(String[] args) {
Misil misilInicial = new Misil(8, 3);
Samus samus = new Samus("Samus", 99, 2, misilInicial);
Metroide metroideGrande = new Metroide("Zeta", 30, "GRANDE");
Metroide metroidePequeno = new Metroide("Rinka", 12, "PEQUEÑO");
samus.mostrarEstado();
samus.disparar(metroideGrande);
samus.disparar(metroideGrande);
samus.disparar(metroidePequeno);
samus.recogerMisil(new Misil(15, 4));
samus.disparar(metroidePequeno);
samus.mostrarEstado();
}
}1313. El jardinero y sus plantas contra los zombis
🌻 Plants vs. Zombies🟡 3 clasesClase Principal: Jardinero · 3 clases en total · 2 conexiones (o-- / *--)0 / 4
13. El jardinero y sus plantas contra los zombis
🌻 Plants vs. Zombies🟡 3 clasesEl jugador planta defensas y cada planta tiene un coste, una vida y una cadencia de disparo. Los zombis avanzan por el jardín y, si llegan a la casa, el jardinero pierde. Aquí solo hay una planta activa y un zombi: es association simple sin colecciones.
🎯 Misión POO: Crea las clases Planta (tipo, vida, coste, dano), Zombi (nombre, vida, velocidad) y Jardinero (nombre, monedas, plantaActiva). SIN usar List: la planta activa y el zombi se guardan en atributos simples. Implementa plantar(), disparar(zombi) y defender().
💡 Métodos que puedes implementar
Planta.disparar(): devuelve el daño y avisa si la planta se queda sin recargasPlanta.recibirDanio(danio): la planta pierde vida y puede morirZombi.avanzar(): suma la velocidad a su posición de carrilZombi.recibirDanio(danio): descuenta vida (el chador zombi aguanta más)Jardinero.plantar(planta): paga el coste con las monedas disponiblesJardinero.disparar(zombi): delega en la planta activa y muestra el resultado
💡 Simulación Java Completa:Jardinero (Asociación intermedia)
Código Java funcional listo para compilar y ejecutar con la simulación en consola:
class Planta {
private String tipo;
private int vida;
private int coste;
private int dano;
private int recarga;
public Planta(String tipo, int vida, int coste, int dano) {
this.tipo = tipo;
this.vida = vida;
this.coste = coste;
this.dano = dano;
this.recarga = 2;
}
public int disparar() {
if (this.recarga <= 0) {
return 0;
}
this.recarga--;
return this.dano;
}
public boolean recibirDanio(int danio) {
this.vida -= danio;
return this.vida <= 0;
}
public boolean estaViva() {
return this.vida > 0;
}
public String getTipo() {
return tipo;
}
public int getCoste() {
return coste;
}
}
class Zombi {
private String nombre;
private int vida;
private int velocidad;
private int posX;
private String tipo;
public Zombi(String nombre, String tipo, int vida, int velocidad) {
this.nombre = nombre;
this.tipo = tipo;
this.vida = vida;
this.velocidad = velocidad;
this.posX = 0;
}
public void avanzar() {
this.posX += this.velocidad;
}
public boolean recibirDanio(int danio) {
int danoEfectivo = this.tipo.equals("CHADOR") ? danio / 2 : danio;
this.vida -= danoEfectivo;
if (this.vida <= 0) {
System.out.println("🧟 " + nombre + " fue derrotado");
return true;
}
return false;
}
public boolean llegoAlFinal() {
return this.posX >= 50;
}
public String getNombre() {
return nombre;
}
}
class Jardinero {
private String nombre;
private int monedas;
private Planta plantaActiva;
private int zombisDerrotados;
public Jardinero(String nombre, int monedas) {
this.nombre = nombre;
this.monedas = monedas;
this.plantaActiva = null;
this.zombisDerrotados = 0;
}
public boolean plantar(Planta planta) {
if (this.monedas < planta.getCoste()) {
System.out.println("🪙 No hay monedas suficientes para plantar " + planta.getTipo());
return false;
}
this.monedas -= planta.getCoste();
this.plantaActiva = planta;
System.out.println("🌱 " + nombre + " plantó " + planta.getTipo() + " (-" + planta.getCoste() + " monedas)");
return true;
}
public void disparar(Zombi zombi) {
if (this.plantaActiva == null || !this.plantaActiva.estaViva()) {
System.out.println("No hay ninguna planta activa que dispare.");
return;
}
int danio = this.plantaActiva.disparar();
if (danio == 0) {
System.out.println("La planta está recargando...");
return;
}
System.out.println("🌻 " + this.plantaActiva.getTipo() + " dispara a " + zombi.getNombre());
if (zombi.recibirDanio(danio)) {
this.zombisDerrotados++;
}
}
public void mostrarEstado() {
String planta = this.plantaActiva == null ? "ninguna" : this.plantaActiva.getTipo();
System.out.println(nombre + " | monedas: " + monedas + " | planta: " + planta + " | zombis derrotados: " + zombisDerrotados);
}
}
public class Main {
public static void main(String[] args) {
Jardinero jardinero = new Jardinero("Crisp", 75);
Zombi zombiNormal = new Zombi("Zombi básico", "NORMAL", 20, 5);
Zombi zombiChador = new Zombi("Zombi con cono", "CHADOR", 40, 3);
jardinero.plantar(new Planta("Girasol", 30, 50, 6));
jardinero.disparar(zombiNormal);
jardinero.disparar(zombiNormal);
zombiNormal.avanzar();
zombiChador.avanzar();
jardinero.disparar(zombiChador);
jardinero.mostrarEstado();
}
}1414. El aldeano, su cuartel y los muros
🏰 Clash of Clans🟡 3 clasesClase Principal: Aldeano · 3 clases en total · 2 conexiones (o-- / *--)0 / 4
14. El aldeano, su cuartel y los muros
🏰 Clash of Clans🟡 3 clasesEn Clash of Clans el aldeano sube de nivel, improve su cuartel y coloca muros alrededor del pueblo. Cada muro tiene vida y tipo: si un muro cae, los enemigos entran más rápido. Aquí hay un solo aldeano, un cuartel y un muro activo.
🎯 Misión POO: Crea las clases Muro (tipo, vida), Cuartel (nivel, capacidadTropas, tropasFormadas) y Aldeano (nombre, nivel, oro, cuartel). SIN List ni arrays: cada Relationship se resuelve con un atributo. Implementa mejorar(), invocarTropas() y colocarMuro().
💡 Métodos que puedes implementar
Muro.recibirDanio(danio): baja la vida del muro y avisa si cayóMuro.estaEnPie(): true mientras tenga vidaCuartel.mejorar(nivel): sube el nivel y devuelve la nueva capacidad de tropasCuartel.puedeInvocar(): true si quedan plazas libres de tropaAldeano.invocarTropas(nombreTropa): pide una tropa al cuartel y gasta oroAldeano.colocarMuro(muro): asocia el muro al pueblo y repara el anterior
💡 Simulación Java Completa:Aldeano (Asociación intermedia)
Código Java funcional listo para compilar y ejecutar con la simulación en consola:
class Muro {
private String tipo;
private int vida;
private int nivel;
public Muro(String tipo, int vida, int nivel) {
this.tipo = tipo;
this.vida = vida;
this.nivel = nivel;
}
public boolean recibirDanio(int danio) {
this.vida -= danio;
if (this.vida <= 0) {
this.vida = 0;
System.out.println("🧱 El muro de " + tipo + " ha caído.");
return false;
}
return true;
}
public boolean estaEnPie() {
return this.vida > 0;
}
public String getTipo() {
return tipo;
}
public int getVida() {
return vida;
}
}
class Cuartel {
private int nivel;
private int capacidadTropas;
private int tropasFormadas;
public Cuartel(int nivel) {
this.nivel = nivel;
this.capacidadTropas = nivel * 5;
this.tropasFormadas = 0;
}
public void mejorar() {
this.nivel++;
this.capacidadTropas = this.nivel * 5;
System.out.println("🏰 Cuartel mejorado a nivel " + this.nivel + " (capacidad " + this.capacidadTropas + ")");
}
public boolean puedeInvocar() {
return this.tropasFormadas < this.capacidadTropas;
}
public void invocarTropa(String nombre) {
if (puedeInvocar()) {
this.tropasFormadas++;
System.out.println("⚔️ Se invocó " + nombre + " en el cuartel");
} else {
System.out.println("El cuartel está al máximo de tropas (" + this.tropasFormadas + "/" + this.capacidadTropas + ")");
}
}
public int getCapacidadTropas() {
return capacidadTropas;
}
}
class Aldeano {
private String nombre;
private int nivel;
private int oro;
private Cuartel cuartel;
private Muro muroPrincipal;
private int poblacion;
public Aldeano(String nombre, int nivel, int oro, Cuartel cuartel) {
this.nombre = nombre;
this.nivel = nivel;
this.oro = oro;
this.cuartel = cuartel;
this.muroPrincipal = null;
this.poblacion = 0;
}
public void mejorarCuartel() {
this.oro -= 500;
this.cuartel.mejorar();
System.out.println("💰 " + nombre + " gastó 500 de oro (quedan " + this.oro + ")");
}
public void invocarTropas(String nombreTropa) {
this.cuartel.invocarTropa(nombreTropa);
this.oro -= 50;
this.poblacion += 2;
}
public void colocarMuro(Muro muro) {
this.muroPrincipal = muro;
System.out.println("🧱 " + nombre + " colocó un muro de " + muro.getTipo() + " con " + muro.getVida() + " de vida");
}
public void mostrarEstado() {
String muro = this.muroPrincipal == null ? "sin muros" : this.muroPrincipal.getTipo() + " (" + this.muroPrincipal.getVida() + " HP)";
System.out.println(nombre + " | nivel: " + nivel + " | oro: " + oro + " | población: " + poblacion + " | muro: " + muro);
}
}
public class Main {
public static void main(String[] args) {
Cuartel cuartelInicial = new Cuartel(3);
Aldeano aldeano = new Aldeano("Chief", 4, 1000, cuartelInicial);
aldeano.mostrarEstado();
aldeano.colocarMuro(new Muro("Piedra", 300, 2));
aldeano.invocarTropas("Duendes");
aldeano.mejorarCuartel();
aldeano.invocarTropas("Gólems");
aldeano.mostrarEstado();
}
}1515. La partida de Candy Crush: ficha y azúcaritas
🍬 Candy Crush Saga🟡 3 clasesClase Principal: Partida · 3 clases en total · 2 conexiones (o-- / *--)0 / 4
15. La partida de Candy Crush: ficha y azúcaritas
🍬 Candy Crush Saga🟡 3 clasesEn Candy Crush mueves fichas de colores en la pantalla. Al formar una línea de tres o más fichas del mismo color se forma una "azucarita" que desaparece y suma puntos. Aquí modelamos una sola ficha activa y una sola azucarita por combo.
🎯 Misión POO: Crea las clases Ficha (color, fila, columna), Azucarita (tipo, puntos) y Partida (jugador, movimientos, fichaSeleccionada). SIN List ni arrays: la ficha seleccionada se guarda en un atributo. Implementa seleccionar(), mover(), formarCombo() y jugadasRestantes().
💡 Métodos que puedes implementar
Ficha.mover(fila, columna): cambia la posición de la fichaFicha.mismoColor(otra): compara el color con otra fichaAzucarita.generar(color, cantidad): crea una azucarita con los puntos de la combinaciónPartida.seleccionar(ficha): guarda la ficha activa (atributo, no lista)Partida.mover(ficha, fila, columna): mueve la ficha y consume un movimientoPartida.formarCombo(cantidad): si hay 3 o más del mismo color, genera la azucarita y suma puntos
💡 Simulación Java Completa:Partida (Asociación intermedia)
Código Java funcional listo para compilar y ejecutar con la simulación en consola:
class Ficha {
private String color;
private int fila;
private int columna;
private String tipo;
public Ficha(String color, String tipo, int fila, int columna) {
this.color = color;
this.tipo = tipo;
this.fila = fila;
this.columna = columna;
}
public void mover(int fila, int columna) {
this.fila = fila;
this.columna = columna;
}
public boolean mismoColor(Ficha otra) {
return this.color.equals(otra.getColor());
}
public String getColor() {
return color;
}
public String getPosicion() {
return tipo + " " + color + " en (" + fila + "," + columna + ")";
}
}
class Azucarita {
private String tipo;
private int puntos;
private String colorOrigen;
public Azucarita(String tipo) {
this.tipo = tipo;
this.puntos = 0;
this.colorOrigen = "";
}
public void generar(String color, int cantidad) {
this.colorOrigen = color;
this.puntos = cantidad * cantidad * 10;
System.out.println("🍬 Azucarita " + tipo + " de color " + color + " (+" + this.puntos + " puntos)");
}
public int getPuntos() {
return puntos;
}
}
class Partida {
private String jugador;
private int movimientos;
private int puntos;
private Ficha fichaSeleccionada;
private Azucarita azucaritaCreada;
public Partida(String jugador, int movimientos) {
this.jugador = jugador;
this.movimientos = movimientos;
this.puntos = 0;
this.fichaSeleccionada = null;
this.azucaritaCreada = new Azucarita("Normal");
}
public void seleccionar(Ficha ficha) {
this.fichaSeleccionada = ficha;
System.out.println("👆 " + jugador + " seleccionó " + ficha.getPosicion());
}
public boolean mover(Ficha ficha, int fila, int columna) {
if (this.fichaSeleccionada == null) {
System.out.println("Primero selecciona una ficha.");
return false;
}
ficha.mover(fila, columna);
this.movimientos--;
System.out.println("🍭 " + ficha.getPosicion() + " | jugadas restantes: " + this.movimientos);
return true;
}
public void formarCombo(int cantidad) {
if (cantidad >= 3 && this.fichaSeleccionada != null) {
this.azucaritaCreada.generar(this.fichaSeleccionada.getColor(), cantidad);
this.puntos += this.azucaritaCreada.getPuntos();
} else {
System.out.println("No hay combo: se necesitan 3 fichas del mismo color.");
}
}
public int jugadasRestantes() {
return this.movimientos;
}
public void mostrarEstado() {
System.out.println(jugador + " | jugadas: " + movimientos + " | puntos: " + puntos);
}
}
public class Main {
public static void main(String[] args) {
Partida partida = new Partida("Ana", 5);
Ficha roja = new Ficha("ROJO", "Gomita", 2, 1);
Ficha roja2 = new Ficha("ROJO", "Gomita", 2, 2);
Ficha azul = new Ficha("AZUL", "Caramelo", 1, 3);
partida.seleccionar(roja);
partida.mover(roja, 2, 2);
partida.formarCombo(roja.mismoColor(roja2) ? 3 : 1);
partida.seleccionar(azul);
partida.mover(azul, 3, 3);
partida.formarCombo(1);
partida.mostrarEstado();
}
}1616. Agente, arma, bala y bomba en una ronda
🎯 Counter-Strike 2🟠 4 clasesClase Principal: Agente · 4 clases en total · 3 conexiones (o-- / *--)0 / 4
16. Agente, arma, bala y bomba en una ronda
🎯 Counter-Strike 2🟠 4 clasesUna ronda de shooter táctico une cuatro piezas: el agente que juega, el arma que usa, la bala que dispara y la bomba que hay que plantar o defender. El arma decide cuántas balas quedan en el cargador y la bala decide el daño.
🎯 Misión POO: Crea las cuatro clases: Bala (dano, velocidad), Arma (nombre, cargador, precision), Bomba (tiempo, plantada) y Agente (nombre, rol, vida). Encadena la asociación completa: el agente tiene un arma, el arma crea la bala y el agente puede plantar una bomba.
💡 Métodos que puedes implementar
Bala.recorrer(distancia): suma el alcance y devuelve true si sale del mapaArma.disparar(): descuenta una bala del cargador y devuelve una Bala nuevaArma.estaVacia(): true cuando se acabó el cargadorBomba.plantar(): arranca la cuenta regresivaBomba.explota(): true si el tiempo llegó a ceroAgente.disparar(objetivo): pide el disparo al arma, mueve la bala y aplica el dañoAgente.plantarBomba(bomba): delega en la bomba y avisa si la ronda se gana
💡 Simulación Java Completa:Agente (Asociación avanzada)
Código Java funcional listo para compilar y ejecutar con la simulación en consola:
class Bala {
private int dano;
private int velocidad;
private int alcance;
public Bala(int dano, int velocidad) {
this.dano = dano;
this.velocidad = velocidad;
this.alcance = 0;
}
public boolean recorrer(int distancia) {
this.alcance += distancia;
return this.alcance > 120;
}
public int impacto() {
return this.dano;
}
}
class Arma {
private String nombre;
private int dano;
private int cargador;
private int precision;
public Arma(String nombre, int dano, int cargador, int precision) {
this.nombre = nombre;
this.dano = dano;
this.cargador = cargador;
this.precision = precision;
}
public boolean estaVacia() {
return this.cargador <= 0;
}
public Bala disparar() {
this.cargador--;
return new Bala(this.dano, this.precision);
}
public void recargar() {
this.cargador = 30;
System.out.println("🔄 " + nombre + " recargada");
}
public String getNombre() {
return nombre;
}
}
class Bomba {
private int tiempo;
private boolean plantada;
private String posicion;
public Bomba(int tiempo) {
this.tiempo = tiempo;
this.plantada = false;
this.posicion = "A";
}
public void plantar(String posicion) {
this.plantada = true;
this.posicion = posicion;
System.out.println("💣 Bomba plantada en " + posicion + " con " + this.tiempo + " s");
}
public void pasarTiempo() {
if (plantada && this.tiempo > 0) {
this.tiempo--;
}
}
public boolean explota() {
return plantada && this.tiempo == 0;
}
}
class Agente {
private String nombre;
private String rol;
private int vida;
private Arma arma;
private int baja;
private Bomba bomba;
public Agente(String nombre, String rol, int vida, Arma arma) {
this.nombre = nombre;
this.rol = rol;
this.vida = vida;
this.arma = arma;
this.baja = 0;
this.bomba = new Bomba(5);
}
public void disparar(Agente objetivo) {
if (arma.estaVacia()) {
System.out.println(nombre + " no tiene balas en el cargador.");
arma.recargar();
return;
}
Bala bala = arma.disparar();
bala.recorrer(60);
int dano = bala.impacto();
objetivo.vida -= dano;
System.out.println("🎯 " + nombre + " dispara al " + objetivo.nombre + " y le quita " + dano + " de vida (" + objetivo.vida + " restante)");
if (objetivo.vida <= 0) {
this.baja++;
}
}
public void plantarBomba(String posicion) {
bomba.plantar(posicion);
}
public boolean estaVivo() {
return this.vida > 0;
}
public void mostrarEstado() {
System.out.println(nombre + " [" + rol + "] | vida: " + vida + " | arma: " + arma.getNombre() + " | bajas: " + baja);
}
}
public class Main {
public static void main(String[] args) {
Arma ak47 = new Arma("AK-47", 25, 2, 4);
Arma awp = new Arma("AWP", 90, 1, 2);
Agente terrorist = new Agente("Agente Alfa", "Terrorista", 100, ak47);
Agente ct = new Agente("Agente Bravo", "Antiterrorista", 100, awp);
terrorist.mostrarEstado();
terrorist.disparar(ct);
ct.disparar(terrorist);
ct.mostrarEstado();
terrorist.plantarBomba("B");
terrorist.disparar(ct);
terrorist.mostrarEstado();
}
}1717. La granja de Stardew Valley
🌾 Stardew Valley🟠 4 clasesClase Principal: Granjero · 4 clases en total · 3 conexiones (o-- / *--)0 / 4
17. La granja de Stardew Valley
🌾 Stardew Valley🟠 4 clasesEn Stardew Valley el granjero cultiva, cuida las gallinas y vende su cosecha en el mercado de Pierre. Cada cosecha tarda días en crecer y el mercado paga un precio distinto según el producto y la calidad.
🎯 Misión POO: Crea Cultivo (tipo, diasParaCosechar, precioBase), Gallina (nombre, huevosPorDia), Mercado (nombre, multiplicador) y Granjero (nombre, energia, oro). Encadena la asociación: el granjero riega un cultivo, recoge la gallina y lleva la cosecha al mercado.
💡 Métodos que puedes implementar
Cultivo.regar(): suma un día de crecimiento y avisa si ya está listoCultivo.estaListo(): true cuando pasaron los días de crecimientoCultivo.cosechar(): devuelve el cultivo cosechado y lo deja listo para replantarGallina.recolectarHuevos(): suma huevos y consume comidaMercado.vender(cultivo): multiplica el precio base del cultivo y devuelve el dineroGranjero.cosechar(cultivo): pide la cosecha al cultivo y la lleva al mercado
💡 Simulación Java Completa:Granjero (Asociación avanzada)
Código Java funcional listo para compilar y ejecutar con la simulación en consola:
class Cultivo {
private String tipo;
private int diasCrecimiento;
private int diasRegados;
private int precioBase;
private boolean listo;
public Cultivo(String tipo, int diasCrecimiento, int precioBase) {
this.tipo = tipo;
this.diasCrecimiento = diasCrecimiento;
this.diasRegados = 0;
this.precioBase = precioBase;
this.listo = false;
}
public void regar() {
if (this.listo) {
System.out.println("El cultivo de " + tipo + " ya está listo para cosechar.");
return;
}
this.diasRegados++;
if (this.diasRegados >= this.diasCrecimiento) {
this.listo = true;
System.out.println("🌾 " + tipo + " ¡listo para cosechar!");
}
}
public boolean estaListo() {
return listo;
}
public String cosechar() {
if (!listo) {
return "";
}
this.listo = false;
this.diasRegados = 0;
return this.tipo;
}
public int getPrecioBase() {
return precioBase;
}
}
class Gallina {
private String nombre;
private int huevosPorDia;
private boolean alimentada;
public Gallina(String nombre, int huevosPorDia) {
this.nombre = nombre;
this.huevosPorDia = huevosPorDia;
this.alimentada = false;
}
public void alimentar() {
this.alimentada = true;
System.out.println("🌽 Se alimentó a " + this.nombre);
}
public int recolectarHuevos() {
if (!alimentada) {
System.out.println(this.nombre + " no está alimentada: no da huevos.");
return 0;
}
this.alimentada = false;
return this.huevosPorDia;
}
public String getNombre() {
return nombre;
}
}
class Mercado {
private String nombre;
private double multiplicador;
private int ventas;
public Mercado(String nombre, double multiplicador) {
this.nombre = nombre;
this.multiplicador = multiplicador;
this.ventas = 0;
}
public int vender(String producto, int precioBase) {
this.ventas++;
int total = (int) (precioBase * this.multiplicador);
System.out.println("💰 " + nombre + " pagó " + total + " por " + producto);
return total;
}
public String getNombre() {
return nombre;
}
public int getVentas() {
return ventas;
}
}
class Granjero {
private String nombre;
private int energia;
private int oro;
private int huevos;
private int nivelAgricola;
private Mercado mercado;
public Granjero(String nombre, int oro, Mercado mercado) {
this.nombre = nombre;
this.oro = oro;
this.mercado = mercado;
this.energia = 100;
this.huevos = 0;
this.nivelAgricola = 1;
}
public void regar(Cultivo cultivo) {
if (energia < 5) {
System.out.println("😴 " + nombre + " está muy cansado para regar.");
return;
}
energia -= 5;
cultivo.regar();
}
public void cosechar(Cultivo cultivo) {
String producto = cultivo.cosechar();
if (producto.isEmpty()) {
System.out.println("El cultivo de " + "todavía no está listo.");
return;
}
this.oro += this.mercado.vender(producto, cultivo.getPrecioBase() * this.nivelAgricola);
}
public void cuidarGallina(Gallina gallina) {
gallina.alimentar();
int huevos = gallina.recolectarHuevos();
this.huevos += huevos;
System.out.println("🥚 " + gallina.getNombre() + " dejó " + huevos + " huevos");
}
public void mostrarEstado() {
System.out.println(nombre + " | energía: " + energia + " | oro: " + oro + " | huevos: " + huevos + " | mercado: " + mercado.getNombre());
}
}
public class Main {
public static void main(String[] args) {
Mercado pierre = new Mercado("Tienda de Pierre", 1.25);
Granjero granjero = new Granjero("Avery", 500, pierre);
Cultivo papa = new Cultivo("Papa", 3, 40);
Cultivo girasol = new Cultivo("Girasol", 2, 25);
Gallina gallina = new Gallina("Gallina Clara", 1);
granjero.mostrarEstado();
granjero.regar(papa);
granjero.regar(papa);
granjero.cosechar(papa);
granjero.cuidarGallina(gallina);
granjero.cosechar(girasol);
granjero.mostrarEstado();
}
}1818. La vida de un Sim en su casa
🏡 The Sims🟠 4 clasesClase Principal: Sim · 4 clases en total · 3 conexiones (o-- / *--)0 / 4
18. La vida de un Sim en su casa
🏡 The Sims🟠 4 clasesEn The Sims cada personaje vive en una casa, usa muebles para cubrir necesidades y tiene una mascota que también necesita atención. Las necesidades bajan con el tiempo y se recuperan usando el mueble adecuado.
🎯 Misión POO: Crea Mueble (nombre, tipo, confort), Mascota (nombre, hambre, felicidad), Casa (direccion, dimensiones) y Sim (nombre, energia, higiene). Encadena la asociación completa: el Sim usa los muebles de su casa y cuida a su mascota.
💡 Métodos que puedes implementar
Mueble.usar(): sube la necesidad que cubre y gasta duraciónCasa.buscarMueble(tipo): devuelve el mueble que coincide con la necesidadCasa.agregarMueble(mueble): coloca el mueble dentro de la casaMascota.comer(alimento): baja el hambre de la mascotaMascota.jugar(): sube la felicidad de la mascotaSim.usarMueble(mueble): delega en el mueble y recupera energía o higieneSim.cuidarMascota(mascota): alimentar y jugar con la mascota de la casa
💡 Simulación Java Completa:Sim (Asociación avanzada)
Código Java funcional listo para compilar y ejecutar con la simulación en consola:
class Mueble {
private String nombre;
private String tipo;
private int confort;
private int precio;
private int durabilidad;
public Mueble(String nombre, String tipo, int confort, int precio) {
this.nombre = nombre;
this.tipo = tipo;
this.confort = confort;
this.precio = precio;
this.durabilidad = 100;
}
public int usar() {
if (this.durabilidad <= 0) {
return 0;
}
this.durabilidad -= 10;
return this.confort;
}
public boolean estaRoto() {
return this.durabilidad <= 0;
}
public String getTipo() {
return tipo;
}
public String getNombre() {
return nombre;
}
}
class Casa {
private String direccion;
private int dimensiones;
private int contadorMuebles;
public Casa(String direccion, int dimensiones) {
this.direccion = direccion;
this.dimensiones = dimensiones;
this.contadorMuebles = 0;
}
public void agregarMueble(Mueble mueble) {
this.contadorMuebles++;
System.out.println("🏠 " + direccion + " ahora tiene " + this.contadorMuebles + " muebles");
}
public int getMuebles() {
return contadorMuebles;
}
}
class Mascota {
private String nombre;
private int hambre;
private int felicidad;
private String especie;
public Mascota(String nombre, String especie) {
this.nombre = nombre;
this.especie = especie;
this.hambre = 50;
this.felicidad = 50;
}
public void comer(String alimento) {
this.hambre = Math.max(0, this.hambre - 25);
System.out.println("🥣 " + nombre + " comió " + alimento + " (hambre: " + this.hambre + ")");
}
public void jugar() {
this.felicidad += 10;
System.out.println("🎾 " + nombre + " jugó con su dueño (felicidad: " + this.felicidad + ")");
}
}
class Sim {
private String nombre;
private int energia;
private int higiene;
private int dinero;
private Casa casa;
private Mascota mascota;
public Sim(String nombre, int dinero, Casa casa, Mascota mascota) {
this.nombre = nombre;
this.dinero = dinero;
this.casa = casa;
this.mascota = mascota;
this.energia = 60;
this.higiene = 60;
}
public void comprarMueble(Mueble mueble) {
this.dinero -= 100;
this.casa.agregarMueble(mueble);
System.out.println("🛒 " + nombre + " compró " + mueble.getNombre() + " por 100 §");
}
public void usarMueble(Mueble mueble) {
int beneficio = mueble.usar();
if (mueble.getTipo().equals("ENERGIA")) {
this.energia = Math.min(100, this.energia + beneficio);
} else {
this.higiene = Math.min(100, this.higiene + beneficio);
}
System.out.println("🛋️ " + nombre + " usó " + mueble.getNombre() + " (+" + beneficio + ")");
}
public void cuidarMascota() {
this.mascota.comer("croqueta");
this.mascota.jugar();
}
public void mostrarEstado() {
System.out.println(nombre + " | energía: " + energia + " | higiene: " + higiene + " | dinero: " + dinero + " | muebles: " + casa.getMuebles());
}
}
public class Main {
public static void main(String[] args) {
Casa casa = new Casa("Vía Simulación 12", 60);
Mascota perrito = new Mascota("Simba", "perro");
Sim sim = new Sim("Bella", 1000, casa, perrito);
sim.mostrarEstado();
sim.usarMueble(new Mueble("Cama acogedora", "ENERGIA", 25, 300));
sim.comprarMueble(new Mueble("Ducha nueva", "HIGIENE", 20, 200));
sim.usarMueble(new Mueble("Ducha nueva", "HIGIENE", 20, 200));
sim.cuidarMascota();
sim.mostrarEstado();
}
}1919. El arquero de Skyrim y su equipo
🏹 The Elder Scrolls: Skyrim🟠 4 clasesClase Principal: Arquero · 4 clases en total · 3 conexiones (o-- / *--)0 / 4
19. El arquero de Skyrim y su equipo
🏹 The Elder Scrolls: Skyrim🟠 4 clasesUn arquero de Skyrim lleva un arco con una tension concreta, dispara flechas con daño y puntería diferentes y practica contra dianas a distintas distancias. Un arco de gran Premio hace más daño pero pesa más y cansa antes.
🎯 Misión POO: Crea Diana (distancia, tipo), Flecha (dano, punteria) y Arco (nombre, tension, peso) y Arquero (nombre, vida, arquitectura, arco, ultimaDiana). Modela la cadena completa: el arquero carga el arco, apunta a una diana y la flecha se clava según la distancia.
💡 Métodos que puedes implementar
Diana.getFactorDistancia(): cerca = 1.0, media = 0.8, lejos = 0.6Flecha.clavar(diana): daño real = dano * punteria * factorDistanciaArco.disparar(flecha): el arco aplica su tensión como bonus y se desgastaArco.puedeDisparar(): false si el peso cansa al arqueroArquero.apuntar(diana): guarda la diana objetivo y calcula la dificultadArquero.disparar(flecha, diana): encadena arco → flecha → diana y muestra el resultado
💡 Simulación Java Completa:Arquero (Asociación avanzada)
Código Java funcional listo para compilar y ejecutar con la simulación en consola:
class Diana {
private int distancia;
private String tipo;
private int dificultad;
public Diana(int distancia, String tipo, int dificultad) {
this.distancia = distancia;
this.tipo = tipo;
this.dificultad = dificultad;
}
public double getFactorDistancia() {
if (this.distancia <= 20) {
return 1.0;
}
if (this.distancia <= 50) {
return 0.8;
}
return 0.6;
}
public String getTipo() {
return tipo;
}
}
class Flecha {
private int dano;
private int punteria;
private boolean clavada;
public Flecha(int dano, int punteria) {
this.dano = dano;
this.punteria = punteria;
this.clavada = false;
}
public int clavar(Diana diana) {
this.clavada = true;
return (int) (this.dano * this.punteria * diana.getFactorDistancia());
}
public boolean estaClavada() {
return clavada;
}
}
class Arco {
private String nombre;
private int tension;
private int peso;
private int desgaste;
public Arco(String nombre, int tension, int peso) {
this.nombre = nombre;
this.tension = tension;
this.peso = peso;
this.desgaste = 0;
}
public boolean puedeDisparar() {
return this.desgaste < 50;
}
public int aplicarTension(Flecha flecha) {
this.desgaste += this.peso / 10;
return this.tension;
}
public String getNombre() {
return nombre;
}
}
class Arquero {
private String nombre;
private int vida;
private int arquitectura;
private Arco arco;
private Diana ultimaDiana;
private int flechasClavadas;
public Arquero(String nombre, int vida, int arquitectura, Arco arco) {
this.nombre = nombre;
this.vida = vida;
this.arquitectura = arquitectura;
this.arco = arco;
this.ultimaDiana = null;
this.flechasClavadas = 0;
}
public void apuntar(Diana diana) {
this.ultimaDiana = diana;
System.out.println("🎯 " + nombre + " apunta a la diana " + diana.getTipo());
}
public void disparar(Flecha flecha) {
if (this.ultimaDiana == null) {
System.out.println("Primero hay que apuntar a una diana.");
return;
}
if (!this.arco.puedeDisparar()) {
System.out.println("El arco " + this.arco.getNombre() + " está demasiado gastado.");
return;
}
int bonus = this.arco.aplicarTension(flecha);
int danoTotal = flecha.clavar(this.ultimaDiana) + bonus;
System.out.println("🏹 " + nombre + " clavó la flecha con " + danoTotal + " de daño (arco " + this.arco.getNombre() + ")");
this.flechasClavadas++;
}
public int getPunteria() {
return 10 + this.arquitectura;
}
public void mostrarEstado() {
System.out.println(nombre + " | vida: " + vida + " | puntería: " + getPunteria() + " | flechas clavadas: " + flechasClavadas);
}
}
public class Main {
public static void main(String[] args) {
Arco arcoLargo = new Arco("Arco Largo de Bosque", 12, 30);
Arquero arquero = new Arquero("Eorlund", 120, 40, arcoLargo);
Diana cercana = new Diana(15, "cercana", 10);
Diana lejana = new Diana(80, "lejana", 40);
arquero.mostrarEstado();
arquero.apuntar(cercana);
arquero.disparar(new Flecha(20, arquero.getPunteria() / 10));
arquero.apuntar(lejana);
arquero.disparar(new Flecha(20, 1));
arquero.mostrarEstado();
}
}2020. Aventura espacial: nave, planeta y mineral
🌌 Starfield🟠 4 clasesClase Principal: Astronauta · 4 clases en total · 3 conexiones (o-- / *--)0 / 4
20. Aventura espacial: nave, planeta y mineral
🌌 Starfield🟠 4 clasesEn una aventura espacial el astronauta pilota una nave, aterriza en planetas y recoge minerales para mejorar el combustible. Cada planeta tiene su propio tipo de mineral y su dificultad de extracción, y la nave consume combustible en cada salto.
🎯 Misión POO: Es el reto final: crea Nave (modelo, combustible, velocidad), Mineral (tipo, valor, rareza), Planeta (nombre, dificultad, atmosfera) y Astronauta (nombre, vida, nave, mochilaOro). Encadena la asociación completa y simula un viaje con dos planetas.
💡 Métodos que puedes implementar
Mineral.extraer(dificultad): el valor final depende de la rareza y de la dificultad del planetaPlaneta.explorar(): devuelve un mineral propio del planetaPlaneta.esPeligroso(): true si su atmósfera es hostilNave.viajar(planeta): consume combustible según la distancia y avisa si no alcanzaNave.recargar(menaje): suma combustible con la energía del mineralAstronauta.explorar(planeta): pide el mineral al planeta y lo guarda en la mochilaAstronauta.mostrarEstado(): inventario, combustible y vida
💡 Simulación Java Completa:Astronauta (Asociación avanzada)
Código Java funcional listo para compilar y ejecutar con la simulación en consola:
class Mineral {
private String tipo;
private int valor;
private String rareza;
private int energia;
public Mineral(String tipo, int valor, String rareza, int energia) {
this.tipo = tipo;
this.valor = valor;
this.rareza = rareza;
this.energia = energia;
}
public int extraer(int dificultad) {
int resultado = this.valor;
if (this.rareza.equals("RARO")) {
resultado = resultado * 2;
}
if (this.rareza.equals("LEGENDARIO")) {
resultado = resultado * 3;
}
return Math.max(1, resultado - dificultad);
}
public String getTipo() {
return tipo;
}
public int getEnergia() {
return energia;
}
}
class Planeta {
private String nombre;
private int distancia;
private int dificultad;
private String atmosfera;
public Planeta(String nombre, int distancia, int dificultad, String atmosfera) {
this.nombre = nombre;
this.distancia = distancia;
this.dificultad = dificultad;
this.atmosfera = atmosfera;
}
public Mineral explorar() {
System.out.println("🪐 Explorando " + this.nombre + "...");
if (this.dificultad > 5) {
return new Mineral("Uranio", 30, "RARO", 20);
}
return new Mineral("Hierro", 10, "COMUN", 8);
}
public boolean esPeligroso() {
return this.atmosfera.equals("HOSTIL");
}
public String getNombre() {
return nombre;
}
public int getDistancia() {
return distancia;
}
public int getDificultad() {
return dificultad;
}
}
class Nave {
private String modelo;
private int combustible;
private int velocidad;
private int capacidadTanque;
public Nave(String modelo, int capacidadTanque, int velocidad) {
this.modelo = modelo;
this.capacidadTanque = capacidadTanque;
this.combustible = capacidadTanque;
this.velocidad = velocidad;
}
public void viajar(Planeta planeta) {
int costo = planeta.getDistancia() / 10;
if (costo > this.combustible) {
System.out.println("⛽ No hay combustible suficiente para llegar a " + planeta.getNombre());
return;
}
this.combustible -= costo;
System.out.println("🚀 " + this.modelo + " viaja a " + planeta.getNombre() + " (combustible: " + this.combustible + ")");
}
public void recargar(Mineral menaje) {
int limite = this.capacidadTanque - this.combustible;
int carga = Math.min(limite, menaje.getEnergia());
this.combustible += carga;
System.out.println("⛽ Se recargó con " + menaje.getTipo() + ": +" + carga + " de combustible");
}
public int getCombustible() {
return combustible;
}
}
class Astronauta {
private String nombre;
private int vida;
private Nave nave;
private int oro;
private int mineralesRecolectados;
private Planeta destino;
public Astronauta(String nombre, int vida, Nave nave) {
this.nombre = nombre;
this.vida = vida;
this.nave = nave;
this.oro = 0;
this.mineralesRecolectados = 0;
this.destino = null;
}
public boolean viajar(Planeta planeta) {
int costo = planeta.getDistancia() / 10;
if (costo > this.nave.getCombustible()) {
return false;
}
this.nave.viajar(planeta);
this.destino = planeta;
return true;
}
public void explorar(Planeta planeta) {
Mineral mineral = planeta.explorar();
int valor = mineral.extraer(planeta.getDificultad());
this.oro += valor;
this.mineralesRecolectados++;
if (planeta.esPeligroso()) {
this.vida -= 10;
}
System.out.println("⛏️ " + this.nombre + " extrajo " + mineral.getTipo() + " por " + valor + " de oro");
}
public void recargarNave() {
Mineral auxiliar = new Mineral("Batería de protones", 5, "COMUN", 25);
this.nave.recargar(auxiliar);
}
public void mostrarEstado() {
String lugar = this.destino == null ? "en órbita" : this.destino.getNombre();
System.out.println(nombre + " | " + lugar + " | vida: " + vida + " | oro: " + oro + " | minerales: " + mineralesRecolectados + " | combustible: " + this.nave.getCombustible());
}
}
public class Main {
public static void main(String[] args) {
Nave nave = new Nave("Explorador MK-II", 100, 60);
Astronauta astronauta = new Astronauta("Riley", 90, nave);
Planeta viridia = new Planeta("Viridia", 30, 3, "AMIGABLE");
Planeta arkon = new Planeta("Arkon", 90, 7, "HOSTIL");
astronauta.mostrarEstado();
astronauta.viajar(viridia);
astronauta.explorar(viridia);
astronauta.recargarNave();
astronauta.viajar(arkon);
astronauta.explorar(arkon);
astronauta.mostrarEstado();
}
}2121. Gladiadores Medievales en la Arena
⚔️ RPG Medieval / Gladiadores🔴 expertoClase Principal: Luchador · 4 clases en total · 3 conexiones (o-- / *--)0 / 4
21. Gladiadores Medievales en la Arena
⚔️ RPG Medieval / Gladiadores🔴 expertoDos luchadores combaten por turnos en una arena medieval. Cada luchador posee una Espada que calcula el daño con probabilidad de crítico, un Escudo que mitiga impactos consumiendo durabilidad, y una lista de Pociones curativas en su mochila.
🎯 Misión POO: Crea las clases Espada, Escudo, Pocion y Luchador. Modela la asociación entre el Luchador y su equipamiento. En el método ejecutarTurno(rival), el luchador decide si atacar con su espada o consumir una poción si su vida baja de 30.
💡 Simulación Java Completa:Luchador (Combate por turnos)
Código Java funcional listo para compilar y ejecutar con la simulación en consola:
import java.util.ArrayList;
import java.util.List;
class Espada {
private String nombre;
private int danioBase;
private double probCritico;
public Espada(String nombre, int danioBase, double probCritico) {
this.nombre = nombre;
this.danioBase = danioBase;
this.probCritico = probCritico;
}
public int calcularDanio() {
boolean esCritico = Math.random() < probCritico;
int danioFinal = esCritico ? danioBase * 2 : danioBase;
if (esCritico) System.out.println(" 💥 ¡Golpe Crítico con " + nombre + "!");
return danioFinal;
}
public String getNombre() { return nombre; }
}
class Escudo {
private String nombre;
private int defensa;
private int durabilidad;
public Escudo(String nombre, int defensa, int durabilidad) {
this.nombre = nombre;
this.defensa = defensa;
this.durabilidad = durabilidad;
}
public int mitigarDanio(int danio) {
if (durabilidad <= 0) return danio;
int danioMitigado = Math.max(0, danio - defensa);
durabilidad--;
System.out.println(" 🛡️ " + nombre + " absorbió " + (danio - danioMitigado) + " pts de daño. (Durabilidad restante: " + durabilidad + ")");
return danioMitigado;
}
}
class Pocion {
private String nombre;
private int puntosCuracion;
private boolean usada;
public Pocion(String nombre, int puntosCuracion) {
this.nombre = nombre;
this.puntosCuracion = puntosCuracion;
this.usada = false;
}
public int aplicar(Luchador objetivo) {
if (usada) return 0;
this.usada = true;
return puntosCuracion;
}
public boolean isUsada() { return usada; }
public String getNombre() { return nombre; }
}
class Luchador {
private String nombre;
private int vida;
private int energia;
private Espada arma;
private Escudo escudo;
private List<Pocion> pociones;
public Luchador(String nombre, int vida, int energia, Espada arma, Escudo escudo) {
this.nombre = nombre;
this.vida = vida;
this.energia = energia;
this.arma = arma;
this.escudo = escudo;
this.pociones = new ArrayList<>();
}
public void agregarPocion(Pocion p) {
this.pociones.add(p);
}
public void atacar(Luchador rival) {
System.out.println("⚔️ " + nombre + " ataca a " + rival.getNombre() + " con " + arma.getNombre() + "!");
int danio = arma.calcularDanio();
rival.recibirDanio(danio);
}
public void recibirDanio(int danioEntrante) {
int danioFinal = escudo != null ? escudo.mitigarDanio(danioEntrante) : danioEntrante;
this.vida = Math.max(0, this.vida - danioFinal);
System.out.println(" 💔 " + nombre + " recibe " + danioFinal + " de daño. Vida restante: " + this.vida + " HP.");
}
public void usarPocion(int indice) {
if (indice >= 0 && indice < pociones.size()) {
Pocion p = pociones.get(indice);
if (!p.isUsada()) {
int curacion = p.aplicar(this);
this.vida += curacion;
System.out.println("🧪 " + nombre + " usó " + p.getNombre() + " y recuperó " + curacion + " HP. Vida actual: " + this.vida);
}
}
}
public boolean estaVivo() { return this.vida > 0; }
public String getNombre() { return nombre; }
public int getVida() { return vida; }
}
public class Main {
public static void main(String[] args) {
Espada espadaExcalibur = new Espada("Excalibur", 25, 0.35);
Escudo escudoTorre = new Escudo("Escudo de Roble", 10, 3);
Luchador lancelot = new Luchador("Sir Lancelot", 100, 50, espadaExcalibur, escudoTorre);
lancelot.agregarPocion(new Pocion("Elixir Mayor", 30));
Espada hachaGuerra = new Espada("Filo Oscuro", 22, 0.20);
Escudo broquelHierro = new Escudo("Broquel de Hierro", 8, 4);
Luchador mordred = new Luchador("Mordred", 95, 40, hachaGuerra, broquelHierro);
System.out.println("=== 🔔 INICIO DEL DUELO POR TURNOS ===");
// Turno 1
lancelot.atacar(mordred);
// Turno 2
mordred.atacar(lancelot);
// Turno 3 - Curación
lancelot.usarPocion(0);
}
}2222. Duelo de Entrenadores Pokémon
⚡ Pokémon🔴 expertoClase Principal: Entrenador · 4 clases en total · 3 conexiones (o-- / *--)0 / 4
22. Duelo de Entrenadores Pokémon
⚡ Pokémon🔴 expertoDos entrenadores se enfrentan en la liga. El Entrenador comanda un Pokémon activo y lleva en su mochila una lista de Items de Curación. El Pokémon posee una lista de 4 Movimientos con tipo, potencia y PP.
🎯 Misión POO: Modela Entrenador, Pokemon, Movimiento e ItemCura. En cada turno, el entrenador ordena ejecutar un movimiento por slot de su Pokémon contra el rival o aplica una Poción de su mochila.
💡 Simulación Java Completa:Entrenador (Combate por turnos)
Código Java funcional listo para compilar y ejecutar con la simulación en consola:
import java.util.ArrayList;
import java.util.List;
class Movimiento {
private String nombre;
private String tipoElemento;
private int potencia;
private int ppActuales;
public Movimiento(String nombre, String tipoElemento, int potencia, int ppMax) {
this.nombre = nombre;
this.tipoElemento = tipoElemento;
this.potencia = potencia;
this.ppActuales = ppMax;
}
public boolean consumirPP() {
if (ppActuales > 0) {
ppActuales--;
return true;
}
return false;
}
public String getNombre() { return nombre; }
public int getPotencia() { return potencia; }
public int getPpActuales() { return ppActuales; }
}
class ItemCura {
private String nombre;
private int puntosRestaurados;
private int cantidad;
public ItemCura(String nombre, int puntosRestaurados, int cantidad) {
this.nombre = nombre;
this.puntosRestaurados = puntosRestaurados;
this.cantidad = cantidad;
}
public int consumir() {
if (cantidad > 0) {
cantidad--;
return puntosRestaurados;
}
return 0;
}
public String getNombre() { return nombre; }
public int getCantidad() { return cantidad; }
}
class Pokemon {
private String especie;
private String tipo;
private int hpMax;
private int hpActual;
private List<Movimiento> movimientos;
public Pokemon(String especie, String tipo, int hpMax) {
this.especie = especie;
this.tipo = tipo;
this.hpMax = hpMax;
this.hpActual = hpMax;
this.movimientos = new ArrayList<>();
}
public void aprenderMovimiento(Movimiento m) {
if (movimientos.size() < 4) movimientos.add(m);
}
public Movimiento ejecutarMovimiento(int slot) {
if (slot >= 0 && slot < movimientos.size()) {
Movimiento m = movimientos.get(slot);
if (m.consumirPP()) return m;
}
return null;
}
public void recibirDanio(int danio) {
this.hpActual = Math.max(0, this.hpActual - danio);
System.out.println(" 💥 " + especie + " recibió " + danio + " de daño. (PS: " + hpActual + "/" + hpMax + ")");
}
public void curar(int hp) {
this.hpActual = Math.min(hpMax, this.hpActual + hp);
System.out.println(" ✨ " + especie + " recuperó salud. (PS: " + hpActual + "/" + hpMax + ")");
}
public boolean estaDebilitado() { return hpActual <= 0; }
public String getEspecie() { return especie; }
public int getHpActual() { return hpActual; }
}
class Entrenador {
private String nombre;
private Pokemon pokemonActivo;
private List<ItemCura> mochila;
public Entrenador(String nombre, Pokemon pokemonActivo) {
this.nombre = nombre;
this.pokemonActivo = pokemonActivo;
this.mochila = new ArrayList<>();
}
public void agregarItem(ItemCura item) { mochila.add(item); }
public void ordenarAtaque(Entrenador rival, int slot) {
System.out.println("📢 " + nombre + ": ¡" + pokemonActivo.getEspecie() + ", adelante!");
Movimiento mov = pokemonActivo.ejecutarMovimiento(slot);
if (mov != null) {
System.out.println(" 🔥 Usó " + mov.getNombre() + " (Potencia: " + mov.getPotencia() + ")!");
rival.getPokemonActivo().recibirDanio(mov.getPotencia());
} else {
System.out.println(" ❌ No quedan PP para ese movimiento.");
}
}
public void usarItemMochila(int indiceItem) {
if (indiceItem >= 0 && indiceItem < mochila.size()) {
ItemCura item = mochila.get(indiceItem);
int curacion = item.consumir();
if (curacion > 0) {
System.out.println("🎒 " + nombre + " usó " + item.getNombre() + " en " + pokemonActivo.getEspecie() + "!");
pokemonActivo.curar(curacion);
}
}
}
public boolean tienePokemonVivo() { return !pokemonActivo.estaDebilitado(); }
public Pokemon getPokemonActivo() { return pokemonActivo; }
public String getNombre() { return nombre; }
}
public class Main {
public static void main(String[] args) {
Pokemon pikachu = new Pokemon("Pikachu", "Eléctrico", 90);
pikachu.aprenderMovimiento(new Movimiento("Impactrueno", "Eléctrico", 35, 15));
pikachu.aprenderMovimiento(new Movimiento("Ataque Rápido", "Normal", 25, 20));
Pokemon charizard = new Pokemon("Charizard", "Fuego", 120);
charizard.aprenderMovimiento(new Movimiento("Lanzallamas", "Fuego", 40, 10));
Entrenador ash = new Entrenador("Ash Ketchum", pikachu);
ash.agregarItem(new ItemCura("Superpocion", 50, 2));
Entrenador red = new Entrenador("Red", charizard);
// Turnos
ash.ordenarAtaque(red, 0);
red.ordenarAtaque(ash, 0);
ash.usarItemMochila(0);
}
}2323. Duelo de Cartas TCG (Yu-Gi-Oh!)
🎴 Yu-Gi-Oh! / TCG🔴 expertoClase Principal: Duelista · 3 clases en total · 3 conexiones (o-- / *--)0 / 4
23. Duelo de Cartas TCG (Yu-Gi-Oh!)
🎴 Yu-Gi-Oh! / TCG🔴 expertoDos duelistas se baten en duelo con 4000 LP. Cada duelista invoca un Monstruo en su zona de batalla, activa Cartas Mágicas de potenciación y envía cartas destruidas al Cementerio.
🎯 Misión POO: Implementa Duelista, CartaMonstruo, CartaMagica y ZonaDuelo. El duelista declara ataque entre su monstruo y el monstruo rival; la diferencia de ATK se resta a los LP del perdedor.
💡 Simulación Java Completa:Duelista (Combate por turnos)
Código Java funcional listo para compilar y ejecutar con la simulación en consola:
import java.util.ArrayList;
import java.util.List;
class CartaMonstruo {
private String nombre;
private int estrellas;
private int ataqueATK;
private int defensaDEF;
private boolean modoAtaque;
public CartaMonstruo(String nombre, int estrellas, int ataqueATK, int defensaDEF) {
this.nombre = nombre;
this.estrellas = estrellas;
this.ataqueATK = ataqueATK;
this.defensaDEF = defensaDEF;
this.modoAtaque = true;
}
public void potenciarATK(int bonus) {
this.ataqueATK += bonus;
System.out.println(" ✨ " + nombre + " aumentó su ATK a " + ataqueATK + "!");
}
public String getNombre() { return nombre; }
public int getAtaqueATK() { return ataqueATK; }
public int getDefensaDEF() { return defensaDEF; }
}
class CartaMagica {
private String nombre;
private int bonusATK;
private boolean fueUsada;
public CartaMagica(String nombre, int bonusATK) {
this.nombre = nombre;
this.bonusATK = bonusATK;
this.fueUsada = false;
}
public void aplicarEfecto(CartaMonstruo objetivo) {
if (!fueUsada && objetivo != null) {
System.out.println("🎴 ¡Activando Carta Mágica: " + nombre + "!");
objetivo.potenciarATK(bonusATK);
this.fueUsada = true;
}
}
}
class Duelista {
private String nombre;
private int puntosVidaLP;
private CartaMonstruo monstruoCampo;
private CartaMagica magicaActiva;
private List<CartaMonstruo> cementerio;
public Duelista(String nombre, int puntosVidaLP) {
this.nombre = nombre;
this.puntosVidaLP = puntosVidaLP;
this.cementerio = new ArrayList<>();
}
public void invocarMonstruo(CartaMonstruo m) {
this.monstruoCampo = m;
System.out.println("🎴 " + nombre + " invoca a " + m.getNombre() + " (ATK: " + m.getAtaqueATK() + "/DEF: " + m.getDefensaDEF() + ")!");
}
public void activarMagia(CartaMagica magia) {
this.magicaActiva = magia;
if (monstruoCampo != null) magia.aplicarEfecto(monstruoCampo);
}
public void declararAtaque(Duelista rival) {
if (this.monstruoCampo == null) return;
System.out.println("⚔️ " + nombre + " declara ataque con " + monstruoCampo.getNombre() + "!");
CartaMonstruo rivalMonstruo = rival.getMonstruoCampo();
if (rivalMonstruo != null) {
int diff = this.monstruoCampo.getAtaqueATK() - rivalMonstruo.getAtaqueATK();
if (diff > 0) {
System.out.println(" 💥 " + rivalMonstruo.getNombre() + " es destruido!");
rival.enviarAlCementerio(rivalMonstruo);
rival.reducirLP(diff);
} else if (diff < 0) {
System.out.println(" 💥 El ataque falló y " + monstruoCampo.getNombre() + " fue destruido!");
this.enviarAlCementerio(this.monstruoCampo);
this.reducirLP(-diff);
} else {
System.out.println(" 💥 ¡Ambos monstruos se destruyen mutuamente!");
this.enviarAlCementerio(this.monstruoCampo);
rival.enviarAlCementerio(rivalMonstruo);
}
}
}
public void enviarAlCementerio(CartaMonstruo m) {
cementerio.add(m);
if (monstruoCampo == m) monstruoCampo = null;
}
public void reducirLP(int danio) {
this.puntosVidaLP = Math.max(0, this.puntosVidaLP - danio);
System.out.println(" 💔 " + nombre + " pierde " + danio + " LP. (LP restantes: " + puntosVidaLP + ")");
}
public boolean estaDerrotado() { return puntosVidaLP <= 0; }
public CartaMonstruo getMonstruoCampo() { return monstruoCampo; }
public String getNombre() { return nombre; }
}
public class Main {
public static void main(String[] args) {
Duelista yugi = new Duelista("Yugi Muto", 4000);
Duelista kaiba = new Duelista("Seto Kaiba", 4000);
yugi.invocarMonstruo(new CartaMonstruo("Mago Oscuro", 7, 2500, 2100));
kaiba.invocarMonstruo(new CartaMonstruo("Dragón Blanco de Ojos Azules", 8, 3000, 2500));
// Yugi potencia a su monstruo con magia
yugi.activarMagia(new CartaMagica("Libro de Magia Secreta", 700));
// Yugi ataca a Kaiba
yugi.declararAtaque(kaiba);
}
}2424. Combate PvP en Arena de Bloques
⛏️ Minecraft🔴 expertoClase Principal: JugadorSteve · 4 clases en total · 3 conexiones (o-- / *--)0 / 4
24. Combate PvP en Arena de Bloques
⛏️ Minecraft🔴 expertoDos jugadores en un servidor PvP de Minecraft combaten con Espadas de Diamante encantadas, Pecheras que absorben daño según su durabilidad y Manzanas Doradas de regeneración.
🎯 Misión POO: Modela JugadorSteve, EspadaDiamante, ArmaduraPechera y ManzanaDorada. En cada turno se calcula el golpe crítico con probabilidad y el consumo de manzanas si la salud está crítica.
💡 Simulación Java Completa:JugadorSteve (Combate por turnos)
Código Java funcional listo para compilar y ejecutar con la simulación en consola:
import java.util.ArrayList;
import java.util.List;
class EspadaDiamante {
private int nivelFilo;
private double danioBase;
public EspadaDiamante(int nivelFilo, double danioBase) {
this.nivelFilo = nivelFilo;
this.danioBase = danioBase;
}
public double calcularGolpe() {
boolean critico = Math.random() < 0.30;
double danio = danioBase + (nivelFilo * 1.25);
if (critico) {
danio *= 1.5;
System.out.println(" 💥 ¡Golpe Crítico con salto de espada!");
}
return danio;
}
}
class ArmaduraPechera {
private int proteccionPuntos;
private int durabilidad;
public ArmaduraPechera(int proteccionPuntos, int durabilidad) {
this.proteccionPuntos = proteccionPuntos;
this.durabilidad = durabilidad;
}
public double mitigarDanio(double danio) {
if (durabilidad <= 0) return danio;
double reduccion = proteccionPuntos * 0.4;
durabilidad -= 2;
return Math.max(1.0, danio - reduccion);
}
}
class ManzanaDorada {
private double corazonesRegeneracion;
private boolean esEncantada;
private boolean consumida;
public ManzanaDorada(double corazones, boolean encantada) {
this.corazonesRegeneracion = corazones;
this.esEncantada = encantada;
this.consumida = false;
}
public double consumir() {
if (!consumida) {
consumida = true;
return corazonesRegeneracion;
}
return 0;
}
}
class JugadorSteve {
private String apodo;
private double corazonesVida;
private EspadaDiamante armaPrincipal;
private ArmaduraPechera pechera;
private List<ManzanaDorada> inventarioManzanas;
public JugadorSteve(String apodo, double corazones, EspadaDiamante arma, ArmaduraPechera pechera) {
this.apodo = apodo;
this.corazonesVida = corazones;
this.armaPrincipal = arma;
this.pechera = pechera;
this.inventarioManzanas = new ArrayList<>();
}
public void agregarManzana(ManzanaDorada m) { inventarioManzanas.add(m); }
public void golpear(JugadorSteve enemigo) {
System.out.println("🗡️ " + apodo + " ataca a " + enemigo.getApodo() + "!");
double danio = armaPrincipal.calcularGolpe();
enemigo.recibirImpacto(danio);
}
public void recibirImpacto(double danioFisico) {
double danioFinal = pechera != null ? pechera.mitigarDanio(danioFisico) : danioFisico;
this.corazonesVida = Math.max(0.0, this.corazonesVida - danioFinal);
System.out.printf(" 💔 %s recibió %.1f de daño. Corazones: %.1f/20.0\n", apodo, danioFinal, corazonesVida);
}
public void comerManzana(int indice) {
if (indice >= 0 && indice < inventarioManzanas.size()) {
double curado = inventarioManzanas.get(indice).consumir();
if (curado > 0) {
this.corazonesVida = Math.min(20.0, this.corazonesVida + curado);
System.out.printf("🍎 %s comió Manzana Dorada y regeneró %.1f corazones! (Total: %.1f)\n", apodo, curado, corazonesVida);
}
}
}
public boolean estaMuerto() { return corazonesVida <= 0; }
public String getApodo() { return apodo; }
}
public class Main {
public static void main(String[] args) {
EspadaDiamante espada1 = new EspadaDiamante(5, 7.0);
ArmaduraPechera pechera1 = new ArmaduraPechera(8, 100);
JugadorSteve steve = new JugadorSteve("Steve_Pro", 20.0, espada1, pechera1);
steve.agregarManzana(new ManzanaDorada(6.0, true));
EspadaDiamante espada2 = new EspadaDiamante(4, 7.0);
ArmaduraPechera pechera2 = new ArmaduraPechera(6, 80);
JugadorSteve alex = new JugadorSteve("Alex_Gamer", 20.0, espada2, pechera2);
steve.golpear(alex);
alex.golpear(steve);
alex.golpear(steve);
steve.comerManzana(0);
}
}2525. Duelo 1v1 Battle Royale (Fortnite)
🎯 Fortnite / Battle Royale🔴 expertoClase Principal: JugadorBR · 4 clases en total · 3 conexiones (o-- / *--)0 / 4
25. Duelo 1v1 Battle Royale (Fortnite)
🎯 Fortnite / Battle Royale🔴 expertoDos supervivientes en el círculo final intercambian disparos de escopeta Pump, erigen muros de madera para cubrirse y beben mini escudos para regenerar protección.
🎯 Misión POO: Modela JugadorBR, EscopetaPump, MuroConstruccion y MiniEscudo. Si el jugador tiene un muro en pie, el daño del disparo rival destruye primero el muro antes de impactar el escudo/salud.
💡 Simulación Java Completa:JugadorBR (Combate por turnos)
Código Java funcional listo para compilar y ejecutar con la simulación en consola:
import java.util.ArrayList;
import java.util.List;
class EscopetaPump {
private String rareza;
private int danioPorPerdigon;
private int perdigonesPorTiro;
public EscopetaPump(String rareza, int danioPorPerdigon, int perdigones) {
this.rareza = rareza;
this.danioPorPerdigon = danioPorPerdigon;
this.perdigonesPorTiro = perdigones;
}
public int calcularDisparo() {
int impactados = (int) (Math.random() * 4) + 6; // 6 a 10 perdigones
int total = impactados * danioPorPerdigon;
System.out.println(" 💥 Pump " + rareza + " impactó " + impactados + "/" + perdigonesPorTiro + " perdigones (" + total + " dmg)!");
return total;
}
}
class MuroConstruccion {
private String material;
private int saludMuro;
public MuroConstruccion(String material, int saludInicial) {
this.material = material;
this.saludMuro = saludInicial;
}
public int absorberDanio(int danio) {
if (saludMuro <= 0) return danio;
if (danio >= saludMuro) {
int sobrante = danio - saludMuro;
System.out.println(" 🧱 ¡El muro de " + material + " fue destruido!");
saludMuro = 0;
return sobrante;
} else {
saludMuro -= danio;
System.out.println(" 🧱 El muro de " + material + " bloqueó todo el daño (Salud muro restante: " + saludMuro + ")");
return 0;
}
}
public boolean isEnPie() { return saludMuro > 0; }
}
class MiniEscudo {
private int valorEscudo;
private boolean consumido;
public MiniEscudo(int valorEscudo) {
this.valorEscudo = valorEscudo;
this.consumido = false;
}
public int aplicar(int escudoActual) {
if (!consumido && escudoActual < 50) {
consumido = true;
return Math.min(valorEscudo, 50 - escudoActual);
}
return 0;
}
}
class JugadorBR {
private String gamerTag;
private int salud;
private int escudo;
private EscopetaPump arma;
private MuroConstruccion muroActivo;
private List<MiniEscudo> inventarioMinis;
public JugadorBR(String gamerTag, EscopetaPump arma) {
this.gamerTag = gamerTag;
this.salud = 100;
this.escudo = 50;
this.arma = arma;
this.inventarioMinis = new ArrayList<>();
}
public void agregarMini(MiniEscudo mini) { inventarioMinis.add(mini); }
public void construirMuro(String material) {
this.muroActivo = new MuroConstruccion(material, 150);
System.out.println("🏗️ " + gamerTag + " levantó una pared de " + material + "!");
}
public void dispararEscopeta(JugadorBR rival) {
System.out.println("🎯 " + gamerTag + " dispara su Pump contra " + rival.getGamerTag() + "!");
int danio = arma.calcularDisparo();
rival.recibirImpacto(danio);
}
public void recibirImpacto(int danio) {
int danioRestante = (muroActivo != null && muroActivo.isEnPie()) ? muroActivo.absorberDanio(danio) : danio;
if (danioRestante > 0) {
if (escudo > 0) {
int absorbidoEscudo = Math.min(escudo, danioRestante);
escudo -= absorbidoEscudo;
danioRestante -= absorbidoEscudo;
}
salud = Math.max(0, salud - danioRestante);
System.out.println(" 💔 " + gamerTag + " -> Salud: " + salud + " | Escudo: " + escudo);
}
}
public void beberMini(int indice) {
if (indice >= 0 && indice < inventarioMinis.size()) {
int recargado = inventarioMinis.get(indice).aplicar(escudo);
if (recargado > 0) {
escudo += recargado;
System.out.println("🧪 " + gamerTag + " bebió un Mini (+ " + recargado + " escudo). Escudo total: " + escudo);
}
}
}
public String getGamerTag() { return gamerTag; }
}
public class Main {
public static void main(String[] args) {
EscopetaPump pumpDorada = new EscopetaPump("Legendaria", 11, 10);
JugadorBR ninja = new JugadorBR("Ninja", pumpDorada);
ninja.agregarMini(new MiniEscudo(25));
EscopetaPump pumpAzul = new EscopetaPump("Rara", 9, 10);
JugadorBR tfue = new JugadorBR("Tfue", pumpAzul);
ninja.dispararEscopeta(tfue);
tfue.construirMuro("Madera");
ninja.dispararEscopeta(tfue);
tfue.beberMini(0);
}
}2626. Duelo de Cenizas (Dark Souls / Elden Ring)
🔥 Dark Souls / Soulslike🔴 expertoClase Principal: CaballeroSinLuz · 4 clases en total · 3 conexiones (o-- / *--)0 / 4
26. Duelo de Cenizas (Dark Souls / Elden Ring)
🔥 Dark Souls / Soulslike🔴 expertoUn SinLuz desafía a un Caballero Negro. Cada combatiente gestiona su barra de Estamina para empuñar UltraEspadas pesadas y Frascos de Estus para recuperar PS.
🎯 Misión POO: Modela CaballeroSinLuz, UltraEspada, FrascoEstus y TalismanProteccion. Los ataques consumen estamina; si el combatiente no tiene estamina suficiente, su golpe se cancela.
💡 Simulación Java Completa:CaballeroSinLuz (Combate por turnos)
Código Java funcional listo para compilar y ejecutar con la simulación en consola:
class UltraEspada {
private String nombre;
private int danioFisico;
private int costoEstamina;
public UltraEspada(String nombre, int danio, int costoEstamina) {
this.nombre = nombre;
this.danioFisico = danio;
this.costoEstamina = costoEstamina;
}
public int calcularGolpe() { return danioFisico; }
public int getCostoEstamina() { return costoEstamina; }
public String getNombre() { return nombre; }
}
class FrascoEstus {
private int nivelRefuerzo;
private int curacionBase;
private int usosRestantes;
public FrascoEstus(int refuerzo, int curacion, int usos) {
this.nivelRefuerzo = refuerzo;
this.curacionBase = curacion + (refuerzo * 25);
this.usosRestantes = usos;
}
public int beber() {
if (usosRestantes > 0) {
usosRestantes--;
return curacionBase;
}
return 0;
}
public int getUsosRestantes() { return usosRestantes; }
}
class TalismanProteccion {
private double reduccionDanioPorcentaje;
public TalismanProteccion(double reduccion) {
this.reduccionDanioPorcentaje = reduccion;
}
public int filtrarDanio(int danio) {
return (int) (danio * (1.0 - reduccionDanioPorcentaje));
}
}
class CaballeroSinLuz {
private String nombre;
private int puntosVidaPS;
private int estamina;
private UltraEspada armaPesada;
private FrascoEstus frasco;
private TalismanProteccion talisman;
public CaballeroSinLuz(String nombre, int ps, int estamina, UltraEspada arma, FrascoEstus frasco, TalismanProteccion talisman) {
this.nombre = nombre;
this.puntosVidaPS = ps;
this.estamina = estamina;
this.armaPesada = arma;
this.frasco = frasco;
this.talisman = talisman;
}
public void ejecutarTajo(CaballeroSinLuz rival) {
if (estamina >= armaPesada.getCostoEstamina()) {
estamina -= armaPesada.getCostoEstamina();
System.out.println("⚔️ " + nombre + " descarga un tajo colosal con " + armaPesada.getNombre() + "! (Estamina: " + estamina + ")");
rival.recibirGolpe(armaPesada.calcularGolpe());
} else {
System.out.println("⚠️ " + nombre + " no tiene suficiente estamina para blandir su arma!");
}
}
public void beberEstus() {
int curado = frasco.beber();
if (curado > 0) {
puntosVidaPS += curado;
System.out.println("🔥 " + nombre + " bebió Frasco de Estus (+ " + curado + " PS). Salud actual: " + puntosVidaPS + " (Estus: " + frasco.getUsosRestantes() + ")");
}
}
public void recibirGolpe(int danio) {
int danioFinal = talisman != null ? talisman.filtrarDanio(danio) : danio;
puntosVidaPS = Math.max(0, puntosVidaPS - danioFinal);
System.out.println(" 💔 " + nombre + " sufre " + danioFinal + " de daño. PS restantes: " + puntosVidaPS);
}
public void regenerarEstamina() {
estamina += 30;
System.out.println("💨 " + nombre + " recuperó el aliento (+30 estamina).");
}
public String getNombre() { return nombre; }
}
public class Main {
public static void main(String[] args) {
UltraEspada espadonGuts = new UltraEspada("Espadón de Ceniza", 48, 35);
FrascoEstus estus = new FrascoEstus(2, 60, 3);
TalismanProteccion talismanDragon = new TalismanProteccion(0.15);
CaballeroSinLuz heroe = new CaballeroSinLuz("Latente de Lothric", 160, 70, espadonGuts, estus, talismanDragon);
CaballeroSinLuz boss = new CaballeroSinLuz("Caballero Negro", 180, 60, new UltraEspada("Hacha de Caballero", 42, 30), new FrascoEstus(0, 0, 0), null);
heroe.ejecutarTajo(boss);
boss.ejecutarTajo(heroe);
heroe.beberEstus();
}
}2727. Duelo 1v1 en Mid Lane (League of Legends)
🏆 League of Legends / MOBA🔴 expertoClase Principal: Campeon · 4 clases en total · 3 conexiones (o-- / *--)0 / 4
27. Duelo 1v1 en Mid Lane (League of Legends)
🏆 League of Legends / MOBA🔴 expertoDos campeones se enfrentan en la línea central. Cada campeón tiene estadísticas de AP/AD potenciadas por un Objeto Mítico, lanza su Habilidad Q gastando maná y bebe Pociones Corruptas.
🎯 Misión POO: Modela Campeon, ObjetoMitico, HabilidadQ y PocionCorrupta. En cada turno se comprueba el enfriamiento y coste de maná de la habilidad antes de infligir daño al rival.
💡 Simulación Java Completa:Campeon (Combate por turnos)
Código Java funcional listo para compilar y ejecutar con la simulación en consola:
import java.util.ArrayList;
import java.util.List;
class ObjetoMitico {
private String nombre;
private int ataqueAD;
private int poderHabilidadAP;
public ObjetoMitico(String nombre, int ad, int ap) {
this.nombre = nombre;
this.ataqueAD = ad;
this.poderHabilidadAP = ap;
}
public int getAtaqueAD() { return ataqueAD; }
public int getPoderHabilidadAP() { return poderHabilidadAP; }
}
class HabilidadQ {
private String nombreHabilidad;
private int danioBase;
private int costoMana;
private double escaladoAP;
public HabilidadQ(String nombre, int danioBase, int costoMana, double escaladoAP) {
this.nombreHabilidad = nombre;
this.danioBase = danioBase;
this.costoMana = costoMana;
this.escaladoAP = escaladoAP;
}
public int calcularDanioTotal(int apCampeon) {
return danioBase + (int) (apCampeon * escaladoAP);
}
public int getCostoMana() { return costoMana; }
public String getNombreHabilidad() { return nombreHabilidad; }
}
class PocionCorrupta {
private int cargas;
private int curaSalud;
private int curaMana;
public PocionCorrupta(int cargas, int curaSalud, int curaMana) {
this.cargas = cargas;
this.curaSalud = curaSalud;
this.curaMana = curaMana;
}
public boolean usarCarga() {
if (cargas > 0) {
cargas--;
return true;
}
return false;
}
public int getCuraSalud() { return curaSalud; }
public int getCuraMana() { return curaMana; }
}
class Campeon {
private String nombreCampeon;
private int saludHP;
private int manaMP;
private ObjetoMitico itemMitico;
private HabilidadQ habilidadQ;
private List<PocionCorrupta> pociones;
public Campeon(String nombre, int hp, int mp, ObjetoMitico item, HabilidadQ q) {
this.nombreCampeon = nombre;
this.saludHP = hp;
this.manaMP = mp;
this.itemMitico = item;
this.habilidadQ = q;
this.pociones = new ArrayList<>();
}
public void agregarPocion(PocionCorrupta p) { pociones.add(p); }
public void lanzarHabilidadQ(Campeon rival) {
if (manaMP >= habilidadQ.getCostoMana()) {
manaMP -= habilidadQ.getCostoMana();
int apTotal = itemMitico != null ? itemMitico.getPoderHabilidadAP() : 0;
int danio = habilidadQ.calcularDanioTotal(apTotal);
System.out.println("✨ " + nombreCampeon + " lanza [" + habilidadQ.getNombreHabilidad() + "]!");
rival.recibirDanio(danio);
} else {
System.out.println("⚠️ " + nombreCampeon + " no tiene suficiente maná!");
}
}
public void autoAtaque(Campeon rival) {
int ad = 40 + (itemMitico != null ? itemMitico.getAtaqueAD() : 0);
System.out.println("🗡️ " + nombreCampeon + " conecta un básico a " + rival.getNombreCampeon() + "!");
rival.recibirDanio(ad);
}
public void recibirDanio(int danio) {
this.saludHP = Math.max(0, this.saludHP - danio);
System.out.println(" 💥 " + nombreCampeon + " recibió " + danio + " dmg. (HP: " + saludHP + ")");
}
public void consumirPocion(int indice) {
if (indice >= 0 && indice < pociones.size()) {
PocionCorrupta pot = pociones.get(indice);
if (pot.usarCarga()) {
saludHP += pot.getCuraSalud();
manaMP += pot.getCuraMana();
System.out.println("🧪 " + nombreCampeon + " consumió poción corrupta (+HP/+MP).");
}
}
}
public String getNombreCampeon() { return nombreCampeon; }
}
public class Main {
public static void main(String[] args) {
ObjetoMitico ecoLuden = new ObjetoMitico("Eco de Luden", 0, 80);
HabilidadQ orbeEngano = new HabilidadQ("Orbe del Engaño", 55, 40, 0.70);
Campeon ahri = new Campeon("Ahri", 280, 200, ecoLuden, orbeEngano);
ahri.agregarPocion(new PocionCorrupta(3, 40, 30));
ObjetoMitico tempestadLuden = new ObjetoMitico("Tempestad de Luden", 0, 70);
HabilidadQ desintegrar = new HabilidadQ("Desintegrar", 50, 35, 0.65);
Campeon annie = new Campeon("Annie", 270, 190, tempestadLuden, desintegrar);
ahri.lanzarHabilidadQ(annie);
annie.lanzarHabilidadQ(ahri);
ahri.consumirPocion(0);
}
}2828. Torneo de Guerreros Z (Dragon Ball)
🐉 Dragon Ball Z🔴 expertoClase Principal: GuerreroZ · 4 clases en total · 3 conexiones (o-- / *--)0 / 4
28. Torneo de Guerreros Z (Dragon Ball)
🐉 Dragon Ball Z🔴 expertoDos guerreros se baten a duelo en el Torneo de las Artes Marciales. Gestionan su barra de Ki, liberan Técnicas Especiales de energía y consumen Semillas del Ermitaño.
🎯 Misión POO: Modela GuerreroZ, TecnicaKi, SemillaErmitano y AuraTransformacion. En cada turno el guerrero puede Cargar Ki, lanzar su técnica especial o comer una semilla si su vida es baja.
💡 Simulación Java Completa:GuerreroZ (Combate por turnos)
Código Java funcional listo para compilar y ejecutar con la simulación en consola:
class TecnicaKi {
private String nombreTecnica;
private int costoKi;
private int potenciaBase;
public TecnicaKi(String nombre, int costoKi, int potencia) {
this.nombreTecnica = nombre;
this.costoKi = costoKi;
this.potenciaBase = potencia;
}
public int calcularDanio(double multiplicadorAura) {
return (int) (potenciaBase * multiplicadorAura);
}
public int getCostoKi() { return costoKi; }
public String getNombreTecnica() { return nombreTecnica; }
}
class SemillaErmitano {
private boolean disponible = true;
public boolean consumir() {
if (disponible) {
disponible = false;
return true;
}
return false;
}
}
class AuraTransformacion {
private String nombreFase;
private double multiplicador;
private boolean activa = false;
public AuraTransformacion(String fase, double mult) {
this.nombreFase = fase;
this.multiplicador = mult;
}
public void activar() {
this.activa = true;
System.out.println("⚡ ¡Despertó la transformación " + nombreFase + "!");
}
public double getMultiplicador() { return activa ? multiplicador : 1.0; }
}
class GuerreroZ {
private String nombre;
private int vidaHp;
private int kiActual;
private TecnicaKi tecnica;
private SemillaErmitano semilla;
private AuraTransformacion aura;
public GuerreroZ(String nombre, int hp, TecnicaKi tecnica, AuraTransformacion aura) {
this.nombre = nombre;
this.vidaHp = hp;
this.kiActual = 50;
this.tecnica = tecnica;
this.semilla = new SemillaErmitano();
this.aura = aura;
}
public void cargarKi() {
kiActual += 35;
System.out.println("💥 " + nombre + " concentra su Ki (+35 Ki). Total Ki: " + kiActual);
if (kiActual >= 80 && aura != null) aura.activar();
}
public void lanzarTecnicaEspecial(GuerreroZ rival) {
if (kiActual >= tecnica.getCostoKi()) {
kiActual -= tecnica.getCostoKi();
int danio = tecnica.calcularDanio(aura != null ? aura.getMultiplicador() : 1.0);
System.out.println("🔥 ¡" + nombre + " grita: " + tecnica.getNombreTecnica() + "!");
rival.recibirGolpeKi(danio);
} else {
System.out.println("⚠️ " + nombre + " no tiene suficiente Ki!");
}
}
public void comerSemilla() {
if (semilla.consumir()) {
this.vidaHp = 200;
this.kiActual = 100;
System.out.println("🌱 " + nombre + " comió una Semilla del Ermitaño! (Salud y Ki al 100%)");
}
}
public void recibirGolpeKi(int danio) {
this.vidaHp = Math.max(0, this.vidaHp - danio);
System.out.println(" 💥 " + nombre + " recibió el impacto (-" + danio + " HP). Salud restante: " + vidaHp);
}
public String getNombre() { return nombre; }
}
public class Main {
public static void main(String[] args) {
GuerreroZ goku = new GuerreroZ("Goku", 180, new TecnicaKi("KAMEHAMEHA", 45, 60), new AuraTransformacion("Super Saiyajin", 1.5));
GuerreroZ vegeta = new GuerreroZ("Vegeta", 175, new TecnicaKi("FINAL FLASH", 50, 65), new AuraTransformacion("Super Vegeta", 1.4));
goku.cargarKi();
goku.lanzarTecnicaEspecial(vegeta);
vegeta.cargarKi();
vegeta.lanzarTecnicaEspecial(goku);
goku.comerSemilla();
}
}2929. Reacciones Elementales de Teyvat (Genshin Impact)
✨ Genshin Impact🔴 expertoClase Principal: PersonajeTeyvat · 4 clases en total · 3 conexiones (o-- / *--)0 / 4
29. Reacciones Elementales de Teyvat (Genshin Impact)
✨ Genshin Impact🔴 expertoDos personajes canalizan visiones de Pyro y Hydro. Cada personaje porta un Arma legendaria con crítico, un Set de Artefactos de maestría y platos de comida curativa.
🎯 Misión POO: Modela PersonajeTeyvat, ArmaGenshin, SetArtefactos y ComidaCurativa. Si el rival ya tiene aura Hydro aplicada y recibe ataque Pyro, se activa la reacción Vaporización multiplicando el daño.
💡 Simulación Java Completa:PersonajeTeyvat (Combate por turnos)
Código Java funcional listo para compilar y ejecutar con la simulación en consola:
import java.util.ArrayList;
import java.util.List;
class ArmaGenshin {
private String nombreArma;
private int ataqueBasico;
private double probCritico;
public ArmaGenshin(String nombre, int atk, double crit) {
this.nombreArma = nombre;
this.ataqueBasico = atk;
this.probCritico = crit;
}
public int getDanioTotal() {
boolean crit = Math.random() < probCritico;
if (crit) System.out.println(" 💥 ¡Golpe Crítico con " + nombreArma + "!");
return crit ? (int)(ataqueBasico * 1.8) : ataqueBasico;
}
}
class SetArtefactos {
private int maestriaElemental;
public SetArtefactos(int maestria) {
this.maestriaElemental = maestria;
}
public double calcularMultiplicadorReaccion() {
return 1.5 + (maestriaElemental * 0.002);
}
}
class ComidaCurativa {
private String nombrePlato;
private int puntosCuracion;
private boolean servida = false;
public ComidaCurativa(String nombre, int cura) {
this.nombrePlato = nombre;
this.puntosCuracion = cura;
}
public int consumir() {
if (!servida) {
servida = true;
return puntosCuracion;
}
return 0;
}
public String getNombrePlato() { return nombrePlato; }
}
class PersonajeTeyvat {
private String nombre;
private String elementoVision;
private int vidaHp;
private String auraAplicada = "Ninguna";
private ArmaGenshin arma;
private SetArtefactos artefactos;
private List<ComidaCurativa> platos;
public PersonajeTeyvat(String nombre, String elemento, int hp, ArmaGenshin arma, SetArtefactos artefactos) {
this.nombre = nombre;
this.elementoVision = elemento;
this.vidaHp = hp;
this.arma = arma;
this.artefactos = artefactos;
this.platos = new ArrayList<>();
}
public void agregarComida(ComidaCurativa c) { platos.add(c); }
public void habilidadElemental(PersonajeTeyvat rival) {
System.out.println("🌟 " + nombre + " [" + elementoVision + "] usa Habilidad Elemental contra " + rival.getNombre() + "!");
int danio = arma.getDanioTotal();
rival.recibirImpactoElemental(danio, this.elementoVision);
}
public void recibirImpactoElemental(int danioBase, String elementoAtacante) {
int danioFinal = danioBase;
if (this.auraAplicada.equals("Hydro") && elementoAtacante.equals("Pyro")) {
double mult = artefactos != null ? artefactos.calcularMultiplicadorReaccion() : 1.5;
danioFinal = (int) (danioBase * mult);
System.out.printf(" 🔥💧 ¡REACCIÓN ELEMENTAL: VAPORIZACIÓN! (Daño x%.2f = %d)\n", mult, danioFinal);
this.auraAplicada = "Ninguna";
} else {
this.auraAplicada = elementoAtacante;
System.out.println(" 💧 Aura " + elementoAtacante + " aplicada al objetivo.");
}
this.vidaHp = Math.max(0, this.vidaHp - danioFinal);
System.out.println(" 💔 " + nombre + " HP restante: " + vidaHp);
}
public void comerPlato(int indice) {
if (indice >= 0 && indice < platos.size()) {
ComidaCurativa comida = platos.get(indice);
int curado = comida.consumir();
if (curado > 0) {
this.vidaHp += curado;
System.out.println("🍲 " + nombre + " comió " + comida.getNombrePlato() + " (+ " + curado + " HP).");
}
}
}
public String getNombre() { return nombre; }
}
public class Main {
public static void main(String[] args) {
PersonajeTeyvat yelan = new PersonajeTeyvat("Yelan", "Hydro", 200, new ArmaGenshin("Aqua Simulacra", 35, 0.4), new SetArtefactos(100));
PersonajeTeyvat hutao = new PersonajeTeyvat("Hu Tao", "Pyro", 180, new ArmaGenshin("Báculo de Homa", 45, 0.5), new SetArtefactos(220));
hutao.agregarComida(new ComidaCurativa("Tricolor Dango", 50));
yelan.habilidadElemental(hutao);
hutao.habilidadElemental(yelan);
hutao.comerPlato(0);
}
}3030. Arena PvP de Campeones (World of Warcraft)
🛡️ World of Warcraft🔴 expertoClase Principal: HeroeAzeroth · 4 clases en total · 3 conexiones (o-- / *--)0 / 4
30. Arena PvP de Campeones (World of Warcraft)
🛡️ World of Warcraft🔴 expertoUn Guerrero y un Chamán se enfrentan en la Arena de Dalaran. El Guerrero empuña un Arma Forjada, el Chamán planta Tótems que pulsan mejoras cada turno y consumen Frascos alquímicos.
🎯 Misión POO: Modela HeroeAzeroth, ArmaForjada, TotemSoporte y FrascoPoder. El tótem aplica daño o curación pasiva al inicio de cada turno mientras tenga durabilidad.
💡 Simulación Java Completa:HeroeAzeroth (Combate por turnos)
Código Java funcional listo para compilar y ejecutar con la simulación en consola:
import java.util.ArrayList;
import java.util.List;
class ArmaForjada {
private String nombreArma;
private int danioDPS;
public ArmaForjada(String nombre, int dps) {
this.nombreArma = nombre;
this.danioDPS = dps;
}
public int calcularGolpe() { return danioDPS; }
public String getNombreArma() { return nombreArma; }
}
class TotemSoporte {
private String tipoTotem;
private int efectoPuntos;
private int rondas;
public TotemSoporte(String tipo, int efecto, int rondas) {
this.tipoTotem = tipo;
this.efectoPuntos = efecto;
this.rondas = rondas;
}
public int pulsarRonda() {
if (rondas > 0) {
rondas--;
System.out.println(" ⚡ Tótem de " + tipoTotem + " emitió pulso (+ " + efectoPuntos + " / rondas restantes: " + rondas + ")");
return efectoPuntos;
}
return 0;
}
public boolean isActivo() { return rondas > 0; }
}
class FrascoPoder {
private String nombre;
private int bonus;
private boolean usado = false;
public FrascoPoder(String nombre, int bonus) {
this.nombre = nombre;
this.bonus = bonus;
}
public int consumir() {
if (!usado) {
usado = true;
return bonus;
}
return 0;
}
}
class HeroeAzeroth {
private String nombre;
private String claseRol;
private int salud;
private int iraRage;
private ArmaForjada arma;
private TotemSoporte totem;
private List<FrascoPoder> frascos;
public HeroeAzeroth(String nombre, String clase, int hp, ArmaForjada arma) {
this.nombre = nombre;
this.claseRol = clase;
this.salud = hp;
this.iraRage = 30;
this.arma = arma;
this.frascos = new ArrayList<>();
}
public void plantarTotem(TotemSoporte t) {
this.totem = t;
System.out.println("🗿 " + nombre + " clavó un tótem en la arena!");
}
public void procesarEfectoTotem() {
if (totem != null && totem.isActivo()) {
this.salud += totem.pulsarRonda();
}
}
public void golpeMortal(HeroeAzeroth rival) {
System.out.println("⚔️ " + nombre + " ejecuta Golpe Mortal con " + arma.getNombreArma() + "!");
int danio = arma.calcularGolpe();
rival.recibirDanio(danio);
}
public void recibirDanio(int danio) {
this.salud = Math.max(0, this.salud - danio);
System.out.println(" 💥 " + nombre + " sufrió " + danio + " dmg. (Salud: " + salud + ")");
}
public void beberFrasco(int i) {
if (i >= 0 && i < frascos.size()) {
iraRage += frascos.get(i).consumir();
}
}
public void agregarFrasco(FrascoPoder f) { frascos.add(f); }
public String getNombre() { return nombre; }
}
public class Main {
public static void main(String[] args) {
HeroeAzeroth warrior = new HeroeAzeroth("Garrosh", "Guerrero", 260, new ArmaForjada("Aullavísceras", 45));
HeroeAzeroth shaman = new HeroeAzeroth("Thrall", "Chamán", 240, new ArmaForjada("Martillo Maldito", 38));
shaman.plantarTotem(new TotemSoporte("Corriente Sanadora", 25, 3));
warrior.golpeMortal(shaman);
shaman.procesarEfectoTotem();
shaman.golpeMortal(warrior);
}
}3131. Combate Clásico de Soldados (Final Fantasy)
🔮 Final Fantasy🔴 expertoClase Principal: SoldadoFF · 4 clases en total · 3 conexiones (o-- / *--)0 / 4
31. Combate Clásico de Soldados (Final Fantasy)
🔮 Final Fantasy🔴 expertoDos soldados de élite usan Espadas Buster con ranuras de Materia elemental (Fuego, Hielo) y éteres de maná.
🎯 Misión POO: Modela SoldadoFF, EspadaRanurada, MateriaMagica y PocionEter. El soldado puede atacar físicamente con su sable o conjurar el hechizo de la Materia si tiene MP suficiente.
💡 Simulación Java Completa:SoldadoFF (Combate por turnos)
Código Java funcional listo para compilar y ejecutar con la simulación en consola:
import java.util.ArrayList;
import java.util.List;
class EspadaRanurada {
private String nombre;
private int danioFisico;
public EspadaRanurada(String nombre, int danio) {
this.nombre = nombre;
this.danioFisico = danio;
}
public int getDanioFisico() { return danioFisico; }
public String getNombre() { return nombre; }
}
class MateriaMagica {
private String elemento;
private String hechizo;
private int poder;
private int costoMP;
public MateriaMagica(String elemento, String hechizo, int poder, int costoMP) {
this.elemento = elemento;
this.hechizo = hechizo;
this.poder = poder;
this.costoMP = costoMP;
}
public int getPoder() { return poder; }
public int getCostoMP() { return costoMP; }
public String getHechizo() { return hechizo; }
}
class PocionEter {
private int mp;
private boolean gastado = false;
public PocionEter(int mp) { this.mp = mp; }
public int consumir() {
if (!gastado) { gastado = true; return mp; }
return 0;
}
}
class SoldadoFF {
private String nombre;
private int hpActual;
private int mpActual;
private EspadaRanurada sable;
private List<MateriaMagica> materias;
private List<PocionEter> eteres;
public SoldadoFF(String nombre, int hp, int mp, EspadaRanurada sable) {
this.nombre = nombre;
this.hpActual = hp;
this.mpActual = mp;
this.sable = sable;
this.materias = new ArrayList<>();
this.eteres = new ArrayList<>();
}
public void engastarMateria(MateriaMagica m) { materias.add(m); }
public void agregarEter(PocionEter e) { eteres.add(e); }
public void ataqueFisico(SoldadoFF rival) {
System.out.println("🗡️ " + nombre + " corta con " + sable.getNombre() + "!");
rival.recibirDanio(sable.getDanioFisico());
}
public void conjurarMateria(int slot, SoldadoFF rival) {
if (slot >= 0 && slot < materias.size()) {
MateriaMagica m = materias.get(slot);
if (mpActual >= m.getCostoMP()) {
mpActual -= m.getCostoMP();
System.out.println("🔮 " + nombre + " conjura [" + m.getHechizo() + "]! (MP restante: " + mpActual + ")");
rival.recibirDanio(m.getPoder());
} else {
System.out.println("❌ No hay suficiente MP!");
}
}
}
public void usarEter(int i) {
if (i >= 0 && i < eteres.size()) {
int rec = eteres.get(i).consumir();
if (rec > 0) {
mpActual += rec;
System.out.println("✨ " + nombre + " bebió Éter (+ " + rec + " MP).");
}
}
}
public void recibirDanio(int danio) {
hpActual = Math.max(0, hpActual - danio);
System.out.println(" 💔 " + nombre + " HP: " + hpActual);
}
public String getNombre() { return nombre; }
}
public class Main {
public static void main(String[] args) {
SoldadoFF cloud = new SoldadoFF("Cloud Strife", 300, 80, new EspadaRanurada("Buster Sword", 35));
cloud.engastarMateria(new MateriaMagica("Fuego", "Piro+", 55, 30));
cloud.agregarEter(new PocionEter(40));
SoldadoFF sephiroth = new SoldadoFF("Sefirot", 350, 100, new EspadaRanurada("Masamune", 42));
cloud.conjurarMateria(0, sephiroth);
sephiroth.ataqueFisico(cloud);
cloud.usarEter(0);
}
}3232. Duelo de Netrunners (Cyberpunk 2077)
💾 Cyberpunk 2077🔴 expertoClase Principal: MercenarioCyber · 4 clases en total · 3 conexiones (o-- / *--)0 / 4
32. Duelo de Netrunners (Cyberpunk 2077)
💾 Cyberpunk 2077🔴 expertoDos mercenarios cibernéticos en Night City se enfrentan hackeando el implante del rival con Ciberdecks, pistolas inteligentes y recuperadores MaxDoc.
🎯 Misión POO: Modela MercenarioCyber, CiberdeckOS, PistolaSmart y InhaladorMaxDoc. Los quickhacks de sobrecalentamiento consumen memoria RAM del ciberdeck para aplicar daño sin fallar.
💡 Simulación Java Completa:MercenarioCyber (Combate por turnos)
Código Java funcional listo para compilar y ejecutar con la simulación en consola:
import java.util.ArrayList;
import java.util.List;
class CiberdeckOS {
private String modeloChip;
private int danioQuickhack;
private int costoRAM;
public CiberdeckOS(String modelo, int danio, int costoRAM) {
this.modeloChip = modelo;
this.danioQuickhack = danio;
this.costoRAM = costoRAM;
}
public int getDanioQuickhack() { return danioQuickhack; }
public int getCostoRAM() { return costoRAM; }
public String getModeloChip() { return modeloChip; }
}
class PistolaSmart {
private String modelo;
private int danio;
public PistolaSmart(String modelo, int danio) {
this.modelo = modelo;
this.danio = danio;
}
public int calcularDisparo() { return danio; }
public String getModelo() { return modelo; }
}
class InhaladorMaxDoc {
private int cura;
private boolean usado = false;
public InhaladorMaxDoc(int cura) { this.cura = cura; }
public int activar() {
if (!usado) { usado = true; return cura; }
return 0;
}
}
class MercenarioCyber {
private String alias;
private int ciberSalud;
private int ramActual;
private CiberdeckOS ciberdeck;
private PistolaSmart pistola;
private List<InhaladorMaxDoc> inhaladores;
public MercenarioCyber(String alias, int salud, int ram, CiberdeckOS deck, PistolaSmart gun) {
this.alias = alias;
this.ciberSalud = salud;
this.ramActual = ram;
this.ciberdeck = deck;
this.pistola = gun;
this.inhaladores = new ArrayList<>();
}
public void agregarInhalador(InhaladorMaxDoc doc) { inhaladores.add(doc); }
public void ejecutarQuickhack(MercenarioCyber rival) {
if (ramActual >= ciberdeck.getCostoRAM()) {
ramActual -= ciberdeck.getCostoRAM();
System.out.println("💾 " + alias + " inyecta Sobrecalentamiento con " + ciberdeck.getModeloChip() + "!");
rival.recibirDanio(ciberdeck.getDanioQuickhack());
} else {
System.out.println("⚠️ RAM insuficiente para el hackeo!");
}
}
public void disparoTeledirigido(MercenarioCyber rival) {
System.out.println("🔫 " + alias + " dispara ráfaga inteligente con " + pistola.getModelo() + "!");
rival.recibirDanio(pistola.calcularDisparo());
}
public void inhalarMaxDoc(int i) {
if (i >= 0 && i < inhaladores.size()) {
int h = inhaladores.get(i).activar();
if (h > 0) {
ciberSalud += h;
System.out.println("💉 " + alias + " usó MaxDoc (+ " + h + " HP).");
}
}
}
public void recibirDanio(int d) {
ciberSalud = Math.max(0, ciberSalud - d);
System.out.println(" 💥 " + alias + " integridad: " + ciberSalud + " HP");
}
public String getAlias() { return alias; }
}
public class Main {
public static void main(String[] args) {
MercenarioCyber v = new MercenarioCyber("V", 220, 16, new CiberdeckOS("Militech Tetratronic", 50, 6), new PistolaSmart("Kang Tao Dian", 30));
v.agregarInhalador(new InhaladorMaxDoc(45));
MercenarioCyber smasher = new MercenarioCyber("Adam Smasher", 320, 8, new CiberdeckOS("Arasaka Mk.5", 40, 8), new PistolaSmart("Carnage Smart", 45));
v.ejecutarQuickhack(smasher);
smasher.disparoTeledirigido(v);
v.inhalarMaxDoc(0);
}
}3333. Combate de Vanguardia (Overwatch)
🛡️ Overwatch🔴 expertoClase Principal: HeroeOverwatch · 4 clases en total · 3 conexiones (o-- / *--)0 / 4
33. Combate de Vanguardia (Overwatch)
🛡️ Overwatch🔴 expertoDos héroes de Overwatch disputan el objetivo. Disparan sus cañones, despliegan barreras de energía protectoras y consumen packs de salud distribuidos por el mapa.
🎯 Misión POO: Modela HeroeOverwatch, CanionEnergia, BarreraEscudo y PackSalud. La barrera mitiga el daño entrante hasta que su energía colapsa.
💡 Simulación Java Completa:HeroeOverwatch (Combate por turnos)
Código Java funcional listo para compilar y ejecutar con la simulación en consola:
import java.util.ArrayList;
import java.util.List;
class CanionEnergia {
private String tipo;
private int danio;
public CanionEnergia(String tipo, int danio) { this.tipo = tipo; this.danio = danio; }
public int disparar() { return danio; }
}
class BarreraEscudo {
private int hp;
private boolean activa = false;
public BarreraEscudo(int hp) { this.hp = hp; }
public void desplegar() { this.activa = true; }
public int absorber(int danio) {
if (!activa || hp <= 0) return danio;
if (danio >= hp) {
int sobrante = danio - hp;
hp = 0;
activa = false;
System.out.println(" 🛡️ ¡La barrera fue destrozada!");
return sobrante;
} else {
hp -= danio;
System.out.println(" 🛡️ Barrera absorbió el tiro (HP Barrera: " + hp + ")");
return 0;
}
}
}
class PackSalud {
private int cura;
private boolean tomado = false;
public PackSalud(int cura) { this.cura = cura; }
public int consumir() {
if (!tomado) { tomado = true; return cura; }
return 0;
}
}
class HeroeOverwatch {
private String nombre;
private int salud;
private CanionEnergia canion;
private BarreraEscudo barrera;
private List<PackSalud> packs;
public HeroeOverwatch(String nombre, int salud, CanionEnergia canion, BarreraEscudo barrera) {
this.nombre = nombre;
this.salud = salud;
this.canion = canion;
this.barrera = barrera;
this.packs = new ArrayList<>();
}
public void agregarPack(PackSalud p) { packs.add(p); }
public void desplegarBarrera() {
if (barrera != null) {
barrera.desplegar();
System.out.println("🛡️ " + nombre + " levantó su escudo de energía!");
}
}
public void dispararCanion(HeroeOverwatch rival) {
System.out.println("🎯 " + nombre + " abre fuego!");
rival.recibirDisparo(canion.disparar());
}
public void recibirDisparo(int danio) {
int residual = barrera != null ? barrera.absorber(danio) : danio;
salud = Math.max(0, salud - residual);
System.out.println(" 💔 " + nombre + " Salud: " + salud + " HP");
}
public void agarrarPackSalud(int i) {
if (i >= 0 && i < packs.size()) {
int c = packs.get(i).consumir();
if (c > 0) {
salud += c;
System.out.println("➕ " + nombre + " tomó Mega Pack de Salud (+ " + c + " HP).");
}
}
}
}
public class Main {
public static void main(String[] args) {
HeroeOverwatch reinhardt = new HeroeOverwatch("Reinhardt", 400, new CanionEnergia("Martillo a Reacción", 50), new BarreraEscudo(250));
HeroeOverwatch winston = new HeroeOverwatch("Winston", 350, new CanionEnergia("Cañón Tesla", 40), new BarreraEscudo(150));
reinhardt.agregarPack(new PackSalud(75));
reinhardt.desplegarBarrera();
winston.dispararCanion(reinhardt);
reinhardt.dispararCanion(winston);
reinhardt.agarrarPackSalud(0);
}
}3434. Duelo Kombat 1v1 (Mortal Kombat)
🩸 Mortal Kombat🔴 expertoClase Principal: Kombatiente · 4 clases en total · 3 conexiones (o-- / *--)0 / 4
34. Duelo Kombat 1v1 (Mortal Kombat)
🩸 Mortal Kombat🔴 expertoDos kombatientes se miden en el torneo mortal. Cada uno tiene un Estilo de Pelea marcial, un Arma Kombat blanca y Amuletos de alma curativos.
🎯 Misión POO: Modela Kombatiente, EstiloCombate, ArmaKombat y AmuletoCuracion. Ejecuta combos y ataques especiales con armas sangrientas en turnos.
💡 Simulación Java Completa:Kombatiente (Combate por turnos)
Código Java funcional listo para compilar y ejecutar con la simulación en consola:
import java.util.ArrayList;
import java.util.List;
class EstiloCombate {
private String nombre;
private int danio;
public EstiloCombate(String n, int d) { this.nombre = n; this.danio = d; }
public int getDanio() { return danio; }
public String getNombre() { return nombre; }
}
class ArmaKombat {
private String nombre;
private int danio;
public ArmaKombat(String n, int d) { this.nombre = n; this.danio = d; }
public int getDanio() { return danio; }
public String getNombre() { return nombre; }
}
class AmuletoCuracion {
private int cura;
private boolean usado = false;
public AmuletoCuracion(int c) { this.cura = c; }
public int consumir() {
if (!usado) { usado = true; return cura; }
return 0;
}
}
class Kombatiente {
private String nombre;
private int salud;
private EstiloCombate estilo;
private ArmaKombat arma;
private List<AmuletoCuracion> amuletos;
public Kombatiente(String nombre, int salud, EstiloCombate estilo, ArmaKombat arma) {
this.nombre = nombre;
this.salud = salud;
this.estilo = estilo;
this.arma = arma;
this.amuletos = new ArrayList<>();
}
public void agregarAmuleto(AmuletoCuracion a) { amuletos.add(a); }
public void ataqueBasico(Kombatiente rival) {
System.out.println("👊 " + nombre + " conecta combo de estilo [" + estilo.getNombre() + "]!");
rival.recibirDanio(estilo.getDanio());
}
public void golpeConArma(Kombatiente rival) {
System.out.println("🗡️ " + nombre + " clava su " + arma.getNombre() + "!");
rival.recibirDanio(arma.getDanio());
}
public void usarAmuleto(int i) {
if (i >= 0 && i < amuletos.size()) {
int c = amuletos.get(i).consumir();
if (c > 0) {
salud += c;
System.out.println("🩸 " + nombre + " invocó amuleto (+ " + c + " HP).");
}
}
}
public void recibirDanio(int d) {
salud = Math.max(0, salud - d);
System.out.println(" 💥 " + nombre + " Salud: " + salud + " HP");
}
}
public class Main {
public static void main(String[] args) {
Kombatiente scorpion = new Kombatiente("Scorpion", 250, new EstiloCombate("Ninjutsu", 30), new ArmaKombat("Kunai con Cadena", 45));
scorpion.agregarAmuleto(new AmuletoCuracion(35));
Kombatiente subzero = new Kombatiente("Sub-Zero", 250, new EstiloCombate("Shotokan", 28), new ArmaKombat("Daga de Hielo", 40));
scorpion.golpeConArma(subzero);
subzero.ataqueBasico(scorpion);
scorpion.usarAmuleto(0);
}
}3535. Combate Infernal (DOOM)
🔥 DOOM🔴 expertoClase Principal: DoomSlayer · 4 clases en total · 3 conexiones (o-- / *--)0 / 4
35. Combate Infernal (DOOM)
🔥 DOOM🔴 expertoEl Doom Slayer enfrenta a un Barón del Infierno. Porta su legendaria Super Escopeta, un Lanzallamas de hombro para extraer armadura y cajas de cartuchos de munición.
🎯 Misión POO: Modela DoomSlayer, SuperShotgun, CanionHombro y CajaCartuchos. El disparo de doble cañón consume cartuchos para aniquilar enemigos.
💡 Simulación Java Completa:DoomSlayer (Combate por turnos)
Código Java funcional listo para compilar y ejecutar con la simulación en consola:
import java.util.ArrayList;
import java.util.List;
class SuperShotgun {
private String nombre;
private int danio;
private int balas;
public SuperShotgun(String nombre, int danio, int balas) {
this.nombre = nombre;
this.danio = danio;
this.balas = balas;
}
public int disparar() {
if (balas >= 2) {
balas -= 2;
System.out.println(" 💥 ¡BOOM! Doble cañón disparado (Balas restantes: " + balas + ")");
return danio;
}
System.out.println(" ⚠️ ¡Click! Sin cartuchos.");
return 0;
}
public void recargar(int cant) { this.balas += cant; }
}
class CanionHombro {
private int danio;
public CanionHombro(int d) { this.danio = d; }
public int incinerar() { return danio; }
}
class CajaCartuchos {
private int cant;
private boolean vacia = false;
public CajaCartuchos(int cant) { this.cant = cant; }
public int suministrar() {
if (!vacia) { vacia = true; return cant; }
return 0;
}
}
class DoomSlayer {
private String nombre;
private int vida;
private int armadura;
private SuperShotgun escopeta;
private CanionHombro hombro;
private List<CajaCartuchos> reservas;
public DoomSlayer(String nombre, int vida, int armadura, SuperShotgun s, CanionHombro h) {
this.nombre = nombre;
this.vida = vida;
this.armadura = armadura;
this.escopeta = s;
this.hombro = h;
this.reservas = new ArrayList<>();
}
public void agregarCaja(CajaCartuchos c) { reservas.add(c); }
public void dispararDobleCanon(DoomSlayer demonio) {
System.out.println("💣 " + nombre + " descarga su Super Escopeta!");
int d = escopeta.disparar();
demonio.recibirDanio(d);
}
public void quemarConHombro(DoomSlayer demonio) {
System.out.println("🔥 " + nombre + " quema al objetivo con lanzallamas!");
demonio.recibirDanio(hombro.incinerar());
this.armadura += 20;
}
public void recargarCartuchos(int i) {
if (i >= 0 && i < reservas.size()) {
int b = reservas.get(i).suministrar();
if (b > 0) {
escopeta.recargar(b);
System.out.println("📦 " + nombre + " recargó " + b + " cartuchos.");
}
}
}
public void recibirDanio(int d) {
vida = Math.max(0, vida - d);
System.out.println(" 💔 " + nombre + " Vida: " + vida + " HP");
}
}
public class Main {
public static void main(String[] args) {
DoomSlayer slayer = new DoomSlayer("Doom Slayer", 200, 100, new SuperShotgun("Super Shotgun", 65, 4), new CanionHombro(25));
slayer.agregarCaja(new CajaCartuchos(6));
DoomSlayer baron = new DoomSlayer("Barón del Infierno", 300, 0, new SuperShotgun("Garras de Fuego", 35, 99), new CanionHombro(15));
slayer.dispararDobleCanon(baron);
slayer.quemarConHombro(baron);
baron.dispararDobleCanon(slayer);
slayer.recargarCartuchos(0);
}
}3636. Infiltración en la Nave (Among Us)
🚀 Among Us🔴 expertoClase Principal: TripulanteNave · 4 clases en total · 3 conexiones (o-- / *--)0 / 4
36. Infiltración en la Nave (Among Us)
🚀 Among Us🔴 expertoUn Tripulante y un Impostor se enfrentan en turnos en la nave espacial. El Tripulante usa escáneres y kits de reparación de tareas, mientras el Impostor sabotea con cuchillo.
🎯 Misión POO: Modela TripulanteNave, ScannerTarjeta, BotonEmergencia y KitReparacion. Cada turno el tripulante puede avanzar tareas o alertar por botón de emergencia.
💡 Simulación Java Completa:TripulanteNave (Combate por turnos)
Código Java funcional listo para compilar y ejecutar con la simulación en consola:
import java.util.ArrayList;
import java.util.List;
class ScannerTarjeta {
public boolean escanear() {
System.out.println(" 💳 Tarjeta escaneada con éxito.");
return true;
}
}
class BotonPanico {
private int usos = 1;
public boolean presionar() {
if (usos > 0) {
usos--;
System.out.println(" 🚨 ¡REUNIÓN DE EMERGENCIA CONVOCADA!");
return true;
}
return false;
}
}
class KitReparacion {
private String modulo;
private int progreso;
private boolean usado = false;
public KitReparacion(String m, int p) { this.modulo = m; this.progreso = p; }
public int instalar() {
if (!usado) { usado = true; return progreso; }
return 0;
}
}
class TripulanteNave {
private String colorTraje;
private int vida;
private int tareas;
private ScannerTarjeta scanner;
private BotonPanico boton;
private List<KitReparacion> kits;
public TripulanteNave(String color, ScannerTarjeta scanner, BotonPanico boton) {
this.colorTraje = color;
this.vida = 100;
this.tareas = 0;
this.scanner = scanner;
this.boton = boton;
this.kits = new ArrayList<>();
}
public void agregarKit(KitReparacion k) { kits.add(k); }
public void hacerTarea() {
if (scanner.escanear()) {
tareas += 25;
System.out.println("📋 " + colorTraje + " completó tarea de administración. Progreso: " + tareas + "%");
}
}
public void tocarBoton() {
boton.presionar();
}
public void repararFalla(int i) {
if (i >= 0 && i < kits.size()) {
tareas += kits.get(i).instalar();
System.out.println("🔧 " + colorTraje + " reparó cableado. Progreso: " + tareas + "%");
}
}
public void recibirSabotaje(int danio) {
vida = Math.max(0, vida - danio);
System.out.println(" 💔 " + colorTraje + " fue emboscado! (Salud: " + vida + ")");
}
}
public class Main {
public static void main(String[] args) {
TripulanteNave azul = new TripulanteNave("Azul", new ScannerTarjeta(), new BotonPanico());
azul.agregarKit(new KitReparacion("Escudos", 25));
azul.hacerTarea();
azul.recibirSabotaje(40);
azul.repararFalla(0);
azul.tocarBoton();
}
}3737. Caza de Wyverns (Monster Hunter)
🐉 Monster Hunter🔴 expertoClase Principal: CazadorHunter · 4 clases en total · 3 conexiones (o-- / *--)0 / 4
37. Caza de Wyverns (Monster Hunter)
🐉 Monster Hunter🔴 expertoUn Cazador con Gran Espada y Kinsecto adiestrado se enfrenta a un temible Wyvern en una cacería por turnos, extrayendo esencias y bebiendo megapociones.
🎯 Misión POO: Modela CazadorHunter, GranEspadaCazador, KinsectoMascota y MegaPocionCaza. El kinsecto extrae extractos de ataque que potencian la espada.
💡 Simulación Java Completa:CazadorHunter (Combate por turnos)
Código Java funcional listo para compilar y ejecutar con la simulación en consola:
import java.util.ArrayList;
import java.util.List;
class GranEspadaCazador {
private String nombre;
private int danio;
public GranEspadaCazador(String n, int d) { this.nombre = n; this.danio = d; }
public int calcularTajo(int bonus) { return danio + bonus; }
public String getNombre() { return nombre; }
}
class KinsectoMascota {
private int bonus = 20;
public int extraerEsencia() {
System.out.println(" 🐞 Kinsecto extrajo esencia roja (+ " + bonus + " atk).");
return bonus;
}
}
class MegaPocionCaza {
private int cura;
private boolean tomada = false;
public MegaPocionCaza(int c) { this.cura = c; }
public int consumir() {
if (!tomada) { tomada = true; return cura; }
return 0;
}
}
class CazadorHunter {
private String nombre;
private int salud;
private GranEspadaCazador espada;
private KinsectoMascota kinsecto;
private int bonusActual = 0;
private List<MegaPocionCaza> pociones;
public CazadorHunter(String nombre, int salud, GranEspadaCazador espada, KinsectoMascota kinsecto) {
this.nombre = nombre;
this.salud = salud;
this.espada = espada;
this.kinsecto = kinsecto;
this.pociones = new ArrayList<>();
}
public void agregarPocion(MegaPocionCaza p) { pociones.add(p); }
public void enviarKinsecto() {
bonusActual = kinsecto.extraerEsencia();
}
public void tajoCargado(CazadorHunter wyvern) {
System.out.println("⚔️ " + nombre + " ejecuta Tajo Cargado Nivel 3 con " + espada.getNombre() + "!");
int d = espada.calcularTajo(bonusActual);
wyvern.recibirDanio(d);
}
public void beberMegaPocion(int i) {
if (i >= 0 && i < pociones.size()) {
int c = pociones.get(i).consumir();
if (c > 0) {
salud += c;
System.out.println("🧪 " + nombre + " bebió Megapoción (+ " + c + " HP).");
}
}
}
public void recibirDanio(int d) {
salud = Math.max(0, salud - d);
System.out.println(" 💔 " + nombre + " Salud: " + salud + " HP");
}
}
public class Main {
public static void main(String[] args) {
CazadorHunter hunter = new CazadorHunter("Cazador Wyvern", 180, new GranEspadaCazador("Hoja de Rathalos", 60), new KinsectoMascota());
hunter.agregarPocion(new MegaPocionCaza(50));
CazadorHunter rathalos = new CazadorHunter("Rathalos", 350, new GranEspadaCazador("Garras de Fuego", 40), new KinsectoMascota());
hunter.enviarKinsecto();
hunter.tajoCargado(rathalos);
rathalos.tajoCargado(hunter);
hunter.beberMegaPocion(0);
}
}3838. Duelo en la Taberna (Hearthstone)
🍺 Hearthstone🔴 expertoClase Principal: HeroeHearthstone · 4 clases en total · 3 conexiones (o-- / *--)0 / 4
38. Duelo en la Taberna (Hearthstone)
🍺 Hearthstone🔴 expertoDos héroes en la taberna gestionan cristales de maná por turnos, activan su Poder de Héroe y juegan Esbirros con ataque/salud.
🎯 Misión POO: Modela HeroeHearthstone, PoderHeroe, ArmaHeroica y CartaEsbirro. En cada turno se incrementa el maná disponible para invocar cartas o usar el poder.
💡 Simulación Java Completa:HeroeHearthstone (Combate por turnos)
Código Java funcional listo para compilar y ejecutar con la simulación en consola:
import java.util.ArrayList;
import java.util.List;
class PoderHeroe {
private String nombre;
private int costo;
private int danio;
public PoderHeroe(String n, int c, int d) { this.nombre = n; this.costo = c; this.danio = d; }
public int activar() { return danio; }
public int getCosto() { return costo; }
public String getNombre() { return nombre; }
}
class CartaEsbirro {
private String nombre;
private int costo;
private int ataque;
private int salud;
public CartaEsbirro(String n, int c, int a, int s) { this.nombre = n; this.costo = c; this.ataque = a; this.salud = s; }
public int getAtaque() { return ataque; }
public int getCosto() { return costo; }
public String getNombre() { return nombre; }
}
class HeroeHearthstone {
private String clase;
private int vida;
private int mana;
private PoderHeroe poder;
private List<CartaEsbirro> mesa;
public HeroeHearthstone(String clase, PoderHeroe poder) {
this.clase = clase;
this.vida = 30;
this.mana = 6;
this.poder = poder;
this.mesa = new ArrayList<>();
}
public void usarPoderHeroico(HeroeHearthstone rival) {
if (mana >= poder.getCosto()) {
mana -= poder.getCosto();
System.out.println("✨ " + clase + " usa Poder Heroico [" + poder.getNombre() + "]!");
rival.recibirDanio(poder.activar());
}
}
public void jugarEsbirro(CartaEsbirro e) {
if (mana >= e.getCosto()) {
mana -= e.getCosto();
mesa.add(e);
System.out.println("🃏 " + clase + " invocó a " + e.getNombre() + " (ATK: " + e.getAtaque() + ")");
}
}
public void ordenarAtaqueEsbirro(int slot, HeroeHearthstone rival) {
if (slot >= 0 && slot < mesa.size()) {
CartaEsbirro e = mesa.get(slot);
System.out.println("⚔️ " + e.getNombre() + " ataca al héroe rival!");
rival.recibirDanio(e.getAtaque());
}
}
public void recibirDanio(int d) {
vida = Math.max(0, vida - d);
System.out.println(" 💥 " + clase + " Vida: " + vida + " HP");
}
}
public class Main {
public static void main(String[] args) {
HeroeHearthstone mago = new HeroeHearthstone("Jaina (Maga)", new PoderHeroe("Explosión de Fuego", 2, 1));
HeroeHearthstone cazador = new HeroeHearthstone("Rexxar (Cazador)", new PoderHeroe("Disparo Firme", 2, 2));
mago.jugarEsbirro(new CartaEsbirro("Draco Azur", 5, 4, 4));
mago.usarPoderHeroico(cazador);
cazador.usarPoderHeroico(mago);
mago.ordenarAtaqueEsbirro(0, cazador);
}
}3939. Duelo en Hallownest (Hollow Knight)
🗡️ Hollow Knight🔴 expertoClase Principal: CaballeroVacio · 4 clases en total · 3 conexiones (o-- / *--)0 / 4
39. Duelo en Hallownest (Hollow Knight)
🗡️ Hollow Knight🔴 expertoEl Caballero combate empuñando su Aguijón Puro, acumulando Alma con cada corte para sanar máscaras o disparar hechizos de Espíritu Vengativo.
🎯 Misión POO: Modela CaballeroVacio, AguijonClavo, AmuletoChapa y HechizoEspiritu. Cada golpe de aguijón llena el medidor de alma para focalizar curación.
💡 Simulación Java Completa:CaballeroVacio (Combate por turnos)
Código Java funcional listo para compilar y ejecutar con la simulación en consola:
class AguijonClavo {
private int danio;
private int alma;
public AguijonClavo(int danio, int alma) { this.danio = danio; this.alma = alma; }
public int calcularCorte() { return danio; }
public int getAlmaGenerada() { return alma; }
}
class AmuletoChapa {
private int bonus;
public AmuletoChapa(int b) { this.bonus = b; }
public int getBonusMagico() { return bonus; }
}
class HechizoEspiritu {
private int danio;
private int costo;
public HechizoEspiritu(int danio, int costo) { this.danio = danio; this.costo = costo; }
public int getDanio() { return danio; }
public int getCostoAlma() { return costo; }
}
class CaballeroVacio {
private String nombre;
private int mascaras;
private int alma;
private AguijonClavo aguijon;
private AmuletoChapa amuleto;
private HechizoEspiritu hechizo;
public CaballeroVacio(String nombre, int mascaras, AguijonClavo ag, AmuletoChapa am, HechizoEspiritu h) {
this.nombre = nombre;
this.mascaras = mascaras;
this.alma = 0;
this.aguijon = ag;
this.amuleto = am;
this.hechizo = h;
}
public void golpearAguijon(CaballeroVacio rival) {
System.out.println("🗡️ " + nombre + " asesta un tajo de aguijón!");
rival.recibirDanio(aguijon.calcularCorte());
alma = Math.min(99, alma + aguijon.getAlmaGenerada());
System.out.println(" ✨ Alma recolectada: " + alma + "/99");
}
public void dispararHechizo(CaballeroVacio rival) {
if (alma >= hechizo.getCostoAlma()) {
alma -= hechizo.getCostoAlma();
int d = hechizo.getDanio() + (amuleto != null ? amuleto.getBonusMagico() : 0);
System.out.println("👻 " + nombre + " dispara ¡Espíritu Vengativo!");
rival.recibirDanio(d);
} else {
System.out.println("❌ No hay suficiente alma!");
}
}
public void focalizarCuracion() {
if (alma >= 33) {
alma -= 33;
mascaras += 1;
System.out.println("✨ " + nombre + " focalizó alma y recuperó 1 Máscara (Total: " + mascaras + ")");
}
}
public void recibirDanio(int d) {
mascaras = Math.max(0, mascaras - d);
System.out.println(" 💔 " + nombre + " Máscaras restantes: " + mascaras);
}
}
public class Main {
public static void main(String[] args) {
CaballeroVacio knight = new CaballeroVacio("Caballero", 7, new AguijonClavo(1, 15), new AmuletoChapa(1), new HechizoEspiritu(3, 33));
CaballeroVacio hornet = new CaballeroVacio("Hornet", 8, new AguijonClavo(2, 10), null, new HechizoEspiritu(2, 33));
knight.golpearAguijon(hornet);
knight.golpearAguijon(hornet);
knight.golpearAguijon(hornet);
knight.dispararHechizo(hornet);
hornet.golpearAguijon(knight);
knight.focalizarCuracion();
}
}4040. Duelo de Espadachines de Hyrule (The Legend of Zelda)
🛡️ The Legend of Zelda🔴 expertoClase Principal: HeroeHyrule · 4 clases en total · 3 conexiones (o-- / *--)0 / 4
40. Duelo de Espadachines de Hyrule (The Legend of Zelda)
🛡️ The Legend of Zelda🔴 expertoLink se enfrenta a Dark Link. Empuña la Espada Maestra, se protege con el Escudo Hyliano y come platos cocinados de corazones.
🎯 Misión POO: Modela HeroeHyrule, EspadaMaestra, EscudoHyliano y PlatoCocinado. El escudo permite ejecutar un contraataque Parry si mitiga el impacto a la perfección.
💡 Simulación Java Completa:HeroeHyrule (Combate por turnos)
Código Java funcional listo para compilar y ejecutar con la simulación en consola:
import java.util.ArrayList;
import java.util.List;
class EspadaMaestra {
private int poder;
public EspadaMaestra(int poder) { this.poder = poder; }
public int desatarTajo() {
System.out.println(" ✨ ¡Rayo de luz sagrada de la Espada Maestra!");
return poder;
}
}
class EscudoHyliano {
private int durabilidad = 100;
public int ejecutarParry(int danio) {
boolean exito = Math.random() < 0.40;
if (exito) {
System.out.println(" 🛡️ ¡PARRY PERFECTO! Daño completamente desviado!");
return 0;
}
return Math.max(1, danio - 3);
}
}
class PlatoCocinado {
private String nombre;
private int corazones;
private boolean consumido = false;
public PlatoCocinado(String n, int c) { this.nombre = n; this.corazones = c; }
public int comer() {
if (!consumido) { consumido = true; return corazones; }
return 0;
}
public String getNombre() { return nombre; }
}
class HeroeHyrule {
private String nombre;
private int corazones;
private EspadaMaestra espada;
private EscudoHyliano escudo;
private List<PlatoCocinado> alforja;
public HeroeHyrule(String nombre, int corazones, EspadaMaestra espada, EscudoHyliano escudo) {
this.nombre = nombre;
this.corazones = corazones;
this.espada = espada;
this.escudo = escudo;
this.alforja = new ArrayList<>();
}
public void agregarPlato(PlatoCocinado p) { alforja.add(p); }
public void ataqueGiratorio(HeroeHyrule rival) {
System.out.println("🌀 " + nombre + " ejecuta Ataque Giratorio con la Espada Maestra!");
int d = espada.desatarTajo();
rival.recibirAtaque(d);
}
public void recibirAtaque(int danio) {
int finalD = escudo != null ? escudo.ejecutarParry(danio) : danio;
corazones = Math.max(0, corazones - finalD);
System.out.println(" 💔 " + nombre + " Corazones: " + corazones);
}
public void comerReceta(int i) {
if (i >= 0 && i < alforja.size()) {
PlatoCocinado plato = alforja.get(i);
int h = plato.comer();
if (h > 0) {
corazones += h;
System.out.println("🍗 " + nombre + " comió " + plato.getNombre() + " (+ " + h + " corazones).");
}
}
}
}
public class Main {
public static void main(String[] args) {
HeroeHyrule link = new HeroeHyrule("Link", 15, new EspadaMaestra(6), new EscudoHyliano());
link.agregarPlato(new PlatoCocinado("Salteado de Carne y Setas", 5));
HeroeHyrule darkLink = new HeroeHyrule("Dark Link", 15, new EspadaMaestra(5), new EscudoHyliano());
link.ataqueGiratorio(darkLink);
darkLink.ataqueGiratorio(link);
link.comerReceta(0);
}
}Acceso Privado a Resultados
Ingresa la clave para ver el código de solución en Java


