Saltar al contenido principal

Proyecto: Buscaminas simplificado

Contenidos

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) y ALTO_TABLERO (número de filas), que valen 8 por defecto (tablero de 8×8). Se pueden cambiar esos valores (deben ser como mínimo 2) 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:

    TableroCasillasMinas
    8×8 (por defecto)6410
    10×6609
    5×5254

    Las minas se colocan en posiciones aleatorias, sin repetir casilla.

  • Una jugada consiste en introducir la fila (entre 1 y ALTO_TABLERO) y la columna (entre 1 y ANCHO_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, entre 0 y 8).

  • 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 0 minas alrededor: cada casilla se revela de una en una.

Interfaz en consola

El tablero se muestra con estos símbolos:

SímboloSignificadoColor
#Casilla todavía sin revelarGris
0 a 8Casilla revelada, con el número de minas adyacentesAzul
*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:

UsoCódigo
Gris"\033[90m"
Azul"\033[94m"
Rojo"\033[91m"
Restablecer el color"\033[0m"
Colores y alineación

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_TABLERO y ALTO_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 escribir 8 ni 10 directamente 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 con try/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).
  • 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 del main.py que 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.

HitoQué debe funcionar
1. Tablero vacíoSe 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 colocadasSe 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 casillaSe 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 victoriaEl juego detecta cuándo todas las casillas seguras están reveladas y declara la victoria.
5. Manejo de errores y pulidoLas 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).