TP1 - 4 en línea
Como primer trabajo práctico se solicita desarrollar una versión del juego 4 en línea para dos jugadores.
Acá unos links para probar el juego en el explorador web:
- Versión simple, sin opciones, dos jugadores
- Versión más completa, opciones para cambiar dimensiones, jugar en línea, y más.
Explicación del juego
- El juego generalmente se desarrolla en un tablero de tamaño
6x7
(siendo esto seis filas y siete columnas), pero nuestra versión admitirá cualquier tamañoNxM
. - El cuatro en línea se juega de a dos jugadores que toman turnos,
X
yO
. El tablero comienza vacío yX
puede colocar el primer símbolo, continúaO
, vuelve aX
, y así sucesivamente.- En el juego real se utilizan fichas de dos colores diferentes para
representar a los jugadores, pero para simplificar nuestra
implementación optaremos por los caracteres
X
yO
.
- En el juego real se utilizan fichas de dos colores diferentes para
representar a los jugadores, pero para simplificar nuestra
implementación optaremos por los caracteres
- El jugador del turno actual puede colocar su símbolo en una columna
determinada, donde este símbolo caerá hacia la posición más baja y vacía,
quedando en su posición final.
- Si una columna se encuentra llena (es decir que todos sus casilleros se encuentran ocupados por símbolos), no se pueden colocar más símbolos en dicha columna.
- El juego termina cuando se cumpla una de estas condiciones:
- Hay un 4 en línea en alguna parte del tablero. Es decir, hay cuatro símbolos iguales que forman una línea horizontal, vertical, o diagonal en alguna parte del tablero. El jugador de dicho símbolo es el ganador de la partida.
- Todos los casilleros se llenaron, llegando a un empate.
Una posible representación de un juego 6x7
que pasó por la siguiente
secuencia:
- Empieza con
X
insertando un símbolo en la cuarta columna - Luego
O
inserta un símbolo en la tercer columna - Sigue con
X
insertando otro símbolo en la tercer columna
...tendría este estilo:
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | | | | | | |
| | |X| | | | |
| | |O|X| | | |
Supongamos que el juego sigue, y eventualmente X
gana por un cuatro en línea
en diagonal, podría tener este estilo:
| | | | | | | |
| | | | | | | |
| | |X|O| | | |
| | |O|X| | | |
| | |X|O|X| | |
| |O|O|X|X|X|O|
Objetivo del trabajo práctico
Se busca realizar una implementación del 4 en línea que se pueda jugar de a dos
jugadores humanos, desde la terminal, permitiendo tableros de cualquier
dimensión NxM
, con N
y M
mayores o iguales a cuatro y menores a diez.
Material
Primera parte: Lógica del juego
La primera parte del trabajo práctico consiste en implementar la lógica del
juego. Para ello se deberán implementar las funciones que están definidas dentro
del archivo cuatro_en_linea.py
de modo de cumplir con el contrato que
especifica su documentación.
Las diferentes funciones nos permitirán llevar las responsabilidades del juego hacia código. Cada una responde a una acción o pregunta:
- Acción - empezar un nuevo juego:
crear_tablero
- Acción - colocar el próximo símbolo en una columna:
insertar_simbolo
- Pregunta - ¿de quién es el turno?:
es_turno_de_x
- Pregunta - ¿tenemos un ganador?:
obtener_ganador
- Pregunta - ¿el tablero está completo?:
tablero_completo
Con esto podemos manejar toda la lógica del juego. El código relacionado al
programa (que suele incluir interacción con el usuario mediante las
funciones print
e input
) deberá realizarse para la segunda parte del
trabajo práctico.
Las funciones definidas en el cuatro_en_linea.py
serán útiles para:
- Manejar el programa de la segunda parte del trabajo práctico
- Reutilizarlas y facilitar la lógica de otras funciones dentro del mismo
archivo
cuatro_en_linea.py
- Verificar el funcionamiento del módulo en su totalidad, mediante el archivo
cuatro_en_linea_test.py
Se admite crear otras funciones auxiliares en el archivo cuatro_en_linea.py
si
se considera necesario, pero no se permite eliminar las funciones definidas en
el archivo base, ni tampoco cambiar sus parámetros o tipo de retorno.
Adicionalmente, tampoco se permite el uso de variables globales (pero sí el de constantes).
El detalle específico sobre qué debe hacer cada función está indicado en su respectiva documentación. Dentro del archivo existen varias definiciones como la siguiente:
def crear_tablero(n_filas: int, n_columnas: int) -> List[List[str]]:
"""Crea un nuevo tablero de cuatro en línea, con dimensiones
n_filas por n_columnas.
Para todo el módulo `cuatro_en_linea`, las cadenas reconocidas para los
valores de la lista de listas son las siguientes:
- Celda vacía: ' '
- Celda con símbolo X: 'X'
- Celda con símbolo O: 'O'
PRECONDICIONES:
- n_filas y n_columnas son enteros positivos mayores a tres.
POSTCONDICIONES:
- la función devuelve un nuevo tablero lleno de casilleros vacíos
que se puede utilizar para llamar al resto de las funciones del
módulo.
EJEMPLO:
>>> crear_tablero(4, 5)
[
[' ', ' ', ' ', ' ', ' '],
[' ', ' ', ' ', ' ', ' '],
[' ', ' ', ' ', ' ', ' '],
[' ', ' ', ' ', ' ', ' ']
]
"""
La estructura del tablero
La primera función a implementar será crear_tablero
, y habrás notado
que se espera un valor del tipo de dato ya definido: una lista de listas de
cadenas. No se puede cambiar el tipo de dato del tablero, debe ser
explícitamente una lista de listas de cadenas donde cada cadena solo puede tomar
los valores ' '
, 'X'
, o 'O'
.
Un ejemplo de estado posible para un tablero válido sería el siguiente:
[
[' ', ' ', ' ', ' ', ' '],
[' ', ' ', ' ', 'O', ' '],
[' ', ' ', 'X', 'X', ' '],
['X', 'O', 'O', 'X', ' ']
]
Dicha estructura nos servirá para llevar adelante toda una partida de cuatro en línea. El resto de las funciones del módulo reciben un tablero que esperan esta estructura.
Pruebas
Para saber si su implementación está funcionando correctamente deberán ejecutar
el archivo cuatro_en_linea_test.py
, que correrá un conjunto de pruebas automáticas y
les indicará si su implementación está funcionando correctamente.
Para utilizarlo, copiá el archivo cuatro_en_linea_test.py
en la misma carpeta que
cuatro_en_linea.py
, y ejecutá:
python3 cuatro_en_linea_test.py
Nota: Las pruebas automáticas están para simplificar el desarrollo y ofrecerles un feedback rápido sobre si su código está funcionando o no. Es necesario para la entrega que las pruebas pasen, pero esto no implica que el trabajo esté aprobado. Las pruebas no contemplan todos los casos posibles.
Cada prueba es una función dentro del archivo cuatro_en_linea_test.py
. Si
alguna prueba falla, te recomendamos que leas el código de la prueba para ver
cuál es el caso que falla y cómo solucionar el problema.
Sobre la condición de victoria
La función más complicada de la Parte 1 es obtener_ganador
, que verifica si
hay un 4 en línea en horizontal, vertical, o diagonal. En esta subsección se
incluye una ayuda para encarar dicha función, pero recomendamos primero que lo
intentes hacer por tu cuenta, y si no te sale recurras al texto incluido acá.
Ayuda para condición de victoria.
Segunda parte: Interfaz de usuario
Finalizada la lógica de juego, deberán implementar una interfaz de usuario que
permita jugar al 4 en línea en un nuevo archivo main.py
. El programa debe
pedirle al usuario las dimensiones N
y M
para hacer el tamaño del tablero
NxM
(con N
y M
entre 4 y 10) para luego comenzar el juego.
El programa finaliza cuando haya un ganador o todas las columnas se encuentren
llenas.
Los requerimientos para la interfaz son:
- Debe mostrarse el tablero en un formato agradable para el usuario.
- Debe incluirse una ayuda visual para identificar las coordenadas de la celda, a los bordes del tablero.
- Con "un formato agradable" sería evitando el uso de un simple
print(grilla)
o algún uso deprint
que resulte en la visualización de corchetes o comas resultantes por imprimir una lista de Python.
- Una vez creado el tablero, se le debe indicar al usuario de quién es el turno y en qué columna quiere colocar la próxima ficha.
- En cualquier momento a lo largo de la ejecución el programa no debe explotar. El código también debe realizar todas las validaciones correspondientes para que las entradas del usuario no finalicen el programa con un error.
- Debe incluirse una tecla para finalizar el juego actual.
A continuación les dejamos un ejemplo de una interfaz de usuario para que tengan como referencia. No es necesario que sea idéntica, tómenla como una guía.
Recomendaciones
- Investigar el uso de las funciones
str.ljust
ystr.rjust
para mostrar un tablero alineado. No es necesario su uso, pero tenerlas en cuenta. - Recordar que
cuatro_en_linea
es un módulo y debe importarse/usarse enmain.py
como tal:
import cuatro_en_linea
def main():
tablero = cuatro_en_linea.crear_tablero(...)
main()
Restricciones y condiciones de entrega
- La entrega debe pasar todas las pruebas para ser considerada como tal.
- No se permite el uso de ninguna biblioteca externa.
- El código debe estar correctamente modularizado y seguir las convenciones y buenas prácticas establecidas por el lenguaje y el curso.
- El uso de módulos de la biblioteca estándar de Python deberá ser previamente autorizado por un docente.
- No se permite el uso de
funcion(*argumentos)
. - No se permite el uso de variables globales (sí el de constantes!).
- No se permite el uso de
eval
.
Entrega
La corrección de los trabajos a partir del TP1 serán por la plataforma GitHub. Para esto será necesario crearse una cuenta de GitHub e indicarnos el usuario antes de realizar la entrega al sistema.
En total, la secuencia completa de entrega y corrección tiene los siguientes pasos:
- Llená el siguiente formulario para indicarnos la cuenta de GitHub. Si no tenés cuenta, te podés crear una en https://github.com/ usando el mail que quieras.
- Subí los archivos
cuatro_en_linea.py
ymain.py
en nuestra página de entregas. - Una vez realizada la entrega te debería llegar un mail de una invitación a un repositorio de GitHub con tu entrega. Será necesario aceptar la invitación pues la misma vence a los 7 días una vez realizada.
- Tu ayudante hará la corrección en este repositorio de GitHub y te lo indicará al estar disponible.