#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
const int ancho_tablero = 10;
const int alto_tablero = 10;
const int tipos_barcos = 5;
const char esAGUA = 247; //codigo ASCII para un caracter con forma de agua
const char esIMPACTO = 'X';
const char esBARCO = 'B';
const char esFALLO = '0';
struct PUNTO {
//una localizacion definida en la cuadricula por las coordenadas X(horizontal) Y(vertical)
int X;
int Y;
};
struct BARCO {
//nombre del barco
string nombre;
//Total de puntos en la cuadricula
int longitud;
//Coordenadas de estos puntos
PUNTO onGrid[5]; //0-4 max longitud del barco mas largo
//un booleano para saber si los puntos son "impacto" o no
bool banderaImpacto[5];
} barco[tipos_barcos];
struct JUGADOR {
char grid[alto_tablero][ancho_tablero];
} jugador[3]; //solo se usan los jugadores 1 y 2
enum DIRECCION {HORIZONTAL, VERTICAL};
struct UBICARBARCOS {
DIRECCION direccion;
BARCO TipoBarco;
};
bool juegoenProgreso = false;
//Funciones
void CargarBarcos();
void ReiniciarTablero();
void DibujarTablero ( int );
UBICARBARCOS EntradaUbicaciondeBarcos();
bool EntradaAtaqueJugador ( int&, int&, int );
bool comprobarFinJuego ( int );
int main() {
CargarBarcos();
ReiniciarTablero();
//fase del juego de "UBICAR BARCOS"
//recorre a traves de cada jugador...
for ( int unjugador = 1; unjugador < 3; ++unjugador ) {
//reccore a traves de cada tipo de barco a ubicar
for ( int barcoActual = 0; barcoActual < tipos_barcos; ++barcoActual ) {
//muestra el tablero de juego para jugador
system ( "cls" );
DibujarTablero ( unjugador );
//da las intrucciones
cout << "\n";
cout << "INSTRUCCIONES (Jugador " << unjugador << ")\n\n";
cout << "Estas apunto de colocar tus barcos. La manera de hacerlo:\n";
cout << "Mirando (0:Horizontal,1:Vertical), X (fila superior) coords, Y (lado izquierdo) coordenadas\n";
cout << "Ejemplo: 0 7 2 esto pondra un barco empezando en X:7 Y:2 en sentido horizontal\n\n";
cout << "barco a ubicar: " << barco[barcoActual].nombre << " que tiene una longitud de " << barco[barcoActual].longitud << "\n";
cout << "¿Donde quieres ubicarlo? ";
//obtiene la entrada del jugador y hace un bucle hasta que una buena entrada sea retornada
UBICARBARCOS unBarco;
unBarco.TipoBarco.onGrid[0].X = -1;
while ( unBarco.TipoBarco.onGrid[0].X == -1 ) {
unBarco = EntradaUbicaciondeBarcos();
}
//combina los datos del jugador con los datos del "barco actual"
unBarco.TipoBarco.longitud = barco[barcoActual].longitud;
unBarco.TipoBarco.nombre = barco[barcoActual].nombre;
//Agrega el PRIMER punto de cuadricula para el tablero de juego del jugador actual
jugador[unjugador].grid[unBarco.TipoBarco.onGrid[0].X][unBarco.TipoBarco.onGrid[0].Y] = esBARCO;
//determina TODOS los puntos de la cuadricula basado en la longitud y la direccion
for ( int i = 1; i < unBarco.TipoBarco.longitud; ++i ) {
if ( unBarco.direccion == HORIZONTAL ) {
unBarco.TipoBarco.onGrid[i].X = unBarco.TipoBarco.onGrid[i - 1].X + 1;
unBarco.TipoBarco.onGrid[i].Y = unBarco.TipoBarco.onGrid[i - 1].Y;
}
if ( unBarco.direccion == VERTICAL ) {
unBarco.TipoBarco.onGrid[i].Y = unBarco.TipoBarco.onGrid[i - 1].Y + 1;
unBarco.TipoBarco.onGrid[i].X = unBarco.TipoBarco.onGrid[i - 1].X;
}
//agrega los puntos de cuadricula restantes para el tablero de juego del jugador actual
jugador[unjugador].grid[unBarco.TipoBarco.onGrid[i].X][unBarco.TipoBarco.onGrid[i].Y] = esBARCO;
}
//recorre de vuelta a traves de cada tipo de barco
}
//recorre de vuelta a traves de cada jugador
}
//********* FINALIZAR CON LA FASE DE UBICAR BARCOS *********************************
//************************************************** ***************************
//listo para jugar
juegoenProgreso = true;
int jugadorActual = 1;
do {
//como estamos atacando ahora se muestra el tablero del jugador enemigo
int jugadorEnemigo;
if ( jugadorActual == 1 ) jugadorEnemigo = 2;
if ( jugadorActual == 2 ) jugadorEnemigo = 1;
system ( "cls" );
DibujarTablero ( jugadorEnemigo );
//Obtiene las coordenadas de ataque del jugador actual
bool buenaEntrada = false;
int x, y;
while ( buenaEntrada == false ) {
buenaEntrada = EntradaAtaqueJugador ( x, y, jugadorActual );
}
//Revisa el tablero; si un barco esta ahi se coloca "impacto" de lo contrario "fallo"
if ( jugador[jugadorEnemigo].grid[x][y] == esBARCO ) jugador[jugadorEnemigo].grid[x][y] = esIMPACTO;
if ( jugador[jugadorEnemigo].grid[x][y] == esAGUA ) jugador[jugadorEnemigo].grid[x][y] = esFALLO;
//comprueba si el juego finalizo
//Si 0 es retornado nadie ha ganado aun
int unaVictoria = comprobarFinJuego ( jugadorEnemigo );
if ( unaVictoria != 0 ) {
juegoenProgreso = false;
break;
}
//alterna entre cada jugador haciendo el recorrido de vuelta
jugadorActual = ( jugadorActual == 1 ) ? 2 : 1;
} while ( juegoenProgreso );
system ( "cls" );
cout << "\n\nFELICITACIONES!!! Jugador " << jugadorActual << " HA GANADO EL JUEGO!\n\n\n\n";
system ( "pause" );
return 0;
}
bool comprobarFinJuego ( int jugadorEnemigo ) {
bool ganador = true;
//recorre a traves del tablero enemigo
for ( int w = 0; w < ancho_tablero; ++w ) {
for ( int h = 0; h < alto_tablero; ++h ) {
//si quedan barcos el juego no termina aún
if ( ( jugador[jugadorEnemigo].grid[w][h] = esBARCO != jugadorEnemigo ) )
// !=jugadorEnemigo esta parte del codigo me enviaba una advertencia, al usar esa asignación le aseguro al compilador que estoy usando una asignación a jugadorEnemigo y no una comparación
{
ganador = false;
return ganador;
}
}
}
//al llegar aquí algun jugador ha ganado el juego
return ganador;
}
bool EntradaAtaqueJugador ( int& x, int& y, int eljugador ) {
cout << "\nJUGADOR " << eljugador << ", INGRESA COORDENADAS PARA ATACAR: ";
bool buenaEntrada = false;
cin >> x >> y;
if ( x < 0 || x >= ancho_tablero ) return buenaEntrada;
if ( y < 0 || y >= alto_tablero ) return buenaEntrada;
buenaEntrada = true;
return buenaEntrada;
}
UBICARBARCOS EntradaUbicaciondeBarcos() {
int d, x, y;
UBICARBARCOS tmp;
//Se usa para comprobar un mal retorno
tmp.TipoBarco.onGrid[0].X = -1;
//Obtiene tres enteros del usuario
cin >> d >> x >> y;
if ( d != 0 && d != 1 ) return tmp;
if ( x < 0 || x >= ancho_tablero ) return tmp;
if ( y < 0 || y >= alto_tablero ) return tmp;
//buen ingreso
tmp.direccion = ( DIRECCION ) d;
tmp.TipoBarco.onGrid[0].X = x;
tmp.TipoBarco.onGrid[0].Y = y;
return tmp;
}
void CargarBarcos() {
//establece el valor por defecto para los barcos que planeamos incluir en el juego
//IMPORTANTE!! > COMO SE VIO EN "TIPOS_BARCOS" -por defecto=5 (0-4)
barco[0].nombre = "Crucero"; barco[0].longitud = 2;
barco[1].nombre = "Fragata"; barco[1].longitud = 3;
barco[2].nombre = "Submarino"; barco[2].longitud = 3;
barco[3].nombre = "Escolta"; barco[3].longitud = 4;
barco[4].nombre = "Acorazado"; barco[4].longitud = 5;
}
void ReiniciarTablero() {
//recorre a traves de cada jugador
for ( int jgdr = 1; jgdr < 3; ++jgdr ) {
//Para cada punto de la cuadricula, coloca contenido como "agua"
for ( int w = 0; w < ancho_tablero; ++w ) {
for ( int h = 0; h < alto_tablero; ++h ) {
jugador[jgdr].grid[w][h] = esAGUA;
}
}
//recorre de vuelta al siguiente jugador
}
}
void DibujarTablero ( int jugadorActual ) {
//dibuja el tablero para un jugador ("jugador actual")
cout << "TABLERO DE JUEGO DEL JUGADOR " << jugadorActual << "\n";
cout << "----------------------\n";
//recorre a traves de la fila superior (ancho_tablero) y el numero de columnas
cout << " ";
for ( int w = 0; w < ancho_tablero; ++w ) {
if ( w < 10 )
//Numera caracter de largo 1, agrega dos espacios despues
cout << w << " ";
else if ( w >= 10 )
//Numera dos caracteres de largo, agrega un solo espacio despues
cout << w << " ";
}
cout << "\n";
//recorre a traves de cada punto de la cuadricula y lo muestra en consola
for ( int h = 0; h < alto_tablero; ++h ) {
for ( int w = 0; w < ancho_tablero; ++w ) {
//Si este es el primer punto de cuadricula(a la izquierda), numera la cuadricula primero
if ( w == 0 ) cout << h << " ";
//si h tiene un solo caracter de largo agrega un espacio extra para mantener los numeros alineados
if ( w < 10 && w == 0 ) cout << " ";
//muestra el contenido de la cuadricula (si el juego no ha comenzado aun , estamos colocando los barcos, entonces muestra los barcos
if ( juegoenProgreso == false ) cout << jugador[jugadorActual].grid[w][h] << " ";
//no muestra los barcos, pero muestra daño si es un impacto
if ( juegoenProgreso == true && jugador[jugadorActual].grid[w][h] != esBARCO )
{cout << jugador[jugadorActual].grid[w][h] << " ";}
else if ( juegoenProgreso == true && jugador[jugadorActual].grid[w][h] == esBARCO )
{cout << esAGUA << " ";}
//si llegamos al borde entonces empieza una nueva linea
if ( w == ancho_tablero - 1 ) cout << "\n";
}
}
}