Pseudocódigo con PSeInt

Vamos a mostraros como programar un algoritmo en pseudocódigo para implementar el juego del buscaminas, el juego típico de Windows al que todos hemos pasado alguna hora jugando.

Una herramienta como PSeInt es interesante porque nos permite actualmente escribir y codificar el pseudocódigo de nuestra aplicación para probarla, interpretarla y ver cómo funciona.

Partes más importantes de nuestro algoritmo

Las partes más importantes del algoritmo son:

Calcular máximo y mínimo

Dos funciones, máximo y >mínimo, que son dos funciones auxiliares para calcular el máximo y el mínimo de dos números.


//################################################################################
//Función max: Función auxiliar que calcula el máximo de dos números
//################################################################################

Funcion num<- max(num1,num2)
	Definir num como Entero;
	Si num1>num2 Entonces
		num<-num1;
	SiNo
		num<-num2;	
	FinSi
FinFuncion

//################################################################################
//Función min: Función auxiliar que calcula el mínimo de dos números
//################################################################################

Funcion num<- min(num1,num2)
	Definir num como Entero;
	Si num1<num2 Entonces
		num<-num1;
	SiNo
		num<-num2;	
	FinSi
FinFuncion

Creamos el tablero de juego

Además, vamos a utilizar un tablero de 10x10, en el que colocaremos las minas, que será un array bidimensional de enteros, al que llamaremos tablero.


	//################################################################################
//Función IncializarTablero: Función que recibe las dos talbas: tablero, visible
//Incializa tablero con valores 0
//Incializa visible con valores Falso, indicando que están ocultas
//################################################################################

Funcion InicializarTablero(tablero Por Referencia,visible Por Referencia)
	Definir fila,colum como Entero;
	//Incializo el tablero con valor 0
	Para fila<-0 hasta 9 Hacer
		Para colum<-0 hasta 9 Hacer
			tablero[fila,colum]<-0;
		FinPara
	FinPara
	PonerMinas(tablero);
	//Incializo la tabla visible a falso indicando que ninguna celda está descubierta
	Para fila<-0 hasta 9 Hacer
		Para colum<-0 hasta 9 Hacer
			visible[fila,colum]<-Falso;
		FinPara
	FinPara
	
FinFuncion

También utilizaremos otro array de 10x10 de valores lógicos, llamado visible, en el que inicialmente todos los valores serán falsos, y después cambiarán a verdaderos las casillas que se van descubriendo. Así a la hora de dibujar el tablero, sepa que casillas se deben visualizar y cuales dejar ocultas.


//################################################################################
//Función IncializarTablero: Función que recibe las dos talbas: tablero, visible
//Incializa tablero con valores 0
//Incializa visible con valores Falso, indicando que están ocultas
//################################################################################

Funcion InicializarTablero(tablero Por Referencia,visible Por Referencia)
	Definir fila,colum como Entero;
	//Incializo el tablero con valor 0
	Para fila<-0 hasta 9 Hacer
		Para colum<-0 hasta 9 Hacer
			tablero[fila,colum]<-0;
		FinPara
	FinPara
	PonerMinas(tablero);
	//Incializo la tabla visible a falso indicando que ninguna celda está descubierta
	Para fila<-0 hasta 9 Hacer
		Para colum<-0 hasta 9 Hacer
			visible[fila,colum]<-Falso;
		FinPara
	FinPara
	
FinFuncion

Otras funciones del algoritmo

Funcion PonerMinas

Una vez se inicializa el tablero, utilizamos la función PonerMinas, que lo que hace es colocar 10 minas en el tablero. Las minas las representamos con el número 9, y se usa este número ya que en el resto de casillas se indicará el número de minas que hay alrededor de la misma, por lo que como máximo puede haber 8 minas rodeándola.

Además hemos de asegurarnos que la posición que se ha generado aleatoriamente no se haya repetido, es decir, no se coloquen dos minas en el mismo sitio, si no que se generen 10 minas en cada partida.

Cada vez que se coloca una mina, se calculan (es el paso más importante de este pseudocódigo) las casillas vecinas a la casilla dónde se ha colocado la mina, para incrementar en 1 el número de minas que tiene cerca. Lo hacemos de esta forma, usando máximos y mínimos, para calcular el número de casillas adyacentes a cada punto, para no indicar un índice que esté fuera del tablero en caso que la mina esté colocada en un extremo o vértice del tablero, ya que en ese caso tendría menos casillas adyacentes.

Cuando se acabe de colocar todas las minas tendremos, además, casillas con números, indicando las minas que están en casillas adyacentes, y posibles casillas con ceros, indicando que alrededor no tienen ninguna mina.

//################################################################################
//Función PonerMinas: Función que recibe el tablero (tabla 10x10) por referencia
//Genera 10 posiciones de la tabla e incializa esas posiciones con minas (valor 9)
//Debe asegurar que se ponen 10 minas.
//Cada vez que se pone una mina se incrementa en 1 el valor de las celdas vecinas,
//si no son una mina
//################################################################################

Funcion PonerMinas(tablero Por Referencia)
	Definir num_minas,fila,colum,fila2,colum2 como Entero;
	num_minas<-0;
	//Vamos a poner 10 minas en el tablero
	Mientras num_minas<10 Hacer
		//Me aseguro que no haya ya una mina en la posición que se genera aleatoriamente
		Repetir
			fila<-azar(10);
			colum<-azar(10);
		Hasta Que tablero[fila,colum]<>9;
		//Reperesentamos la mina con el número 9
		tablero[fila,colum]<-9;
		//Ahora incremento el número de minas cercanas en las casillas vecinas
		Para fila2 <- max(0,fila-1) hasta min(9, fila+1) hacer
			Para colum2 <- max(0,colum-1) hasta min(9, colum+1) hacer
				Si tablero[fila2, colum2]<>9 entonces
					tablero[fila2,colum2]<-tablero[fila2,colum2]+1;
				FinSi
			FinPara
		FinPara
		num_minas<-num_minas+1;
	FinMientras
FinFuncion

Función DestaparCelda

Usaremos otra función llamada DestaparCelda, que utiliza la referencia del tablero visible y la fila y columna que queremos destapar. Si es una casilla que podemos destapar, que están en falso, esa casilla se cambiará a verdadero y colocará como visible.

Si no hay minas cerca, se van a destapar las casillas que estén adyacentes, lo que se hace con un algoritmo recursivo, para que cuando al pulsar una casilla que no tiene minas alrededor, intente destapar las vecinas que no tienen minas cerca.


	/################################################################################
//Función DestaparCelda: Funcion que recibe por referencia las dos tablas y la
//fila y columna que se debe destapar.
//Si es una casilla que se puede destapar (la posición de la tabla visible es Falso)
//     Se destapa (posición de la tabla visible a Verdadero)
//     Si no hay minas cerca tengo que intentar destapar las vecinas
//            Si la celda vecina no es una mina, la destapo
//Función recursiva
//################################################################################

Funcion DestaparCelda(tablero Por Referencia,visible Por Referencia,fila,colum)
	Definir fila2,colum2 como Entero;
	//Si es una casilla que se puede destapar
	Si visible[fila,colum]=Falso Entonces
		visible[fila,colum]<- Verdadero;
		//Si no hay minas cerca tengo que intentar destapar las vecinas
		Si tablero[fila,colum]=0 Entonces
			Para fila2 <- max(0,fila-1) hasta min(9, fila+1) hacer
				Para colum2 <- max(0,colum-1) hasta min(9, colum+1) hacer
					Si tablero[fila2, colum2]<>9 entonces
						DestaparCelda(tablero,visible,fila2,colum2);
					FinSi
				FinPara
			FinPara
		FinSi
	FinSI
FinFuncion

Función ContarCeldasDestapadas

Otra función empleada es ContarCeldasDestapadas, que se emplea para saber el número de celdas destapadas. Si se alcanzan el valor 90, se habrá ganado, ya que si hay 100 casillas y 10 de ellas tienen minas, 90 será el valor máximo.


//################################################################################
//Función ContarCeldasDestapadas: Funcion que recibe la tabla visible
//Recorre la tabla y cuenta los valores Verdaderos, este valor se devuelve
//Si el contador es 90 significa que hemos destapado todas las casillas: hemos ganado
//################################################################################

Funcion num <- ContarCeldasDestapadas(visible)
	Definir num,fila,colum como Entero;
	num<-0;
	Para fila<-0 hasta 9 Hacer
		Para colum<-0 hasta 9 Hacer
			Si visible[fila,colum] Entonces
				num<-num+1;
			FinSi
		FinPara
	FinPara
FinFuncion

Función ComprobarTablero

La función ComprobarTablero se emplea para comprobar si al levantar una casilla hay una mina, en cuyo caso devolvería el valor -1 y habríamos perdido, o si no destapará la celda y devolverá el número de celdas que se han destapado hasta entonces.

//################################################################################
//Función ComprobarTablero: Funcion que recibe por referencia las dos tablas y la
//fila y columna que se debe destapar.
//Si la posición a destapar es una mina (=9) devuelve -1 (hemos perdido)
//SiNo destapo la casilla correspondiente y cuento las casillas detapadas y se devuelve
//################################################################################

Funcion resultado<-ComprobarTablero(tablero Por Referencia,visible por referencia,fila,colum)
	Definir resultado como Entero;
	//Si es una mina devuelvo -1
	Si tablero[fila,colum]=9 Entonces
		//Destapo la celda con la mina
		visible[fila,colum]<-Verdadero;
		resultado<- -1;
	SiNo
		DestaparCelda(tablero,visible,fila,colum);
		resultado<-ContarCeldasDestapadas(visible);
	FinSi
FinFuncion

Función EscribirTablero

EscribirTablero dibuja el tablero, colocando el símbolo * en las casillas con minas, el símbolo # en las casillas que no son visibles y un número en las casillas que ya hemos destapado.

//################################################################################
//Función EscribirTablero: Funcion que las dos tablas 
//Recorre las tablas y las muestras en pantalla
//Dependiendo del valor de cada posición de la tabla visible, muestra la posición
//de la tabla resultado.
//Si la posición está destapada (verdadero):
//      Si no tiene minas alrededor (valor 0) muestra un hueco
//      Si es una mina, muestro un *
//      SiNo muetro el valor de la casilla (indica cuantas minas tiene alrededor)
//SiNo la posición no es visible y muestro un #
//################################################################################

Funcion EscribirTablero(tablero,visible)
	Definir fila,colum como Entero;
	Definir titfilas,titcolum como Caracter;
	titfilas<-"0123456789";
	titcolum<-"    0 1 2 3 4 5 6 7 8 9";
	
	Escribir titcolum;
	Escribir "";
	//Recorro las tablas
	Para fila<-0 hasta 9 Hacer
		Escribir sin saltar subcadena(titfilas,fila,fila),"   ";
		Para colum<-0 hasta 9 Hacer
			//Si la celda es visible (está destapada)
			Si visible[fila,colum] Entonces
				//Celda que no tiene minas alrededor
				Si tablero[fila,colum]=0 Entonces
					Escribir sin saltar "  ";
				Sino
					//Es una mina
					Si tablero[fila,colum]=9 Entonces
						Escribir sin saltar "* ";
					//Muestro el número de minas que hay en los vecinos	
					SiNo
						Escribir Sin Saltar tablero[fila,colum]," ";
					FinSI
				FinSI
			//La casilla no es visible
			SiNo
				Escribir sin Saltar "# ";
			FinSI
		FinPara
		Escribir "";
	FinPara
FinFuncion

Programa principal

El programa principal es un bucle que va escribiendo el tablero. Va solicitando fila y columna hasta que el resultado de ComprobarTablero sea -1, es decir, hemos encontrado una mina, o bien sea 90, es decir, hemos abierto 90 casillas, y por lo tanto hemos ganado, mostrando el texto “Has pisado una mina!!!!! GAME OVER”, o “YOU ARE THE PLAYER ONE!!!”, según un caso u otro.

//################################################################################
//Programa BuscaMina
//Incilizo las tablas: tablero y visible
//Se repite:
//     Mostrar el tablero
//     Pedir fila y columna de casilla a destapar
//	   Comprobar tablero
//Hasta que la comprobación = -1 (has perdido hay una mina)
//O hasta que haya destapada todas las casillas (Has ganado)
//################################################################################


Proceso Buscaminas
	Definir tablero,fila,colum,resultado como Entero;
	Dimension tablero[10,10];
	Definir visible como Logico;
	Dimension visible[10,10];
	InicializarTablero(tablero,visible);
	Repetir
		EscribirTablero(tablero,visible);
		//Pedir fila y columna de casilla a destapar
		Repetir
			Escribir Sin Saltar "Indica fila:";
			Leer fila;
		Hasta que fila>=0 y fila<=9;
		Repetir
			Escribir Sin Saltar "Indica columna:";
			Leer colum;
		Hasta que colum>=0 y colum<=9;
		//Comprobamos el tablero
		resultado<-ComprobarTablero(tablero,visible,fila,colum);
		Borrar Pantalla;
	Hasta Que resultado=-1 O resultado=90;
	EscribirTablero(tablero,visible);
	//Has destapado una mina
	Si resultado=-1 Entonces
		Escribir "Has pisado una mina!!!!!";
		Escribir "GAME OVER";
	//has destapado todas las casillas
	SiNo
		Escribir "YOU ARE THE PLAYER ONE!!!";
	FinSi
	
FinProceso

Ejecución del programa

Y ya puedes pasamr a comprobar que todo funciona correctamente, realizando una partida de prueba.

Si quieres el código , aquí tienes el juego buscaminas completo.