Вы находитесь на странице: 1из 10

MEMORIA DE LA PRÁCTICA DE

LENGUAJES DE PROGRAMACIÓN
CURSO 2012-2013

EL JUEGO DE HUNDIR LA
FLOTA

Álvaro de Torres Pérez -D.N.I. 36.070.917V


Centro asociado: Pontevedra
Teléfono: 986205072
e-mail: atorres5@alumno.uned.es
Memoria de la práctica curso 2012-2013:
“Hundir la flota”

1. REQUISITOS DE LA PRÁCTICA
La práctica consiste en implementar el juego “Hundir la flota” para dos jugadores, de los
cuales uno será el ordenador.
Se trata de hundir los barcos de la flota del oponente antes de que el rival haga lo propio. Por
turnos alternativos los jugadores irán eligiendo casillas del tablero disponible y disparando.
Si el tiro da en el agua, pasará el turno y si acierta podrá escoger de nuevo una casilla.
Cada jugador dispondrá de una flota de 1 portaaviones (5 casillas), 2 acorazados (4 casillas),
2 fragatas (3 casillas) y 2 submarinos (2 casillas). Estos barcos se dispondrán en cualquier
posición que el jugador desee y con orientación horizontal o vertical (nunca diagonal).
La aplicación pedirá al jugador humano que coloque los barcos y comprobará que ninguno
se toque, es decir, que no ocupen casillas adyacentes. En este caso, se lo indicará al jugador y
le pedirá nuevas coordenadas.
La aplicación colocará de manera aleatoria los barcos del jugador ordenador. Habrá de
cumplir las mismas restricciones.

2. DESARROLLO DEL JUEGO


El ordenador coloca sus barcos y comienza el turno de tiradas. Comienza el humano, que si
acierta vuelve a tirar. Si no acierta, el turno pasa al ordenador.
Para este, generará una posición aleatoria del tablero. Si acierta, volverá a tirar, y si no
acierta pierde el turno. Las posiciones de tiradas del ordenador serán, por este orden:

• La casilla inmediatamente superior a la de la tirada anterior.


• La que está a la derecha.
• La inmediatamente inferior.
• La que está a la izquierda.

El juego acabará cuando el jugador o el ordenador hayan alcanzado a todos los barcos de su
oponente. Se debe implementar un mecanismo de abandono del juego en cualquier
momento por parte del jugador.

3. RESTRICCIONES DE LA PRÁCTICA
• El tablero de juego será de 10x10 casillas, aunque se deberá poder variar el tamaño
del tablero sin tener que modificar nada en el algoritmo, salvo el valor de la
constante ancho/alto.
• No se pueden colocar buques en diagonal.
• No se permiten barcos colocados en las casillas adyacentes a otro barco.
• En cada turno del jugador se mostrarán el tablero con los disparos que ha hecho, los
barcos hundidos (colocados en el tablero) y el estado de la flota (barcos a flote).
• La forma de representar los barcos en el tablero y los disparos fallidos queda a
criterio del alumno.
• Todo el proceso del juego en pantalla de mostrará en modo texto.

2
Memoria de la práctica curso 2012-2013:
“Hundir la flota”

4. CONSIDERACIONES DE DISEÑO/IMPLEMENTACIÓN DE LA
PRÁCTICA
Basándome en el documento de Orientaciones las recomendaciones, he implementado 6
clases, de las cuales 3 son exigidas en dicho documento (Barco, Jugador y Ordenador), 1 es
necesaria para poner en marcha y jugar el juego (Hundir), y 1 me ha parecido conveniente
para separar y clarificar el proceso de establecimiento de las coordenadas (Coordenada).

Para las clases referidas a los jugadores he creado una clase genérica Jugador, de la cual son
herederas dos subclases, JugadorPersona y JugadorOrdenador.

Hay un detalle respecto a la implementación de las coordenadas que puede resultar un


tanto confuso: cuando se pide la coordenada indica que tiene que ir en formato (x,y) donde “x” se
refiere a las columnas (eje horizontal) e “y” se refiere a las filas (eje vertical). Por tanto, en mi
programa la manera de establecer las coordenadas es:

• Posición x en el tablero: corresponde con el eje horizontal (es decir, representa el nº de


columna entre 1 y 10).
• Posición y en el tablero: corresponde con el eje vertical (es decir, representa el nº de fila
entre 1 y 10 ).

En el enunciado de la práctica existe un ejemplo en que las coordenadas se introducen en formato


(y,x), pero entiendo que si establecemos las coordenadas en relación al tablero, el formato
implementado es más claro.

3
Memoria de la práctica curso 2012-2013:
“Hundir la flota”
5. DESCRIPCIÓN DE LAS CLASES IMPLEMENTADAS

a. CLASE “BARCO”

La clase Barco es la que gestiona las funcionalidades propias de los barcos, tanto del jugador
persona como del ordenador.

Atributos de la clase:

• Tamaño del Barco.


• Lista de coordenadas de posición de los barcos.
• Casillas que han sido alcanzadas.

Métodos de la clase:

• Método “Coordenada”, que devuelve la lista de coordenadas del barco.


• Método “insertarCoordenadas”, que dada una coordenada inicial y una orientación
calcula la posición de un barco.
• Método “barcoEnCoordenada”, indica si la coordenada que se le pasa pertenece o no al
barco y sus alrededores.
• Método “barcoHundido”, que indica si el barco está hundido o no.

b. CLASE “COORDENADA”

La clase Coordenada es la que gestiona las distintas celdas dentro del tablero.

Atributos de la clase:

• Posición “x” en el tablero. Corresponde con el eje horizontal (que indica el nº de


columna).
• Posición “y” en el tablero. Corresponde con el eje vertical (que indica el nº de fila).

Métodos de la clase:

• Método “get_x”, que devuelve la coordenada X de la casilla.


• Método “get_y”, que devuelve la coordenada Y de la casilla.
• Método “set_x”, que proporciona valores a la coordenada X de la casilla.
• Método “set_y”, que proporciona valores a la coordenada Y de la casilla.
• Método “equal”, que compara si dos coordenadas son iguales y devuelve el resultado.
• Método “toString”, que devuelve en formato "(X, Y)" la coordenada

c. CLASE “JUGADOR”

La clase Jugador implementa las funcionalidades que son genéricas para ambos jugadores,

4
Memoria de la práctica curso 2012-2013:
“Hundir la flota”
tanto el humano (JugadorPersona) como el ordenador (JugadorOrdenador).

Atributos de la clase:

• Lista de los barcos correspondientes al jugador.


• Representación del tablero de disparos del jugador.
• Número de barcos que contiene el tablero.
• Alto máximo del tablero.
• Ancho máximo del tablero.
• Buffer para la lectura de la pantalla.

Tipos ennumerados:

Mejoran la legibilidad del código porque nos permiten ahorrar líneas repetitivas en las que el
único parámetro que cambia es precisamente el ennumerado. En el caso de la clase jugador
los tipos que se han implementado son:

• Enumerado con el que se representan los distintos estados en que se puede encontrar
una casilla del tablero:
 SinDisparar: No se ha realizado aún un disparo sobre la coordenada.
 Agua: Se ha realizado un disparo y no se ha alcanzado un barco.
 Tocado: Se ha realizado un disparo y se ha alcanzado un barco.

• Enumerado con el que se representan las distintas orientaciones que puede tomar un
barco:
 vertical_arriba.
 vertical_abajo.
 horizontal_izquierda.
 horizontal_derecha.
 Invalido.

Métodos de la clase:

• Método “comprobarBarco”, que al colocar los barcos comprueba si un barco que parte
desde una posición inicial se toca con otro barco.
• Método “esCoordenadaCorrecta”, que indica si la coordenada es correcta y si se
encuentra dentro del tablero.
• Método “actualizaInformacion”, que refresca la información del tablero del jugador.
• Método “mostrarFlota”, que muestra la flota en “modo tablero”.
• Método “mostrarEstadoDisparosPorPantalla”, que proporciona en la pantalla el estado
de los disparos del jugador.
• Método “disparoNoRealizado”, que indica que no se ha disparado en la casilla a la que
se aplica.
• Método “barcoAlcanzado”, que indica si un miembro de la flota ha sido alcanzado.
• Método “flotaHundida”, que comprueba si toda la flota está hundida.

5
Memoria de la práctica curso 2012-2013:
“Hundir la flota”
d. CLASE “JUGADORPERSONA”
La clase JugadorPersona hereda los métodos de la clase Jugador, y es la que implementa las
funcionalidades del jugador humano.

Atributos de la clase:

• Los mismos que en la clase Jugador, además de:


• Lista de coordenadas de los barcos.

Métodos de la clase:

• Método “pedirbarcosAJugador”, que solicita al jugador que coloque los barcos en el


tablero, pidiéndoselos por orden de tamaño: el portaaviones, los dos acorazados, las
dos fragatas y por último los dos submarinos
• Método “pedirBarco”, que coloca el barco en el tablero comprobando si está
correctamente ubicado.
• Método “leerCoordenadaTeclado”, que lee la coordenada que previamente hemos
introducido por el teclado.
• Método “leerOrientacion”, que lee la orientación del barco introducida por el usuario
en el teclado.

e. CLASE “JUGADORORDENADOR”

De la misma manera que la clase anterior, La clase JugadorOrdenador hereda los métodos de
la clase Jugador, y es la que implementa las funcionalidades del ordenador.

Atributos de la clase:

• Los mismos que en la clase Jugador.

Métodos de la clase:

• Método “generarPosicionBarcosAleatoria”, que inicia la generación aleatoria de la


posición de los barcos del ordenador, en el mismo orden de tamaño que en la clase
JugadorPersona: el portaaviones, los dos acorazados, las dos fragatas y por último los
dos submarinos
• Método “generarBarco”, que dado el tamaño indicado del barco genera un barco en
una posición aleatoria.
• Método “generarCoordenadaAleatoria”, que genera una coordenada de forma
aleatoria.
• Método “generarOrientacionAleatoria”, que genera una orientación aleatoria para el
barco que se está ubicando en el tablero (horizontal o vertical, no se permite la
diagonal).
• Método “realizarDisparo”, que genera un disparo del ordenador según se indica en el
enunciado de la práctica, es decir:

 La casilla inmediatamente superior a la de la tirada anterior.

6
Memoria de la práctica curso 2012-2013:
“Hundir la flota”
 La que está a la derecha.
 La inmediatamente inferior.
 La que está a la izquierda.

• Método “set_ultimo_acierto”, que nos indica, en caso de acierto, la coordenada de este


último acierto realizado.

f. CLASE PRINCIPAL “HUNDIR”

La clase “Hundir” es la principal, desde la que se arranca la aplicación y, entre otros


parámetros, incluye las constantes “ANCHO_MAX_TABLERO”, “ALTO_MAX_TABLERO” (ambas
podrían ser modificadas según se exige en las restricciones iniciales de la práctica),
“TAM_MAX_BARCO” y “NUM_TOT_BARCOS”.

Métodos de la clase:

• Método “main”, que da entrada a la aplicación. En esta implementación no lo usaré


porque tengo el siguiente método como base del juego.
• Método “jugar”, que es en el que se implementa el bucle del juego. Incluye una breve
presentación del juego y un texto de ayuda para la colocación de los barcos del
jugador humano.
En este método, se crean las instancias jugador ordenador y jugador persona,
referidas a sus clases correspondientes, y se mantiene el ciclo de turnos de tirada
mientras no se acaba la partida.
Esto incluye la comprobación de las coordenadas de los barcos, de las tiradas, de si los
barcos han sido tocados o hundidos.
También se asegura de mantener los turnos en el orden correcto, de manera que si
hay un acierto el jugador en el turno repite tirada.

6. SOLUCIONES A DIVERSOS PROBLEMAS DE IMPLEMENTACIÓN

a. Reserva de las casillas adyacentes al barco


Una de las dificultades que se encuentran debido a las condiciones iniciales de la práctica es
la referida a reservar las casillas adyacentes a cada barco ubicado para evitar que se
introduzca otro barco pegado al anterior.
La solución que se implementa en esta práctica es mediante la comprobación de si la
coordenada pertenece al barco que estamos ubicando o a sus alrededores:

Función barcoEnCoordenada (Coordenada coord) {


Para cada coordenada adyacente a coord {
Generar coordenada;
}
Para (i=0; i<tamaño del barco; i++){
Si (Coordenada[i]= coord) o (Coordenada[i]= coordenada generada){
Contenido= verdadero;

7
Memoria de la práctica curso 2012-2013:
“Hundir la flota”
Si no
Contenido= falso;
}
Devuelve Contenido;
}
}

b. Asegurar que los barcos no se solapan


El siguiente paso es asegurarse de que el barco que estamos colocando no se toca con otro
barco colocado; esto se comprueba a partir de la coordenada de la posición inicial del barco,
el tamaño del mismo y la orientación:

Función comprobarBarco(int tamanyo, Coordenada coord, Orientacion orientacion, boolean


imprimirError) {
Generar nuevo barco;
Generar la coordenada inicial y la posición del nuevo barco;
Comprobar que no se sale del tablero;
Para (i=0; i<número de barcos colocados; i++){
Para cada coordenada del barco{
Si (alguna coordenada del barco sale de los límites del tablero){
Devuelve error;
}
Si (coordenada del barco= coordenada de barco colocado){
Devuelve error;
}
Si no
Devuelve barco;
}
}
}

c. Asegurar que la orientación no pueda ser diagonal


Cuando ubicamos un barco en el tablero tenemos la restricción de que la orientación no
puede seguir una diagonal del tablero. Para asegurar esta condición, lo que hacemos es pedir
al jugador solamente la coordenada inicial y que escoja la orientación del barco de 4 posibles:
horizontal derecha/izquierda y vertical arriba/abajo. No ofrecemos la posibilidad de escoger
diagonal.

Función insertarCoordenadas(Coordenada coord_ini, Orientacion orientacion){


Inicializar posición con coordenada inicial;
Caso horizontal_derecha{
Para (int i = 1; i < tamaño del barco; i++ ){ // Desplazar hacia la derecha la x tantas
posiciones-1 como tenga el barco
Sumar a la coordenada x 1 posición;
Generar coordenada del barco;
}
}

8
Memoria de la práctica curso 2012-2013:
“Hundir la flota”
Caso horizontal_izquierda{
Para (int i = 1; i < tamaño del barco; i++ ){ // Desplazar hacia la izquierda la x tantas
posiciones-1 como tenga el barco
Restar a la coordenada x 1 posición;
Generar coordenada del barco;
}
}
Caso vertical abajo{
Para (int i = 1; i < tamaño del barco; i++ ){// Desplazar hacia abajo la y tantas
posiciones-1 como tenga el barco
Sumar a la coordenada y 1 posición;
Generar coordenada del barco;
}
}
Caso vertical arriba{
Para (int i = 1; i < tamaño del barco; i++ ){// Desplazar hacia arriba la y tantas
posiciones-1 como tenga el barco
Restar a la coordenada y 1 posición;
Generar coordenada del barco;
}
Caso invalido{
Salir del caso;
}

d. Repetir el tiro en caso de acierto

Tanto para el jugador persona como el jugador ordenador tienen un procedimiento para
comprobar si el tiro ha sido acertado, y en este caso, repetir turno. En el caso del ordenador,
además, el orden de las consiguientes tiradas tras acierto vienen determinadas por las
condiciones iniciales de la práctica. Veamos ambos procedimientos:

I. Repetir el tiro en caso de acierto (válido tanto para el jugador persona


como el ordenador):

Funcion Jugar{
…………….
Distintos métodos
……………….
// Turno jugador
Mostrar estado de los disparos del jugador en pantalla;
Mientras (no acaba partida) y (no acaba turno){
Introducir coordenada de disparo;
Comprobar si es correcta;
Comprobar que no se ha disparado antes en esta coordenada;
Si (no barco alcanzado){
Actualizar información del tablero;
Cambiar el estado de la coordenada a AGUA;

9
Memoria de la práctica curso 2012-2013:
“Hundir la flota”
Fin de turno;
{
Si (barco alcanzado){
Actualizar información del tablero;
Cambiar el estado de la coordenada a TOCADO;
Mostrar estado de los disparos del jugador en pantalla;
Pedir nuevo disparo;
Si (coordenada ya disparada) o (coordenada no valida){
Error;
}
}
}

II. Asegurar el orden correcto de disparos en caso de acierto para el


jugador ordenador:

Este procedimiento asegura que el ordenador repita tiro en caso de acierto siguiendo la pauta que
se exige en las condiciones iniciales, esto es:
 La casilla inmediatamente superior a la de la tirada anterior.
 La que está a la derecha.
 La inmediatamente inferior.
 La que está a la izquierda.

Funcion set_ultimo_acierto(boolean value, Coordenada coord) // Metodo para controlar


el ultimo acierto realizado
Si (es tiro acertado){
Limpiar las listas de orientaciones;
Inicializar listas de orientaciones;
Caso siguiente orientacion{
caso invalido:
No hacer nada;
caso horizontal_derecha:
siguiente_orientacion = vertical_abajo;
caso horizontal_izquierda:
siguiente_orientacion = invalido;
caso vertical_abajo:
siguiente_orientacion = horizontal_izquierda;
caso vertical_arriba:
siguiente_orientacion = horizontal_derecha;
}
}

7. CONCLUSIONES
No puedo establecer mediciones del tiempo de respuesta en función del tiempo de ejecución, por
ser éste fuertemente dependiente de la interacción del jugador humano.

10

Вам также может понравиться