Después de resolver la tarea 2, usted será capaz de:
En esta oportunidad, junto a su equipo de trabajo deberán desarrollar e implementar el clásico juego del combate naval. Para ello deberán utilizar el módulo de python para videojuegos llamado pygame. Descargue el módulo.
Combate naval es un juego para 2, cuyo objetivo consiste en destruir la flota de barcos de sus enemigos antes que él destruya todos los tuyos. Antes de que comience el juego deberás ser capaz de posicionar 5 barcos de distinto tamaño, en una grilla que será tu zona de juego y que permanecerá oculta para tu enemigo (él no sabe el lugar exacto donde escondiste tus barcos). Una vez que haz posicionado todos tus barcos, el juego se desarrollará por turnos en donde debes disparar a 3 casillas de la zona de juego de tu oponente, con la finalidad de encontrar sus barcos escondidos. Si aciertas a una posición en donde hay un barco enemigo, la zona de juego rival deberá mostrar que lograste disparar en uno de sus barcos. El juego se repite mientras no se hayan hundido todos los barcos de alguno de los jugadores.
Para efectos de esta tarea y como parte del desarrollo del juego, se pondrán a disposición de los estudiantes un conjunto de archivos descargarlos de este enlace estos corresponden a la base del juego ustedes deben implementar el resto. A continuación se presentan las características del videojuego que deberán implementar:
Nota
No es necesario estudiar el módulo pygame, usted sólo debe crear las funciones con los conocimientos que ya posee de python (if, for, while, funciones)y de las estructuras de datos que ha visto en clases, además puede documentarse leyendo el material en línea de listas, tuplas, conjuntos y diccionarios.
La mayor parte del juego se encuentra implementado en el archivo main.py, desde donde se llamarán las funciones del módulo de funciones.py, que es el archivo donde se deben implementar las funciones que ustedes deben programar. Una versión simplificada de como main.py llama a las funciones que usted implementará en funciones.py se muestra en el siguiente diagrama de flujo:
Para el desarrollo de la tarea se disponen de las siguientes estructuras de datos:
Los barcos tienen asociados dos diccionarios los que se encuentran descritos a continuación:
IMAGENES_BARCOS = {
"A": "barco_A.png",
"B": "barco_B.png",
"C": "barco_C.png",
"D": "barco_D.png",
"E": "barco_E.png"
}
IMAGENES_BARCOS corresponde a un diccionario con la información de la imagen asociada a cada barco. Para ello contiene una llave de tipo string que representa el tipo de barco y un string asociado al nombre de la imagen de cada barco.
INFO_BARCOS = {
"A": [[1,1],[1,1]],
"B": [[1,2],[1,2]],
"C": [[1,3],[1,3]],
"D": [[1,4],[1,4]],
"E": [[1,5],[1,5]],
}
INFO_BARCOS corresponde a un diccionario que mantiene la información asociada a cada uno de los barcos, según tipo de barco, tanto para el jugador como para el enemigo. La llave corresponde a un string para representar el tipo de barco y cada elemento presente en el diccionario es una lista con 2 elementos, de tipo lista también. El primer elemento de la lista es la información de tus barcos, que es una lista con dos valores, el primero representa el estado del barco (0: barco inactivo, 1: barco activo) y el segundo la dimensión del barco. El segundo elemento posee la misma estructura y corresponde a la información de los barcos enemigos. Este diccionario se encuentra definido en el archivo configuracion.py y te permitirá manipular los diversos acontecimientos que estén asociados a eventos sobre los barcos, durante todo el desarrollo de juego.
Otro elemento importante presente en el juego es la estructura de datos utilizada para representar los disparos. Para ello se utiliza una lista con 2 valores, el primero corresponde a la información del barco al cuál se está disparando y el segundo una tupla con la información de la coordenada donde fue realizado el disparo.
disparos = [tipo_barco, (posicionx, posiciony)]
Además, en el archivo configuracion.py encontrás información importante a la hora de realizar tu tarea. Acá se encuentran todas las variables definidas y que forman parte del desarrollo del juego. Es importante que entiendas su funcionamiento.
Para representar el tablero deberán considerar dos grillas que se implementarán mediante el uso de listas. Estas grillas contienen la información general del tablero de ambos jugadores. Además, para simplificar el desarrollo, se consideran también el uso de dos listas auxiliares para mantener la información de los disparos.
Es importante señalar que pygame trabaja con la pantalla convirtiéndola en un plano cartesiano. La coordenada (0,0) se encuentra en el extremo superior izquierdo. Por lo mismo, deben ser capaces de convertir una coordenada en el plano cartesiano de la pantalla en una coordenada válida para los tableros de juego. Revisar el archivo configuraciones.py que les permitirá entender de mejor manera su funcionamiento.
Las coordenadas dentro de mapa, están definidas como una tupla (x, y), con la posición específica del punto, y un radio, el cual define los límites que cubre la elemento descrito por las coordenadas.
Para el desarrollo de esta tarea, junto a su equipo deberán implementar las funciones que se encuentran declaradas en el archivo funciones.py. La descripción de las funciones, junto sus valores de retorno son las que se encuentra a continuación. Es importante señalar que los nombres y valores de retorno de las funciones deben ser iguales a los que se detallan en el archivo funciones.py
completar_tablero (cursor, tablero, barco_actual, sentido): Retorna la posición de la fila y la columna que fue presionada en la grilla
Para posicionar un barco sobre la grilla, el usuario deberá hacer click sobre ésta en alguna posición del tablero. Los barcos se irán posicionando uno a uno conforme a su tamaño, comenzando con el barco de menor dimensión. Se deberá validar que el usuario haga click sobre una posición válida en el tablero y que el barco se pueda posicionar efectivamente sobre la grilla. Es importante señalar que al hacer click sobre el tablero, la coordenada presionada corresponde a la cabeza del barco. Además, el usuario puede elegir el sentido en el cual posicionar su barco presionando la barra espaciadora, quedando este, de Norte a Sur (cabeza en coordenada Norte) o de Oeste-Este (cabeza en coordenada Oeste)
Parámetros:
- cursor: Tupla con la información de la posición clickeada en el tablero junto al valor del radio del cursor. ((posicionX,posicionY),radio)
- tablero: Lista con la información del tablero de juego
- barco_actual: valor que representa al barco actual a posicionar
- sentido: string que representa el sentido de posición
actualizar_info_posicion (fila, columna, barco_actual): Retorna un valor booleano que representa si se pudo o no actualizar la información del diccionario asociado a barco_actual.
Esta función permite actualizar la información del diccionario de INFO_BARCOS para que, una vez posicionado el barco en el tablero, la pantalla deje de mostrar la imagen asociada a aquel barco.
Parámetros:
- fila: coordenada X del click
- columna: cordenada Y del click
- barco_actual: valor que representa al barco actual
posicionar_barcos_enemigos(tablero_enemigo): Esta función no tiene valor de retorno
Esta función permite posicionar los barcos enemigos en tablero_enemigo. La forma en la cual se generan las posiciones de los barcos enemigos deben ser de una manera aleatoria. No es necesario usar ninguna método en específico, solamente se debe garantizar que entre distintas ejecuciones del programa, los barcos enemigos queden posicionados de manera distinta en la grilla.
Parámetros:
- tablero_enemigo:* lista que representa la información del tablero enemigo
procesar_disparo(cursor, tablero_barcos, tablero_disparos, DX, DY): Esta función retorna una lista asociada al disparo efectuado, tal como se describió más arriba.
Esta función se encarga de actualizar el tablero de disparos efectuados sobre la grilla enemiga. El disparo efectuado sobre el tablero queda determinado por la coordenada X e Y donde se hizo click en el tablero. La función debe ser capaz de validar si efectivamente el disparo es un disparo válido.
Parámetros:
- cursor: Tupla con la información de la posición clickeada en el tablero
- tablero_barcos: Lista que almacena la ubicación de todos los barcos enemigos.
- tablero_disparos: Lista auxiliar que permite mantener actualizada la información de los disparos. Esta lista permite graficar los disparos efectuados.
- DX y DY: Estos valores están definidos en configuraciones.py y permiten convertir la coordenada de la pantalla en una coordenada del tablero de juego, dado que éste se encuentra desplazado respecto al origen (tal como se mostró al principio)
disparo_enemigo(tablero_barcos, tablero_disparos): Esta función retorna una lista asociada al disparo efectuado, tal como se describió más arriba.
Al igual que la función procesar_disparo, esta función cumple la misma finalidad pero actualizando la información de los disparos efectuados por la computadora sobre tu tablero. La forma en la cual se efectua el disparo openente debe ser totalmente aleatoria. No existe un método especial, pero se debe garantizar que los disparos se realicen de manera distinta entre cada ejecución del programa. De igual manera se deben validar que corresponda a un disparo válido (que no esté fuera de los límites del tablero, o que no dispare sobre un valor previamente disparado)
Parámetros:
- tablero_barcos:* Lista que almacena la ubicación de todos tus barcos.
- tablero_disparos:* Lista auxiliar que permite mantener actualizada la información de los disparos. Esta lista permite graficar los disparos efectuados sobre tu tablero.
actualizar_tablero(info_disparos, disparos, jugada): Esta función devuelve 1 si es que en un disparo se pierde un barco o 0 si no se pierde ninguno
Esta función debe ser capaz de procesar la información de los distintos disparos efectuados por cada uno de los jugadores de modo que sea posible procesar los disparos y graficarlos posteriormente. Es importante revisar la función dibujar_tablero que se encuentra en el archivo utilidades.py para que comprendan de que forma se dibujan los disparos y que sean capaces de escribir de manera correcta la función actualizar_disparos, para que sea posible dibujar efectivamente los disparos. Además, esta función debe ser capaz de actualizar la información contenida en el diccionario de INFO_BARCOS para poder tener un registro de los barcos que faltan y obtener de esa forma el ganador del juego. Al momento de procesar los disparos, el correcto llenado de la grilla permite que los disparos que aún no han sido procesados se vean de color amarillo, los disparos que dan a alguna parte de un barco de color rojo y los disparos que van al agua de color verde. De no ocurrir esto quiere decir que la información no se lleno como corresponde.
Parámetros:
- info_tablero: Lista que representa el tablero y que permite mantener actualizada la información de los disparos.
- disparos: Lista con la información de los disparos efectuados durante cada ronda, con el formato presentado anteriormente.
- jugada: Variable lógica que nos permite saber quién está jugando.
Es importante señalar que para escribir las funciones de manera correcta deben revisar el programa en su totalidad para comprender la forma en la cual se implementan las distintas funciones. Cuando el desarrollo es el correcto, el programa puede mostrar los distintos estados sin ningún tipo de problema.
La fecha de entrega es el Viernes 05 de Junio a las 23:00.
La tarea debe ser resuelta en equipos de dos o tres personas.
Sólo uno de los integrantes del equipo debe subir la tarea en la sección Tareas de la plataforma Aula, en el ramo de Programación IWI131.
Se debe entregar un archivo comprimido (.zip) que debe contener todos los archivos para hacer funcionar la tarea con el nombre tarea-2-RUT.zip, reemplazando RUT con el RUT del integrante que subirá la tarea. Sólo debe ir la parte del RUT hasta antes de la raya. Por ejemplo: tarea-2-18000123.zip.
Al principio del archivo funciones.py se debe poner un comentario indicando los RUT de los integrantes del equipo como en el siguiente ejemplo:
# Integrantes:
# 18000123-0 Perico Los Palotes
# 18000456-7 Fulanita de Tal
# 18000890-k Federico Santa Maria
No se puede subir ningún archivo adicional.
Evite dejar para última hora la entrega de la tarea. Cerca del plazo final, la plataforma seguramente estará sobrecargada.
Las tareas atrasadas (máximo un día de retraso) tendrán el descuento especificado en la rúbrica de corrección. NO se recibirán tareas por por correo electrónico.
Los equipos de trabajo pueden ser los mismos de la tarea anterior, pero recuerde que deben ser de 2 ó 3 personas.
Usted puede discutir la tarea con compañeros de otros grupos, pero bajo ningún motivo puede compartir o copiar el código de su tarea. Cada equipo debe escribir su propio código.
Las políticas de copia de la asignatura rigen para la tarea.
En caso de tener problemas con el desarrollo de la tarea, asista a las ayudantías o consulte en el grupo de facebook.