Guerra Naval en Java desde cero ☕
Para lograr entender mejor el ejercicio, vamos a usar Programación Orientada a Objetos ya que con esto podemos crear el tablero y ahorrar código, así que empecemos.
Tablero
public class Tablero {
private int aciertos;
private int fallos;
public final int filas;
public final int columnas;
private int tabla[][];
//-----------
public Tablero(int filas, int columnas) {
this.filas = filas;
this.aciertos = 0;
this.fallos = 0;
this.columnas = columnas;
this.tabla = new int[filas][columnas];
}
public int[][] ubicarFichas(int nfichas) {
if (nfichas > this.columnas * this.filas) {
} else {
for (int i = 0; i < nfichas; i++) {
int posX = (int) (Math.random() * this.filas);
int posY = (int) (Math.random() * this.columnas);
if (tabla[posX][posY] == 1) {
i--;
} else {
this.tabla[posX][posY] = 1;
}
}
}
return this.tabla;
}
public boolean atacar(int x, int y, Tablero tablaRival) {
if (tablaRival.tabla[x][y] == 1) {
tablaRival.tabla[x][y] = 0;
this.aciertos += 1;
return true;
} else {
this.fallos += 1;
return false;
}
}
public boolean mostrarValidacion(Tablero t1, Tablero t2){
boolean ganador = validar(t1, t2);
return ganador;
}
private boolean validar(Tablero t1, Tablero t2) {
int a[][] = t1.getTabla();
int b[][] = t2.getTabla();
int nBarcosA = 0;
int nBarcosB = 0;
for (int i = 0; i < this.filas; i++) {
for (int j = 0; j < this.columnas; j++) {
if (a[i][j] == 1) {
nBarcosA += 1;
}
}
}
for (int i = 0; i < this.filas; i++) {
for (int j = 0; j < this.columnas; j++) {
if (b[i][j] == 1) {
nBarcosB += 1;
}
}
}
boolean salida = (nBarcosA == 0 || nBarcosB == 0) ? true : false;
return salida;
}
public int[][] getTabla() {
return tabla;
}
public int getAciertos() {
return aciertos;
}
public int getFallos() {
return fallos;
}
public void mostrarTabla(Tablero t1, Tablero t2) {
boolean ganador = validar(t1, t2);
if (ganador) {
System.out.println("\n \tYa hay ganador");
System.out.println("\t jugador 1");
System.out.println("\t aciertos: " + t1.getAciertos());
System.out.println("\t fallos: " + t1.getFallos());
System.out.println("\n \t jugador 2");
System.out.println("\t aciertos: " + t2.getAciertos());
System.out.println("\t fallos: " + t2.getFallos());
}
System.out.println("\n tabla Jugador1");
for (int i = 0; i < this.filas; i++) {
for (int j = 0; j < this.columnas; j++) {
System.out.print(t1.tabla[i][j] + " ");
}
System.out.println("");
}
System.out.println("\n tabla Jugador2");
for (int i = 0; i < this.filas; i++) {
for (int j = 0; j < this.columnas; j++) {
System.out.print(t2.tabla[i][j] + " ");
}
System.out.println("");
}
}
}
La clase tablero va a tener las características del juego, tales como el número de aciertos, el número de fallos, filas y columnas del tablero y una matriz que representa el tablero, a la misma vez se encarga de la lógica relacionada a las acciones del juego, tales como ubicar las fichas, atacar y validar si ya hay un ganador.
public int[][] ubicarFichas(int nfichas)
Este método se encarga de ubicar las fichas o barcos de forma aleatoria, el parámetro int nfichas significa el número de fichas que se van a ubicar en el tablero, a su vez este método se encarga de controlar el caso de que una ficha se ubique encima de otra, ya que esto no se puede, para que queden el número de fichas correspondiente en lugares diferentes.
public boolean atacar(int x, int y, Tablero tablaRival)
Este método se encarga de hacer el ataque al rival, para ello se necesitan las coordenadas (x, y) a las que el jugador quiere atacar y el tablero del rival para verificar si en esa coordenada había un barco, en caso de que haya uno se cambia por un 0 y se aumenta el número de aciertos, y se retorna verdadero, para decir que si le derribó un barco a su rival.
private boolean validar(Tablero t1, Tablero t2)
Este método recorre el tablero del jugador 1 y el jugador 2, para ir contando el número de barcos que cada uno tiene, este ayuda a saber si un jugador no tiene barcos, es decir, si uno de los jugadores ya perdió.
Main
import java.util.Scanner;
public class PrincipalGuerraNaval {
public static void main(String[] args) {
Scanner en = new Scanner(System.in);
boolean siOno;
boolean ganador;
int filas = 5;
int columnas = 5;
int atacarEnX;
int atacarEnY;
int numeroFichas = 3;
Tablero j1 = new Tablero(filas, columnas);
j1.ubicarFichas(numeroFichas);
Tablero j2 = new Tablero(filas, columnas);
j2.ubicarFichas(numeroFichas);
ganador = j1.mostrarValidacion(j1, j2);
j1.mostrarTabla(j1, j2);
while (ganador == false) {
System.out.println("\n Ataca jugador1 ");
System.out.print("X: ");
atacarEnX = en.nextInt();
System.out.print("Y: ");
atacarEnY = en.nextInt();
siOno = j1.atacar(atacarEnX, atacarEnY, j2);
System.out.println(siOno);
j2.mostrarTabla(j1, j2);
ganador = j1.mostrarValidacion(j1, j2);
if (ganador == true) {
break;
}
while (siOno) {
System.out.println("\n Ataca otra vez jugador1 ");
System.out.print("X: ");
atacarEnX = en.nextInt();
System.out.print("Y: ");
atacarEnY = en.nextInt();
siOno = j1.atacar(atacarEnX, atacarEnY, j2);
System.out.println(siOno);
j1.mostrarTabla(j1, j2);
ganador = j1.mostrarValidacion(j1, j2);
if (ganador == true) {
break;
}
}
System.out.println("\n Ataca jugador2 ");
System.out.print("X: ");
atacarEnX = en.nextInt();
System.out.print("Y: ");
atacarEnY = en.nextInt();
siOno = j2.atacar(atacarEnX, atacarEnY, j1);
System.out.println(siOno);
j1.mostrarTabla(j1, j2);
ganador = j1.mostrarValidacion(j1, j2);
if (ganador == true) {
break;
}
while (siOno) {
System.out.println("\n Ataca otra vez jugador2 ");
System.out.print("X: ");
atacarEnX = en.nextInt();
System.out.print("Y: ");
atacarEnY = en.nextInt();
siOno = j2.atacar(atacarEnX, atacarEnY, j1);
System.out.println(siOno);
j1.mostrarTabla(j1, j2);
ganador = j1.mostrarValidacion(j1, j2);
if (ganador == true) {
break;
}
}
}
}
}
Finalmente, la clase Main, es la que le da vida al juego, en esta creamos los tablero de cada uno de los jugadores y mostramos por consola las acciones para que se pueda disfrutar el juego.