扫雷游戏C语言的实现
效果展示
实现步骤
首先一共三个文件,分别是test.c、game.h、game.c game.h文件中放入的是所需头文件,宏定义以及对的所需要的函数声明 game.c文件中是对所有函数的实现,其中会调用game.h文件。 test.c文件执行主函数,调用程序执行所需的各个函数,这些函数的实现在game.c文件中。 代码的实现如下: game.h
#pragma once
#ifndef GAME_H_
#include<stdlib.h>
#include<stdio.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 DisplayBoard(char board[ROWS][COLS], int row, int col);
void SetMine(char borad[ROWS][COLS], int row, int col);
void FindMine(char mine[ROWS][COLS], char borad[ROWS][COLS], int row, int col);
int get_mine_count(char borad[ROWS][COLS], int x, int y);
void spread(char mine[ROWS][COLS], char borad[ROWS][COLS], int row, int col);
#endif
game.c
#include "game.h"
void InitBoard(char board[ROWS][COLS], int rows, int cols, char set) {
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
board[i][j] = set;
}
}
}
void DisplayBoard(char board[ROWS][COLS], int row, int col) {
for (int i = 0; i <= col; ++i) {
printf("%d ", i);
}
printf("\n");
for (int i = 1; i <= row; ++i) {
printf("%d ", i);
for (int j = 1; j <= col; ++j) {
printf("%c ", board[i][j]);
}
printf("\n");
}
}
void SetMine(char borad[ROWS][COLS], int row, int col) {
int count = EASY_COUNT;
while (count) {
int x = rand() % row + 1;
int y = rand() % col + 1;
if (borad[x][y] == '0') {
borad[x][y] = '1';
count--;
}
}
}
int get_mine_count(char board[ROWS][COLS], int x, int y) {
return board[x - 1][y - 1] + board[x - 1][y] + board[x - 1][y + 1] + board[x][y - 1] +
board[x][y + 1] + board[x + 1][y - 1] + board[x + 1][y] + board[x + 1][y + 1] -
'0' * 8;
}
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col) {
while (1) {
int x = 0;
int y = 0;
int win = 0;
printf("请输入排查雷的坐标:>");
scanf("%d%d", &x, &y);
if (x >= 1 && x <= row && y >= 1 && y <= col) {
if (mine[x][y] == '1') {
printf("很遗憾,你被炸死了\n");
DisplayBoard(mine, row, col);
break;
}
else {
spread(mine,show, x, y);
DisplayBoard(show, row, col);
}
}
else {
printf("输入坐标非法,请重新输入!\n");
}
int flag = 0;
for (int i = 1; i <= row; ++i) {
for (int j = 1; j <= col; ++j) {
if (show[i][j] == '*') {
flag ++;
}
}
}
if (flag <= EASY_COUNT) {
printf("您赢了!!\n");
DisplayBoard(mine, row, col);
break;
}
}
}
void spread(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y) {
int count = get_mine_count(mine, x, y);
if (count+'0' == '0') {
show[x][y] = ' ';
if ((x - 1 >= 1) && (x - 1 <= ROW) && (y - 1 >= 1) && (y - 1 <= COL) && show[x - 1][y - 1] == '*') {
spread(mine, show, x - 1, y - 1);
}
if ((x >= 1) && (x <= ROW) && (y - 1 >= 1) && (y - 1 <= COL) && show[x][y - 1] == '*') {
spread(mine, show, x, y - 1);
}
if ((x + 1 >= 1) && (x + 1 <= ROW) && (y - 1 >= 1) && (y - 1 <= COL) && show[x + 1][y - 1] == '*') {
spread(mine, show, x + 1, y - 1);
}
if ((x - 1 >= 1) && (x - 1 <= ROW) && (y >= 1) && (y <= COL) && show[x - 1][y] == '*') {
spread(mine, show, x - 1, y);
}
if ((x + 1 >= 1) && (x + 1 <= ROW) && (y >= 1) && (y <= COL) && show[x + 1][y] == '*') {
spread(mine, show, x + 1, y);
}
if ((x - 1 >= 1) && (x - 1 <= ROW) && (y + 1 >= 1) && (y + 1 <= COL) && show[x - 1][y + 1] == '*') {
spread(mine, show, x - 1, y + 1);
}
if ((x >= 1) && (x <= ROW) && (y + 1 >= 1) && (y + 1 <= COL) && show[x][y + 1] == '*') {
spread(mine, show, x, y + 1);
}
if ((x + 1 >= 1) && (x + 1 <= ROW) && (y + 1 >= 1) && (y + 1 <= COL) && show[x + 1][y + 1] == '*') {
spread(mine, show, x + 1, y + 1);
}
}
else {
show[x][y] = count + '0';
}
}
test.c
#include "game.h"
void menu() {
printf("***********************\n");
printf("******* 1. play *******\n");
printf("******* 0. exit *******\n");
printf("***********************\n");
}
void game() {
char mine[ROWS][COLS] = { 0 };
char show[ROWS][COLS] = { 0 };
InitBoard(mine, ROWS, COLS, '0');
InitBoard(show, ROWS, COLS, '*');
SetMine(mine, ROW, COL);
DisplayBoard(show, ROW, COL);
FindMine(mine, show, ROW, COL);
}
void test() {
int input = 0;
srand((unsigned int)time(NULL));
do {
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("选择错误,请重新选择!");
break;
}
} while (input);
}
int main() {
test();
}
编程思想:
首先是游戏开始界面,很好实现。
当输入1的时候进入游戏。程序实现的时候首先需要设置雷放置的位置,该程序设置了10个雷。设置一个数组,初始化全为0;然后随机生成10个x,y坐标,将这10个位置置为1代表雷所在的位置。通过SetMine()来实现。
然后再设置一个数组,该数组用来排查雷。初始化该数组的内容全为*,然后输入该数组的一个坐标,查看上面第一个数组在该位置是否为1;如果不为1则查看该位置的四周8个位置是否有雷,并计算四周雷的数量返回到该位置上。该过程通过FindMine、get_mine_count和spread来实现。其中spread函数是查看该位置四周是否有雷,如果没有雷则会将该位置置为空并继续循环查找旁边的8个位置,知道该位置或四周有雷停止查找。通过递归来实现。
之所以设置两个数组是因为在排查雷的时候需要标注四周雷的数量,会和原数组中设置雷的位置产生冲突。
具体的实现见代码。
|