Proyecto: Buscaminas simplificado
El proyecto no introduce contenido nuevo: pone en práctica todo lo visto en la unidad.
Este es el proyecto de cierre de la unidad: un Buscaminas simplificado que se juega por consola, y que pone en práctica todo lo visto en la unidad (tipos, operadores, condicionales, bucles, funciones, entrada/salida, listas de listas y módulos).
Alcance
-
Solo consola: el juego se desarrolla únicamente para la terminal.
-
Tablero rectangular, representado como una lista de listas. Su tamaño se define con dos constantes:
ANCHO_TABLERO(número de columnas) yALTO_TABLERO(número de filas), que valen8por defecto (tablero de 8×8). Se pueden cambiar esos valores (deben ser como mínimo2) y el juego debe seguir funcionando con cualquier otro tamaño, sin tocar nada más del código. -
Número de minas calculado a partir del tamaño del tablero, para que la proporción de minas se mantenga al cambiarlo. Se debe usar esta fórmula, redondeando el resultado a un número entero (función
round()):NUM_MINAS = round(ANCHO_TABLERO * ALTO_TABLERO * 0.15)Es decir, el 15 % de las casillas del tablero. Por ejemplo:
Tablero Casillas Minas 8×8 (por defecto) 64 10 10×6 60 9 5×5 25 4 Las minas se colocan en posiciones aleatorias, sin repetir casilla.
-
Una jugada consiste en introducir la fila (entre
1yALTO_TABLERO) y la columna (entre1yANCHO_TABLERO) de una casilla. El programa revela esa casilla y muestra cuántas minas hay en las 8 casillas que la rodean (el número de minas adyacentes, entre0y8). -
El juego termina en victoria (todas las casillas sin mina han sido reveladas) o en derrota (se revela una casilla con mina). En ambos casos se muestra el tablero final con todas las minas.
Fuera del alcance
- Interfaz gráfica (GUI): es una ampliación opcional, que solo tiene sentido abordar cuando la versión de consola esté terminada (ver GUI con Tkinter).
- Banderas para marcar casillas sospechosas.
- Temporizador de la partida.
- Revelado automático de las casillas vecinas cuando una casilla tiene
0minas alrededor: cada casilla se revela de una en una.
Interfaz en consola
El tablero se muestra con estos símbolos:
| Símbolo | Significado | Color |
|---|---|---|
# | Casilla todavía sin revelar | Gris |
0 a 8 | Casilla revelada, con el número de minas adyacentes | Azul |
* | Mina (solo se muestra al terminar la partida) | Rojo |
Los colores se consiguen con códigos de escape ANSI, explicados en el apartado Colores en la terminal de Entrada/salida con formato. Los códigos que se deben usar son:
| Uso | Código |
|---|---|
| Gris | "\033[90m" |
| Azul | "\033[94m" |
| Rojo | "\033[91m" |
| Restablecer el color | "\033[0m" |
Si se aplica el ancho dentro de la propia f-string (por ejemplo f"{color}{simbolo:>3}{RESET}"), las columnas siguen alineadas, porque los códigos de color quedan fuera del ancho. Si se coloreara primero el símbolo y después se le diera el ancho, los códigos de escape contarían como caracteres y las columnas se desalinearían.
Ejemplo de una partida con los valores por defecto de las constantes (ANCHO_TABLERO = 8 y ALTO_TABLERO = 8). Con la fórmula del alcance, NUM_MINAS se calcula como round(8 * 8 * 0.15), que da como resultado 10 minas. La partida termina en derrota. Las líneas Fila: y Columna: son lo que escribe el usuario. Aquí no se pueden mostrar los colores, pero en el programa los símbolos deben aparecer coloreados como indica la tabla anterior:
| 1 2 3 4 5 6 7 8
---+------------------------
1 | # # # # # # # #
2 | # # # # # # # #
3 | # # # # # # # #
4 | # # # # # # # #
5 | # # # # # # # #
6 | # # # # # # # #
7 | # # # # # # # #
8 | # # # # # # # #
Fila: 5
Columna: 5
| 1 2 3 4 5 6 7 8
---+------------------------
1 | # # # # # # # #
2 | # # # # # # # #
3 | # # # # # # # #
4 | # # # # # # # #
5 | # # # # 2 # # #
6 | # # # # # # # #
7 | # # # # # # # #
8 | # # # # # # # #
Fila: 9
Columna: 3
Coordenadas fuera del tablero
Fila: 5
Columna: 5
Esa casilla ya está revelada
Fila: hola
Introduce un número entero
Fila: 4
Columna: 4
¡BOOM! Has pisado una mina. Fin de la partida.
| 1 2 3 4 5 6 7 8
---+------------------------
1 | # # * # # # # #
2 | # # # # # * # #
3 | # * # # # # # *
4 | # # # * # # # #
5 | # # # # 2 # * #
6 | * # # # * # # #
7 | # # * # # # # #
8 | # # # # # * # #
Requisitos técnicos
- El tablero y la posición de las minas deben representarse con listas de listas.
- El tamaño del tablero debe definirse con dos constantes (
ANCHO_TABLEROyALTO_TABLERO) y el número de minas (NUM_MINAS) debe calcularse a partir de ellas con la fórmula indicada en el alcance. Todo el código debe depender de estos valores, sin escribir8ni10directamente en otros puntos del programa. - Los colores de la terminal (gris, azul, rojo y el código para restablecerlo) deben definirse también como constantes, en lugar de repetir los códigos de escape por el programa.
- La colocación de las minas debe ser aleatoria (módulo
random). - El cálculo de minas adyacentes a una casilla debe extraerse a una función propia.
- Manejo de errores: el programa no debe terminar con un error por culpa de lo que escribe el usuario. Se debe validar la fila y la columna introducidas y, cuando el dato no sea válido, mostrar el mensaje correspondiente (con este texto exacto) y volver a pedirlo:
- Si no se introduce un número entero:
Introduce un número entero. Se vuelve a pedir ese mismo dato (la fila o la columna) hasta que sea un número entero. Se debe capturar la excepción correspondiente contry/except. - Si la casilla está fuera del tablero:
Coordenadas fuera del tablero. Se vuelve a pedir la jugada completa (fila y columna). - Si la casilla ya estaba revelada:
Esa casilla ya está revelada. Se vuelve a pedir la jugada completa (fila y columna).
- Si no se introduce un número entero:
- Al pisar una mina se muestra
¡BOOM! Has pisado una mina. Fin de la partida.y, al revelar la última casilla sin mina,¡Enhorabuena! Has despejado todas las casillas seguras. - El código de las funciones del juego debe vivir en un módulo propio (
buscaminas.py), separado delmain.pyque arranca la partida (ver bloque de Módulos).
Hitos sugeridos
No hace falta seguir este reparto al pie de la letra, pero sirve como referencia de progreso.
| Hito | Qué debe funcionar |
|---|---|
| 1. Tablero vacío | Se genera y se imprime por pantalla un tablero de ANCHO_TABLERO × ALTO_TABLERO casillas sin revelar (#, en gris), con las filas y columnas numeradas. |
| 2. Minas colocadas | Se calcula NUM_MINAS con la fórmula indicada y se colocan esas minas en posiciones aleatorias del tablero (guardadas internamente, sin mostrarlas). |
| 3. Revelar una casilla | Se introduce una fila y una columna y el programa revela esa casilla: muestra el número de minas adyacentes (en azul), o termina la partida si era una mina (en rojo). |
| 4. Condición de victoria | El juego detecta cuándo todas las casillas seguras están reveladas y declara la victoria. |
| 5. Manejo de errores y pulido | Las coordenadas no numéricas, fuera del tablero o repetidas se rechazan con los mensajes indicados en los requisitos y se vuelve a pedir el dato, sin que el programa termine con un error; el código está organizado en el módulo buscaminas.py + main.py. |
💾 Haz un commit al terminar cada hito (no esperes a tener todo el proyecto listo para hacer el primero).