Necesitas una estructura que te permita almacenar el estado y/o la posición de los barcos:
enum pos
{
Ninguna,
Horizontal,
Vertical
};
struct coord
{
int x;
int y;
};
struct barco
{
int longitud;
struct coord coordenadas;
enum posicion pos;
int estado;
};
Con esto ya puedes "modelar" cada uno de los barcos. Lo ideal sería tener una instrucción que permitiese crear los barcos. Algo del tipo:
struct barco NuevoBarco( int longitud )
{
struct barco to_return;
to_return->longitud = longitud;
to_return->coordenadas.x = -1; // Para indicar que no esta posicionado
to_return->coordenadas.y = -1; // Para indicar que no esta posicionado
to_return->pos = Ninguna;
to_return->estado = longitud;
return to_return;
}
En este caso, "estado" almacena la "vida" del barco... si la vida llega a 0, el barco se considera hundido.
Como puedes ver, no uso memoria dinámica para los barcos... no es necesaria.
Una vez tienes la flota creada, lo suyo es posicionarla. Por la cantidad de barcos que hay no se me ocurre una combinación (tampoco voy a buscarla) en la que no se puedan colocar todos los barcos... yo, en primer lugar, crearía los barcos del más grande al más pequeño y, después, intentaría posicionarlos en ese orden.
Una forma de posicionar los barcos pudiera ser: En un bucle, elegir al azar un par de coordenadas (x,y) y una posición (vertical u horizontal), después compruebas si el barco "entra" en esa posición... y repites el bucle hasta dar con una posición "válida".
Ahora toca inicializar el tablero para borrar la partida anterior si la hubiese.
Una vez has realizado estos pasos el programa está listo para iniciar la partida.
Cada vez que introduces unas coordenadas de disparo puedes hacer los siguientes chequeos:
* Si es una casilla que ya ha sido atacada, se piden nuevas coordenadas
* Se recorre el array de barcos y se comprueba si algún barco se encuentra en la coordenada seleccionada... si es así, actualizas el estado del barco para anotar un "toque". Llegados a este punto, si la vida de 3 barcos es 0, el jugador gana la partida. Si no hay barcos en la coordenada marcada... indicas "agua".
A continuación el prototipo de una función que determine si un barco ha resultado "tocado".
int BarcoTocado( struct barco* barco, struct coord coordDisparo )
{
if ( barco->pos == Horizontal )
{
struct coord coordBarco = barco->coord;
int i = barco->longitud;
while ( i > 0 )
{
if (coordBarco == coordDisparo )
return 1;
coordBarco.x++;
i--;
}
}
else
{
// ...
}
return 0;
}
Creo que con estas guías debería ser sencillo completar el programa.