目录
1.首先我们对常用的字符和变量进行定义,以便我们后期的维护和修改
一.创建用户选择菜单
static void Menu()
{
printf("########################\n");
printf("# 1. Play 0.Exit #\n");
printf("########################\n");
}//用户菜单
二.创建主函数
int main()
{
int quit = 0;
int select = 0;
while (!quit){
Menu();
printf("Please Enter# ");
scanf("%d", &select);
switch (select){
case 1:
Game();//输入1时进入游戏
break;
case 0:
quit = 1;
break;
default:
printf("Postion Error, Try Again!\n");
break;
}
}
printf("byebye!\n");
system("pause");
return 0;
}
三.编写游戏函数
我们可以看到在主函数中我们进入游戏时调用了Game(),因此只需要将游戏的实现过程写入此函数即可
1.首先我们对常用的字符和变量进行定义,以便我们后期的维护和修改
#define ROW 8//定义行(实际行为ROW-2)
#define COL 8//定义列 (实际列为COL-2)
#define STYLE '*'//未扫的位置用*表示
#define NUM 10//定义雷的个数
2.编写游戏函数的大体过程
我们可以看到,在编写游戏函数时,我们调用了很多函数,实现这些函数,即可完成代码的编写。
void Game()
{
srand((unsigned long)time(NULL));//生成随机数
char show_board[ROW][COL];
char mine_board[ROW][COL];
memset(show_board, STYLE, sizeof(show_board));
memset(mine_board, '0', sizeof(mine_board));
SetMines(mine_board, ROW, COL);
int count = (ROW - 2)*(COL - 2) - NUM;//计算不是雷的位置的个数和,用于判断while是否继续
while (count){
system("cls");
ShowBoard(show_board, ROW, COL);
printf("Please Enter Your Postion<x,y># ");
int x = 0;
int y = 0;
scanf("%d %d", &x, &y);
if (x < 1 || x > 10 || y < 1 || y > 10){
printf("Postion Error!\n");
continue;
}//判断输入的位置是否合法,不合法则提示重新输入
if (show_board[x][y] != STYLE){
printf("Postion Is not *\n");
continue;
}//判断舒输入的位置是否已经被扫过
if (mine_board[x][y] == '1'){
printf("game over!\n");
ShowBoard(mine_board, ROW, COL);
break;
}//如果输入的位置有雷,则游戏结束
show_board[x][y] = CountMines(mine_board, x, y);
count--;
}
}
我们注意到该函数里已经有了判断扫雷位置合法性与判断游戏胜利与否的函数,不需要再重新编写函数
3.随机埋雷的函数
static void SetMines(char board[][COL], int row, int col)
{
int count = NUM;
while (count){
int x = rand() % (row - 2) + 1;
int y = rand() % (col - 2) + 1;
if (board[x][y] == '0'){
board[x][y] = '1';
count--;
}
}
}//埋雷过程,可在mine.h中更改雷的个数
4.展示棋盘的函数
static void ShowBoard(char board[][COL], int row, int col)
{
printf(" ");
for (int i = 1; i <= (col - 2); i++){
printf("%d ", i);
}
printf("\n");
ShowLine(col);
for (int i = 1; i <= (row - 2); i++){
printf("%-3d|", i);
for (int j = 1; j <= (col - 2); j++){
printf(" %c |", board[i][j]);
}
printf("\n");
ShowLine(col);
}
}//展示棋盘
为了方便更改行和列之后棋盘展示更加符合编写了方便展示棋盘的函数如下
static void ShowLine(int col)
{
for (int i = 0; i <= (col - 2); i++){
printf("----");
}
printf("\n");
}//方便更改行列时匹配展示的棋盘
5.扫雷成功后展示周围雷个数的函数
static char CountMines(char board[][COL], 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 + 1][y + 1] + board[x + 1][y] + \
board[x + 1][y - 1] + board[x][y - 1] - 7 * '0';
}//计算用户扫一个位置成功后周围雷的个数并传到该位置
自此,我们的所有代码编写完成。
四.用多文件形式展示代码与运行成果
1.头文件 main.h
#pragma once
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <windows.h>
#define ROW 8//定义行(实际行为ROW-2)
#define COL 8//定义列 (实际列为COL-2)
#define STYLE '*'//未扫的位置用*表示
#define NUM 10//定义雷的个数
extern void Game();
2.源文件 main.c
#include "clear_mine.h"
static void Menu()
{
printf("########################\n");
printf("# 1. Play 0.Exit #\n");
printf("########################\n");
}//用户菜单
int main()
{
int quit = 0;
int select = 0;
while (!quit){
Menu();
printf("Please Enter# ");
scanf("%d", &select);
switch (select){
case 1:
Game();//输入1时进入游戏
break;
case 0:
quit = 1;
break;
default:
printf("Postion Error, Try Again!\n");
break;
}
}
printf("byebye!\n");
system("pause");
return 0;
}
3.源文件 game.c
#include "clear_mine.h"
static void SetMines(char board[][COL], int row, int col)
{
int count = NUM;
while (count){
int x = rand() % (row - 2) + 1;
int y = rand() % (col - 2) + 1;
if (board[x][y] == '0'){
board[x][y] = '1';
count--;
}
}
}//埋雷过程,可在mine.h中更改雷的个数
static void ShowLine(int col)
{
for (int i = 0; i <= (col - 2); i++){
printf("----");
}
printf("\n");
}//方便更改行列时匹配展示的棋盘
static void ShowBoard(char board[][COL], int row, int col)
{
printf(" ");
for (int i = 1; i <= (col - 2); i++){
printf("%d ", i);
}
printf("\n");
ShowLine(col);
for (int i = 1; i <= (row - 2); i++){
printf("%-3d|", i);
for (int j = 1; j <= (col - 2); j++){
printf(" %c |", board[i][j]);
}
printf("\n");
ShowLine(col);
}
}//展示棋盘
static char CountMines(char board[][COL], 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 + 1][y + 1] + board[x + 1][y] + \
board[x + 1][y - 1] + board[x][y - 1] - 7 * '0';
}//计算用户扫一个位置成功后周围雷的个数并传到该位置
void Game()
{
srand((unsigned long)time(NULL));//生成随机数
char show_board[ROW][COL];
char mine_board[ROW][COL];
memset(show_board, STYLE, sizeof(show_board));
memset(mine_board, '0', sizeof(mine_board));
SetMines(mine_board, ROW, COL);
int count = (ROW - 2)*(COL - 2) - NUM;//计算不是雷的位置的个数和,用于判断while是否继续
while (count){
system("cls");//实现在一个图中扫雷
ShowBoard(show_board, ROW, COL);
printf("Please Enter Your Postion<x,y># ");
int x = 0;
int y = 0;
scanf("%d %d", &x, &y);
if (x < 1 || x > 10 || y < 1 || y > 10){
printf("Postion Error!\n");
continue;
}//判断输入的位置是否合法,不合法则提示重新输入
if (show_board[x][y] != STYLE){
printf("Postion Is not *\n");
continue;
}//判断舒输入的位置是否已经被扫过
if (mine_board[x][y] == '1'){
printf("game over!\n");
ShowBoard(mine_board, ROW, COL);
break;
}//如果输入的位置有雷,则游戏结束
show_board[x][y] = CountMines(mine_board, x, y);
count--;
}
}
4.运行结果