Buscaminas --- Lenguaje C

Tabla de contenido

Prefacio:

1. Conoce el buscaminas

1.1 Concepto de juego

1.2 Pensamientos rotos

2. Implementación de la interfaz del Buscaminas

2.1 Impresión del menú

2.2 Crear constantes de identificador e inicializar matrices

2.3 Imprimir el tablero de ajedrez

2.4 Minas aleatorias

2.5 Solución de problemas

3. Código fuente

3.1 archivo de encabezado y declaración de prototipo de función game.h

3.2 Implementación de la función de juego game.c 

3.3 Archivo de código de prueba test.c 


❤ Blogger CSDN: Ah Su quiere aprender

  ▶Clasificación de columnas: lenguaje C

  El aprendizaje del lenguaje C es sentar una base sólida para que aprendamos otros lenguajes en el futuro, ¡y C produce todo!

  ¡Comencemos nuestro viaje del lenguaje C!


Prefacio:

  Siguiendo con el mini juego de backgammon, seguimos implementando un juego de buscaminas . ¡Incluso si hay muchas tareas sin terminar en la escuela, no puede evitar que los blogueros resuman y escriban blogs!

1. Conoce el buscaminas

  El juego del buscaminas es simplemente en un tablero de ajedrez. El jugador elige una pequeña cuadrícula desconocida. Si la cuadrícula es una mina, el buscaminas falla y el juego termina. El número de truenos .

  A medida que vayamos despejando minas, y finalmente seleccionemos todas las cuadrículas del tablero que no sean minas, se gana la partida .

1.1 Concepto de juego

  ¿Qué tiene que lograr este juego? Primero echemos un vistazo a cómo se ve el juego del buscaminas en Internet, a fin de determinar los elementos necesarios para su implementación .

  (Almacenamiento e inicialización) Para tener este tablero de ajedrez de 9*9, podemos usar una matriz bidimensional de 9 filas y 9 columnas, y luego hacer una función de interfaz de inicialización para esta matriz . (Minas enterradas) Después de la inicialización, decidimos qué símbolo usar para representar las minas (por ejemplo, podemos usar el número 1 para indicar las minas), y luego organizamos aleatoriamente las posiciones de almacenamiento de las minas en el tablero de ajedrez, es decir, cambiamos el correspondiente elementos en la matriz para representar el símbolo Ray .

  (Mostrar el tablero de ajedrez) Otro punto importante es: para mostrar el tablero de ajedrez, después de elegir jugar el juego, lo primero que debe hacer es imprimir el tablero de ajedrez para que el jugador lo vea . Como no estamos usando herramientas de interfaz (no hay cuadrados azules como en la imagen de arriba), para hacer que las cuadrículas que no se han verificado sean un poco misteriosas, inicialmente inicializamos el tablero de ajedrez con el carácter '*' (estrella) .


  En este momento, ¿han encontrado los lectores que si solo se usa una matriz bidimensional, habrá algunos conflictos ? Veamos la parte de las minas enterradas, dijimos que suponiendo que el número 1 se usa para representar las minas enterradas, y ahora al mostrar el tablero de ajedrez, se dice que se usa * para representar las cuadrículas que no se han verificado, por lo que las cuadrículas que no han sido revisados ​​son míos nuevamente ¿Cómo debo expresarlo? ¿Usar alguna otra notación? El jugador ha superado completamente el nivel después de jugar el último juego y descubrir las reglas . En este caso, usemos dos arreglos bidimensionales idénticos, uno para la visualización y otro para la información de la mina. Debido a que usamos el carácter * para inicializar el tablero de ajedrez de visualización, simplemente usamos una matriz de caracteres, y el tablero de ajedrez enterrado en minas usa el carácter '1' para representar las minas.

  Resumen : Cree dos matrices de caracteres con 9 filas y 9 columnas, una para mostrar y otra para la información de la mina . Como se muestra, lo inicializamos a '*'.Después de verificar, '*' se convierte en el número de minas ocultas en las 8 cuadrículas alrededor de la cuadrícula (el carácter 3 y el número 3 no son lo mismo, pero se puede usar para indicar que hay 3) ; no necesitamos imprimir el tablero de ajedrez con información sobre minas enterradas (equivalente a un fondo, el jugador opera el tablero de ajedrez que se muestra en la interfaz, y la operación de la recepción corresponde al fondo , formando una sensación de acoplamiento~), llamemos al tablero de ajedrez que entierra minas el tablero de minas. Al comienzo del tablero de minas, asumimos el carácter de inicialización '0'. .

  (Desminado) Luego hay otro problema, cómo conectar el tablero de minas y mostrar el tablero de ajedrez, es decir, al limpiar las minas, después de ingresar una coordenada no examinada de acuerdo con el tablero de ajedrez que se muestra, debemos encontrar las coordenadas correspondientes en el tablero de minas, después calculando el número de minas alrededor, regresa y sobrescribe el '*' que se muestra en la posición del tablero de ajedrez .

  Veamos la siguiente situación:

  Pero nuestra matriz tiene solo 9 filas y 9 columnas, y la parte amarilla está más allá del rango de la matriz. Si acceder a ella resultará en un acceso ilegal a la memoria, el programa se bloqueará, entonces, ¿qué debemos hacer ? También podríamos expandir la matriz para convertirla en 11 filas y 11 columnas (porque hay una fila adicional en la parte superior e inferior en la dirección horizontal, lo que equivale a agregar dos filas, y agregar las columnas más a la izquierda y más a la derecha es equivalente a agregar dos columnas). Cuando se inicializan el tablero de minas y el tablero de visualización, se inicializan 11 filas y 11 columnas. Aunque la única parte del tablero de visualización es 9*9, también elegimos inicializar 11 filas y 11 columnas (porque esto no inicializará los dos tableros Cuando se pasan los parámetros, los rangos y las columnas son inconsistentes) . Al mostrar el tablero de ajedrez, sigue siendo una parte de 9*9 .

1.2 Pensamientos rotos

  En primer lugar, si los lectores pueden leer hasta aquí, entonces te aplaudo primero. Después de todo, puedes leer tantas ideas y textos, lo que demuestra que eres un lector muy paciente . Jaja, entonces el siguiente paso es implementar la parte de la función de interfaz del barrido de minas:

2. Implementación de la interfaz del Buscaminas

2.1 Impresión del menú

  Al igual que el backgammon, el blogger lo escribió directamente:

void menu()
{
	printf("*****************\n");
	printf("*** 1. play  ****\n");
	printf("*** 0. exit  ****\n");
	printf("*****************\n");
}

void game()
{
	printf("扫雷游戏\n");
}

int main()
{
	int input = 0;
	do
	{
		menu();
		printf("这是一个扫雷游戏,请选择>:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();//接着就是实现game函数
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
		}
	} while (input);
	return 0;
}

2.2 Crear constantes de identificador e inicializar matrices

juego.h

 ROW y COL están configurados para la parte realmente útil del tablero (9*9), cuando estamos revisando minas o imprimiendo el tablero, no necesitamos usar (11*11) 

prueba.c

juego.c

2.3 Imprimir el tablero de ajedrez

  Lo que está impreso es la parte que muestra el tablero 9*9:

void Display(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	printf("-----扫雷游戏-----\n");
    //打印一行列数
	for (i = 0; i <= col; i++)
	{
		printf("%d ", i);
	}
	printf("\n");
    
	for (i = 1; i <= row; i++)
	{
        //在打印一行显示棋子之前打印该行的行数
		printf("%d ", i);
        //打印棋子
		int j = 0;
		for (j = 1; j <= col; j++)
		{
			printf("%c ", board[i][j]);//第1行到第9行是棋盘的有效部分
		}							   //第0行和第10行是外面一圈
		printf("\n");
	}
}

  Lo que debe agregarse aquí es: ¿ Existe una relación correspondiente entre la línea de coordenadas ingresada por el jugador auxiliar que imprimimos y los elementos de la matriz ? Defina dos matrices con 11 filas y 11 columnas, y el subíndice de fila y el subíndice de columna van del 0 al 10 . Miremos la imagen de abajo:

  Después de imprimir el tablero de ajedrez, ahora es el momento de enterrar las minas en el tablero ~ Tienes que tener minas antes de poder eliminarlas.

2.4 Minas aleatorias

void SetMine(char board[ROWS][COLS], int row, int col)
{
	int count = EASY_COUNT;//埋雷是一个循环,用一个未埋的雷数来控制循环
	while (count)
	{
		//随机生成1-9的x,y坐标
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		//判断是否是可以埋雷的位置
		if (board[x][y] == '0')
		{
			board[x][y] = '1';
			count--;//成功埋一颗雷,剩余雷数减一
		}
	}
}

  Ahora que la mina ha sido enterrada, implementemos nuevamente la función de interfaz de limpieza de minas.

2.5 Solución de problemas

  Debido a que el tablero de ajedrez para mostrar y el tablero de ajedrez para almacenar la información de Lei son exactamente iguales, sus coordenadas se corresponden.

//获取雷的个数
int Get_MineCount(char mine[ROWS][COLS], int x, int y)
{
	return (mine[x - 1][y] + mine[x - 1][y - 1] + mine[x][y - 1] + mine[x + 1][y - 1] +
		mine[x + 1][y] + mine[x + 1][y + 1] + mine[x][y + 1] + mine[x - 1][y + 1] - 8 * '0');
}

void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int win = 0;
	while (win < row*col-EASY_COUNT)//win是排掉不是雷的个数等于棋盘减去雷的个数时游戏胜利,不用再继续输入坐标排雷了
	{
		printf("请输入排查坐标:>");
		scanf("%d%d", &x, &y);
        //判断坐标合法性
		if ((x >= 1 && x <= 9) && (y >= 1 && y <= 9))
		{
			if (mine[x][y] == '1')
			{
				printf("很遗憾,排雷失败,你被炸死了\n");
				Display(mine, row, col);
				break;
			}
			else
			{
				int count = Get_MineCount(mine, x, y);//获取附近雷的个数
				show[x][y] = count + '0';
				Display(show, row, col);
				win++;
			}
		}
		else
		{
			printf("输入坐标不合法,请重新输入\n");
		}
	}
	if (win == row * col - EASY_COUNT)
	{
		printf("恭喜你,排雷成功\n");
		Display(mine, row, col);
	}
}

  Sume el círculo alrededor de la posición marcada, reste el valor del código ASCII de 8 caracteres '0', que es igual al número de caracteres 1 . El valor del código ASCII del carácter 1 es 49, y el valor del código ASCII del carácter 0 es 48. Por ejemplo, hay 3 minas alrededor de la ubicación que se va a verificar, luego sumamos 8 caracteres 0 más 3, restamos 8 caracteres 0, para haz que Get_MineCount devuelva el número 3 . Entonces, ¿por qué las coordenadas correspondientes a la matriz show deben asignarse como 3+'\0'? Debido a que esta es una matriz con caracteres como elementos, agregar el carácter 0 lo convierte en un carácter numérico correspondiente, e imprimirlo también puede indicar el número de minas.

 Bueno, este es nuestro juego de buscaminas simple. Todavía hay algunas funciones que no hemos implementado. Cuando verificamos una coordenada, necesitamos usar la recursividad para expandir un área grande. También está la función de marcar, interfaz gráfica , etc. , seguimos siendo los mismos, y los bloggers publicarán otro blog cuando tengan tiempo libre .

  Dado que no hay una función para expandir recursivamente un segmento, el blogger necesita ingresar 71 coordenadas para jugar un juego de victoria, jaja ~

3. Código fuente

3.1 archivo de encabezado y declaración de prototipo de función game.h

game.h
#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>//包含常见的头文件
#include <stdlib.h>
#include <time.h>

#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define EASY_COUNT 10

void InitBoard(char board[ROWS][COLS], int rows, int cols, char set);
void Display(char board[ROWS][COLS], int row, int col);
void SetMine(char board[ROWS][COLS], int row, int col);
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col);

3.2 Implementación de la función de juego game.c 

game.c

#include "game.h"

void InitBoard(char board[ROWS][COLS], int rows, int cols, char set)
{
	int i = 0;
	for (i = 0; i < rows; i++)
	{
		int j = 0;
		for (j = 0; j < cols; j++)
		{
			board[i][j] = set;
		}
	}
}

void Display(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	printf("-----扫雷游戏-----\n");
	//从零开始可以使其对齐
	for (i = 0; i <= col; i++)
	{
		printf("%d ", i);
	}
	printf("\n");
	for (i = 1; i <= row; i++)
	{
		printf("%d ", i);
		int j = 0;
		for (j = 1; j <= col; j++)
		{
			printf("%c ", board[i][j]);//第1行到第9行是棋盘的有效部分
		}							   //第0行和第10行是外面一圈
		printf("\n");
	}
}

void SetMine(char board[ROWS][COLS], int row, int col)
{
	int count = EASY_COUNT;//埋雷是一个循环,用一个未埋雷数来控制循环
	while (count)
	{
		//随机生成1-9的x,y坐标
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		//判断是不是可以埋雷的位置,不能重复埋雷
		if (board[x][y] == '0')
		{
			board[x][y] = '1';
			count--;//成功埋一颗雷,剩余雷数减一
		}
	}
}

int Get_MineCount(char mine[ROWS][COLS], int x, int y)
{
	return (mine[x - 1][y] + mine[x - 1][y - 1] + mine[x][y - 1] + mine[x + 1][y - 1] +
		mine[x + 1][y] + mine[x + 1][y + 1] + mine[x][y + 1] + mine[x - 1][y + 1] - 8 * '0');
}

void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int win = 0;
	while (win < row*col-EASY_COUNT)
	{
		printf("请输入排查坐标:>");
		scanf("%d%d", &x, &y);
		if ((x >= 1 && x <= 9) && (y >= 1 && y <= 9))
		{
			if (mine[x][y] == '1')
			{
				printf("很遗憾,排雷失败,你被炸死了\n");
				Display(mine, row, col);
				break;
			}
			else
			{
				int count = Get_MineCount(mine, x, y);//获取附近雷的个数
				show[x][y] = count + '0';
				Display(show, row, col);
				win++;
			}
		}
		else
		{
			printf("输入坐标不合法,请重新输入\n");
		}
	}
	if (win == row * col - EASY_COUNT)
	{
		printf("恭喜你,排雷成功\n");
		Display(mine, row, col);
	}
}

3.3 Archivo de código de prueba test.c 

test.c
#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"

void menu()
{
	printf("*****************\n");
	printf("*** 1. play  ****\n");
	printf("*** 0. exit  ****\n");
	printf("*****************\n");
}

void game()
{
	char mine[ROWS][COLS];//雷盘
	char show[ROWS][COLS];//显示盘
	InitBoard(mine, ROWS, COLS, '0');//将11行11列的雷盘都初始化成字符0
	InitBoard(show, ROWS, COLS, '*');
	Display(show, ROW, COL);
	SetMine(mine, ROW, COL);
	FindMine(mine, show, ROW, COL);
}

int main()
{
	int input = 0;
	//使用rand()生成随机数必须要调用一次srand
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("这是一个扫雷游戏,请选择>:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();//接着就是实现game函数
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
		}
	} while (input);
	return 0;
}

  Hablando de esto, se acabó~ 


Conclusión: ¡espero que los lectores obtengan algo después de leerlo! En el camino de aprender C, ¡deséanos más y más C!✔

  Los lectores que no entiendan este artículo o encuentren que hay errores en el contenido del artículo, dejen un mensaje en el área de comentarios a continuación para informarle al blogger ~, y también pueden dar algunas sugerencias para mejorar el artículo al blogger. ¡muchas gracias! último de los últimos!

  ❤ Por favor, preste atención, sus gustos son la fuerza impulsora de mi actualización, trabajemos duro para progresar juntos.

Supongo que te gusta

Origin blog.csdn.net/muwithxi/article/details/130567017
Recomendado
Clasificación