El programa

Todo el programa ha sido creado usando programación orientada a objetos, y se compone de varias clases que se explican a continuación.

Tipos enumerados

Existen dos, uno para codificar direcciones, que se aplica a la orientación de los barcos, o a los movimientos a través del tablero (veremos esto con más detalle).

El otro sirve para codificar el contenido de cada casilla, dentro de los seis posibles valores.

enum direccion {derecha=0, abajo, izquierda, arriba};
enum contenido {libre=0, agua, buque, tocado, hundido, novalido};

Espacio con nombre "cte"

Las constantes del juego de definen y declaran en un espacio con nombre llamado cte de modo que todos los jugadores y el programa que los enfrenta usen los mismos valores. Estas definiciones están en el fichero "const.h".

namespace cte {
   const int alto = 10;
   const int ancho = 10;
   const int nBarcos = 10;
   const int lBarco[nBarcos] = {4, 3, 3, 2, 2, 2, 1, 1, 1, 1};
   const int nPartidas = 10;
};

Estos valores de constantes corresponden al juego tradicional de "Hundir la flota", es decir, un tablero de 10 x 10 casillas, y 10 barcos, uno de cuatro casillas, dos de tres casillas, tres de dos casillas y cuatro de una.

Es fácil modificar esas constantes para todo el juego editando este fichero, de modo que podemos usar tableros más grandes o más barcos de distintos tamaños.

Todos los jugadores deben usar estas constantes mediante las variables de este espacio con nombre, y nunca como constantes literales, no hacerlo así puede provocar errores y por supuesto, la descalificación del jugador.

Clases auxiliares

Hemos definido varias clases para manejar objetos de uso frecuente en el juego. Las declaraciones están incluidas en el fichero "clases.h", y las definiciones en "clases.cpp".

Clase Coordenada

class Coordenada {
  public:
   Coordenada(int _x=0, int _y=0) : x(_x), y(_y) {}
   Coordenada operator+(const Coordenada &c) {
      Coordenada temp;
      temp.x = x + c.x;
      temp.y = y + c.y;
      return temp;
   }
   bool operator==(const Coordenada &c) {
      return (x == c.x) && (y == c.y);
   }
   void Incrementar(direccion, int=1);
   int X() const {return x;}
   int Y() const {return y;}
  private:
   int x;
   int y;
};

Sirve para almacenar y manejar coordenadas de dos dimensiones correspondientes al tablero de juego. Dispone de un constructor con valores por defecto para los parámetros, dos operadores, el de suma y el de igualdad, y tres funciones, para incrementar y obtener las componentes x e y.

La función de incrementar incrementa la coordenada en la dirección indicada y el número de unidades indicado, (1 por defecto).

Estructura DatosBarco

struct DatosBarco {
   Coordenada inicio;
   direccion dir;
};

Usaremos esta estructura para pedir los datos de un barco a los jugadores.

Clase ErrorBarco

class ErrorBarco: public std::exception {
  public:
   ErrorBarco() : exception() {}
   const char* what() const throw() {
      return "Barco fuera de tablero";
   } 
};

Clase derivada de "exception", nos servirá para indicar errores en la colocación de barcos.

Clase Barco

class Barco {
  public:
   Barco(Coordenada c, int l, direccion d) throw(ErrorBarco, std::bad_alloc);
  ~Barco();
   // Devuelve -1 si la coordenada no pertenece al barco
   // o la posición si pertenece
   int Pertenece(Coordenada c) const;
   Coordenada Posicion(int) const;
   void Marcar(Coordenada);
   bool Hundido() const;
  private:
   int longitud;
   Coordenada *posicion;
   bool *estado;
   direccion dir;
};

El constructor admite como parámetros una coordenada, una longitud y una dirección. Entre las tres definen la posición, longitud y dirección del barco. El constructor puede fallar porque el barco resulte estar fuera del tablero o por un error en la asignación de memoria dinámica.

El método Pertenece nos indica si la coordenada que recibimos como parámetro pertenece o no al barco. En caso de pertenecer nos devuelve la posición del barco concreta, empezando en 0 para la coordenada recibida como parámetro en el constructor. Si no pertenece devuelve el valor -1.

tablero

En este ejemplo, si llamamos a Pertenece con las coordenadas "D3", (3,2), tendremos como resultado el valor 2, ya que en esa casilla está la sección número 2 del barco.

Posicion devuelve la coordenada de la casilla que ocupa el orden indicado en el parámetro.

Marcar sirve para marcar la casilla correspondiente a la coordenada indicada como tocado, si es que pertenece al barco, claro.

Hundido devuelve "true" si al barco está hundido, es decir, si todas sus posiciones han sido tocadas.

Los datos almacenados nos permiten controlar el estado y posición de cada una de las casillas ocupadas por el barco.

posicion es un array dinámico con las coordenadas de cada casilla. estado es un array dinámico con el estado de cada casilla. longitud es el tamaño del barco.