No dupliques todo el contenido de un mensaje si no vas a citar nada, si has de referirte a una persona simplemente copia su alias (y lo pones en negrita para llamar con claridad su atención) y responde simplemente... Imagina que ahora yo cito todo tu mensaje, y luego tu otra vez el mío... al anidarse los mensajes sería engorroso y largo (mucho scroll) para llegar al texto que uno escribe.
Ayer, olvide´al final, poner como se llemaba , aunque es claro... aprovecho, para resumir la lógica...
La lógica de un modo escuesta (más claro ahora que se sabe que aplicas la regla de espacio entre barcos):
Resultado solo debeiera tener dos valores: Agua o tocado, luego mejor un buleano para esto. Si ya fue tocado con anteroridad en sucesivas veces esa casilla debe devolver agua.
Como usamos una variable llamada 'tocado' al parámetro lo llamamos agua y entra con TRUe cuando se el resultado es 'agua' y con FALSE, cuando el resutado fue 'tocar la casilla a la que se disparó'.
buleano = Funcion SiguienteDisparo(buleano Agua, byte x, byte y)
Si (agua = FALSE)
Si (Tocado > 0)
Aumentar tocado // Otra casilla tocada de la nave (o de una nave contigua)
Avanzar la cordenada en la que se está (según cada caso).
Si (ConsultarBarcoHundido(Tocado) = TRUE)
Tocado = 0
Devolver FALSE
Fin si
Sino // aquí hay un buque (lo acabamos de descubrir)... insistiremos hasta hundirlo.
Tocado = 1
Orientacion = 1
Avanzar cordenada x
Fin si
Devolver TRUE
Sino // agua = TRUE
Si (Tocado > 0) // un disparo previo acertó?,
Orientacion += 1 // cambiamos de orientación a la siguiente
Cambiar las cordenadas a la casilla adhiacente a la 'arroba' en la orientación actual (que acabamos de saltar).
Devolver TRUE
Sino
Devolver FALSE
Fin si
Fin si
Fin funcion
Y la función sería invocada así:
buleano agua, seguirPista
Si (seguirPista = FALSE)
x = Random(entre 0 y maxColumna)
y = Random(entre 0 y maxFila)
//Sino
// 'x' e 'y', fueron actualizadas en la función SiguienteDisparo, se usan esos valores actualizados.
Fin si
agua = Disparar(x, y)
seguirPista = SiguienteDisparo(agua, x, y)
...y para ser más precisos, elegir 'x' e 'y' de forma aleatoria, no debe ser del todo exacto, puede resultar muy costoso, ya que a medida que se juega, ya hay casillas que fueron elegidas, por tanto no tiene sentido volverlas a elegir... cuantas menos queden, más costará tomar al azar una casilla libre... no es nada óptimo.
Aquí la solución, si no la entiendes pregunta...:
1º Mantener datos de las casillas. Se crea un array con el número de casillas totales. y una variable indica cuanto son estas.
Al comenzar la partida, se meten todas las casillas en un array, que luego es barajado.
ArrayEntero Casillas()
entero maxCasillas, maxFilas, maxColumnas
Funcion NuevaPartida(filas, columnas)
entero k
maxFilas =filas
maxColumnas = columnas
maxCasillas = ((filas * columnas) -1) // -1 aquí, para evitar en todas partes poner -1...
Alojar espacio para Casillas(0 a maxCasillas)
Bucle para k desde 0 a maxCasillas
Casillas(k) = k
Siguiente
BarajarCasillas
... otras cosas en esta función necesarias antes de empezar la partida (como posicionar las flotas)
fin funcion
2º La función BarajarCasillas, reordena de forma aleatoria el contenido en el array.
Funcion BarajarCasillas
entero k, j, i
Bucle para k desde maxCasillas hasta 1 hacia atrás
j = Random(entre 0 y k)
i = Casillas(j)
Casillas(j) = Casillas(k)
Casillas(k) = i
Siguiente
Fin funcion
3º Elegir una casilla al azar entre las disponibles, luego la última disponible ocupa la posición de la tomada, y se descuenta 1 de las disponibles. Si no hay casillas disponibles daría error, pero eso implica que quedan barcos sin hundir pero se ha disparado a todas las casillas, luego hay un error de lógica en el juego (por ello no se contempla en lafunción que no haya casillas disponbles, el juego debe acabar antes que eso ocurra).
entero = Funcion CasillaRandom
entero z
z = Random(entre 0 y maxCasillas) // Elegir una casilla al azar entre las disponibles.
Casillas(z) = Casillas(maxCasillas-1) // movemos la última disponible al hueco de la casilla a devolver.
maxCasillas -= 1 // una casilla libre menos.
Devolver z // entregamos la casilla elegida (una libre)
fin funcion
4º Derivar la casilla a las cordenadas que toque:
Básicamente es convertir un índice de un array unidimensional en los índices de un array bidimensional.
Funcion GetCordenadasFromCasilla (casilla, x, y) // 'x' e 'y' son de salida...
x = (casilla modulo maxFilas)
y = (casilla \ maxFilas) // el '/' es una división entera, o bien una división (flotante) a la que se le retiran los decimales (convenrtido en entero)
Fin Funcion
Y por fin modificamos el fragmento de pseudocódigo de más arriba para
elegir al azar casillas, pero solo entre las que aún están libres. buleano agua, seguirPista
entero casilla
Si (seguirPista = FALSE)
casilla = CasillaRandom
GetCordenadasFromCasilla(casilla, x, y)
Fin si
agua = Disparar(x, y)
seguirPista = SiguienteDisparo(agua, x, y)