《C语言实战:猜数字 + 扫雷 + 自动关机,三个小项目如何“串”成一个完整游戏》

本文介绍使用C语言实现的集成式小游戏项目,包含猜数字(5次机会机制)、扫雷(10雷布局)及Windows系统关机控制(shutdown命令调用)。通过menu()和game()函数组织流程,实现多轮猜数字通关后进入扫雷,失败则触发倒计时关机;支持取消关机(shutdown -a)与安全测试注释方案。重点涵盖rand()随机数生成、system()命令执行、字符串比较(strcmp)、数组输入(scanf %s)等核心C语言实践技术。

目录

1.关机程序
2.猜数字游戏
3.猜数字游戏与关机程序结合

4.扫雷游戏
5.猜数字游戏 扫雷游戏(关机融合版)

1.关机程序
效果:
程序运行起来后,电脑就倒计时1分钟关机。
需用到system函数
system是一个函数,这个函数是用来执行命令的。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int main()
{
	char input[20] = { 0 };
	system("shutdown -s -t 60");
again:
	printf("请注意,你的电脑在一分钟内关机,如果输入:我是猪,就取消关机\n");
	scanf("%d", input);//数组名本身就是地址,input等同于&input[0]
	//两个字符串判断相等,不能用==,要用strcmp函数,相等则返回0.
	if (strcmp(input, "我是猪") == 0)
	{
		system("shutdown -a");//取消关机
		printf("你很乖,关机已取消\n");
	}
	else
	{
		goto again;
	}
	return 0;
}

或者用while循环也行

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
	char input[20] = { 0 };
	system("shutdown -s -t 60");

	while (1)
	{
		printf("请注意,你的电脑在一分钟内关机,如果输入:我是猪,就取消关机\n");
		scanf("%d", input);//数组名本身就是地址,input等同于&input[0]
		//两个字符串判断相等,不能用==,要用strcmp函数,相等则返回0.
		if (strcmp(input, "我是猪") == 0)
		{
			system("shutdown -a");//取消关机
			printf("你很乖,关机已取消\n");
			break;
		}
	}
	

	return 0;
}

2.猜数字游戏
第一种:无限循环,猜不对一直猜。

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

void game()
{
	//首先生成1~100的随机值
	int r = rand() % 100 + 1;
	int a = 0;
	while (1)
	{
		printf("尊贵的玩家,请猜数字\n");
		scanf("%d", &a);
		if (a > r)
		{
			printf("猜大了哦!再接再厉\n");
		}
		else if (a < r)
		{
			printf("猜小了哦!继续努力\n");
		}
		else
		{
			printf("尊贵的玩家啊,恭喜你,猜对了,数字是:%d", r);
			break;
		}
	}
}

int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));//保证调用一次就行
	do
	{
		menu();
		printf("尊贵的来宾,请做出您的选择:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("推出游戏\n");
			printf("欢迎您的参与,小夜期待您的再次光临\n");
			break;
		default:
			printf("亲爱的客人,选择错误,请详细阅读规则后再做出您的选择\n");
			break;
		}
	} while (input);
}

限制猜数字次数为5次

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

void game()
{
	//首先生成1~100的随机值
	int r = rand() % 100 + 1;
	int a = 0;
	int count = 5;
	//scanf("%d",&count);加上这个可自定义猜数字次数
	while (count)
	{
		printf("尊贵的玩家,请猜数字\n");
		scanf("%d", &a);
		if (a > r)
		{
			printf("猜大了哦!再接再厉\n");
		}
		else if (a < r)
		{
			printf("猜小了哦!继续努力\n");
		}
		else
		{
			printf("尊贵的玩家啊,恭喜你,猜对了,数字是:%d", r);
			break;
		}
	
		int b = --count;
		printf("尊贵的玩家,您的剩余次数为:%d\n", b);
		if (count == 0)
		{
			printf("尊贵的玩家,很遗憾的通知你:\n");
			printf("次数已用尽,游戏失败。\n");
			break;
		}
	}
}

int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));//保证调用一次就行
	do
	{
		menu();
		printf("尊贵的来宾,请做出您的选择:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("推出游戏\n");
			printf("欢迎您的参与,小夜期待您的再次光临\n");
			break;
		default:
			printf("亲爱的客人,选择错误,请详细阅读规则后再做出您的选择\n");
			break;
		}
	} while (input);
	return 0;
}

3.猜数字游戏与关机程序结合

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

void game()
{
	//首先生成1~100的随机值
	int r = rand() % 100 + 1;
	int a = 0;
	int count = 5;	//总共只能猜5次

	while (count > 0)
	{
		printf("尊贵的玩家,请猜数字(1~100),你还有%d次机会:\n", count);
		scanf("%d", &a);

		if (a > r)
		{
			printf("猜大了哦!再接再厉\n");
		}
		else if (a < r)
		{
			printf("猜小了哦!继续努力\n");
		}
		else
		{
			printf("尊贵的玩家啊,恭喜你,猜对了,数字是:%d\n", r);
			return;	//猜对了就直接结束game函数,不会走到关机那一步
		}

		count--;	//猜错一次,机会减一
		printf("尊贵的玩家,您的剩余次数为:%d\n", count);
	}

	//能走到这里,说明5次都猜错了,启动关机程序
	printf("尊贵的玩家,很遗憾的通知你:\n");
	printf("次数已用尽,游戏失败。\n");
	printf("电脑将在60秒后关机!如果输入:我是猪,就取消关机\n");
	system("shutdown -s -t 60");	//-s表示关机,-t 60表示60秒后执行

	//给玩家一次“后悔”的机会:输入正确口令就取消关机
	while (1)
	{
		char input[20] = { 0 };
		scanf("%s", input);	//读字符串用%s,数组名本身就是地址,不用加&
		//两个字符串判断相等不能用==,要用strcmp函数,相等时返回0
		if (strcmp(input, "我是猪") == 0)
		{
			system("shutdown -a");	//-a表示取消关机
			printf("你很乖,关机已取消\n");
			break;
		}
		else
		{
			printf("口令错误,电脑依然会在60秒后关机!\n");
		}
	}
}

int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));	//随机数种子,整个程序调用一次就行

	do
	{
		menu();
		printf("尊贵的来宾,请做出您的选择:");
		scanf("%d", &input);

		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			printf("欢迎您的参与,小夜期待您的再次光临\n");
			break;
		default:
			printf("亲爱的客人,选择错误,请详细阅读规则后再做出您的选择\n");
			break;
		}
	} while (input);

	return 0;
}

程序工作小白版本

int main()                  // 程序入口
{
    srand((unsigned int)time(NULL));  // 用当前时间做“随机种子”,只要一次
    do {
        menu();                      // 打印菜单
        scanf("%d", &input);         // 输入 1 或 0
        switch (input) {
        case 1: game(); break;       // 玩一局
        case 0: ...                  // 退出
        }
    } while (input);                 // 输入0就结束循环
}
  • menu():只负责打印那几行星号菜单。
  • game():真正玩游戏的地方。
  • int r = rand() % 100 + 1; → 生成 1~100 的随机答案。
  • int count = 5; → 一共 5 次机会。
  • while (count > 0) → 还有机会就继续猜。
  • 猜大了 / 猜小了都会提示,然后 count-- 把机会减 1,并告诉你剩几次。
  • 猜对了执行 return;,直接退出 game(),不会走到关机那一步。
  • 5 次都错,循环结束,来到关机部分:
  • system(“shutdown -s -t 60”); → 调用 Windows 的关机命令,-s 是关机,-t 60 是 60 秒后执行。
  • 接着的 while(1) 是“后悔药”:输入 我是猪,就执行 system(“shutdown -a”); 取消关机(-a = abort)。
  • strcmp(input, “我是猪”) == 0 → 比较两个字符串必须用 strcmp,相等才返回 0,不能写 ==。
  • 输入用 scanf(“%s”, input),%s 读字符串,数组名本身就是地址,所以不加 &。
    你可以按需要改
  • 想让它 5 次后立刻关机:把 -t 60 改成 -t 0。
  • 想 去掉后悔药、真的无解:把 game() 里第二个 while (1) 整段删掉。
  • 想 安全测试不关机:先把 system(“shutdown…”) 这两行前面加 // 注释掉,测试逻辑,最后再放开。
  • 想改次数:把 int count = 5; 改成别的数字即可。

4.扫雷游戏

  • game.h:放常量(ROW/COL)和函数声明,相当于一张“目录”。

  • game.c:放函数的具体实现(chushihua、buzhi、dayin、FindMine)。

  • one study_10_31.c:放 main()、menu()、game(),负责调用上面那些函数。

  • -one study_10_31.c:

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 };//存放排查出的雷的信息
	//棋盘初始化一下
	//mine数组初始化为全'0' - 表示还没有布置雷,所有位置都不是雷
	//show数组初始化为全'*' - 表示所有位置都没有被排查
	chushihua(mine, ROWS, COLS, '0');
	chushihua(show, ROWS, COLS, '*');

	//布置雷
	buzhi(mine, ROW, COL);

	//打印棋盘(只打印show;打印mine会把所有雷的位置直接暴露给玩家)
	dayin(show, ROW, COL);
	//排查雷
	FindMine(mine, show, ROW, COL);
}



int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));	//随机数种子,整个程序调用一次就行

	do
	{
		menu();
		printf("尊贵的来宾,请做出您的选择:");
		scanf("%d", &input);

		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			printf("欢迎您的参与,小夜期待您的再次光临\n");
			break;
		default:
			printf("亲爱的客人,选择错误,请详细阅读规则后再做出您的选择\n");
			break;
		}
	} while (input);

	return 0;
}

game.h:

#pragma once

//头文件
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>


//定义常量的符号
#define ROW 9
#define COL 9

#define ROWS (ROW+2)
#define COLS (COL+2)

#define EASY_COUNT 10

//函数声明

//初始化棋盘
void chushihua(char board[ROWS][COLS], int r, int c, char set);

//打印棋盘
void dayin(char board[ROWS][COLS], int r, int c);

//布置雷
void buzhi(char board[ROWS][COLS], int r, int c);

//排查雷
void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int r, int c);

game.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"

void chushihua(char board[ROWS][COLS], int r, int c, char set)
{
	int i = 0;
	for (i = 0;i < r;i++)
	{
		int j = 0;
		for (j = 0; j < c;j++)
		{
			board[i][j] = set;
		}
	}

}

void dayin(char board[ROWS][COLS], int r, int c)
{
	int i = 0;
	for (i = 0;i <=c;i++)
	{
		printf("%d", i);
	}
	printf("\n");
	for (i = 1;i <= r;i++)
	{
		int j = 0;
		printf("%d", i);
		for (j = 1;j <= c;j++)
		{
			printf("%c", board[i][j]);
		}
		printf("\n");
	}
}


void buzhi(char mine[ROWS][COLS], int r, int c)
{
//随机布置10个雷
	int count = EASY_COUNT;
	while (count)
	{
		//生成随机坐标  x  y范围均为1~9
		int x = rand() % r + 1;
		int y = rand() % c + 1;
		if ( mine [x][y] == '0')
		{
			mine[x][y] = '1';
			count--;
		}
	}
}

static int GetMineCount(char mine[ROWS][COLS], int x, int y)
{
	int i = 0;
	int j = 0;
	int c = 0;
	for (i = -1;i <= 1;i++)
	{
		for (j = -1;j <= 1;j++)
		{
			if (mine[x + i][y + j] == '1')
				c++;
		}
	}
	return c;
}


void FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int r, int c)
{
	int x = 0;
	int y = 0;
	int win = 0;
	while (win < r * c - EASY_COUNT)
	{
		printf("请输入要排查的坐标:");
		scanf("%d %d", &x, &y);
		//坐标要合法
		if (x >= 1 && x <= r && y >= 1 && y <= c)
		{
			if (mine[x][y] == '1')
			{
				printf("很遗憾,你被炸死了\n");
				dayin(mine, r, c);
				break;
			}
			else
			{
				if (show[x][y] == '*')
				{
					//统计雷的数量
					int n = GetMineCount(mine, x, y);
					show[x][y] = n + '0';
					dayin(show, r, c);
					win++;
				}
				else
				{
					printf("该坐标已经被排查过,重新输入坐标\n");
				}
			}
		
		}
		else
		{
			printf("输入的坐标非法,请重新输入\n");
		}
		if (win == r * c - EASY_COUNT)
		{
			printf("恭喜你,排雷成功\n");
			dayin(mine, r, c);
		}
	}
}

游戏流程
选 1.play
↓
猜数字第1轮(5次机会)──5次用完──→ 关机程序
↓ 猜对
猜数字第2轮(5次机会)──5次用完──→ 关机程序
↓ 猜对
猜数字第3轮(5次机会)──5次用完──→ 关机程序
↓ 3轮全对
进入扫雷(10个雷)
↓ 踩雷 ──────────────→ 关机程序
↓ 排完所有安全格
全部通关,电脑保住了
one study_10_31.c:

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

// 关机和取消关机的公共函数:猜数字失败、扫雷失败都会调用它
void guanji()
{
	printf("\n电脑将在60秒后关机!\n");
	printf("如果输入:我是猪,就取消关机\n");
	system("shutdown -s -t 60");	//-s关机,-t 60表示60秒后执行

	while (1)
	{
		char input[20] = { 0 };
		scanf("%s", input);	//读字符串用%s,数组名本身就是地址
		//字符串比较要用strcmp,相等返回0
		if (strcmp(input, "我是猪") == 0)
		{
			system("shutdown -a");	//-a取消关机
			printf("你很乖,关机已取消\n");
			break;
		}
		else
		{
			printf("口令错误,电脑依然会在60秒后关机!\n");
		}
	}
}

// 猜数字:3轮,每轮5次机会。全部通过返回1,任意一轮失败返回0
int caishuzi()
{
	int round = 0;

	for (round = 1; round <= 3; round++)
	{
		int r = rand() % 100 + 1;	//本轮答案:1~100
		int count = 5;				//本轮5次机会
		int win = 0;				//0表示还没猜对
		int a = 0;

		printf("\n===== 第 %d 轮猜数字开始(范围1~100,共5次机会)=====\n", round);
		while (count > 0)
		{
			printf("请猜数字,你还有%d次机会:", count);
			scanf("%d", &a);

			if (a > r)
			{
				printf("猜大了哦!再接再厉\n");
			}
			else if (a < r)
			{
				printf("猜小了哦!继续努力\n");
			}
			else
			{
				printf("恭喜你,第 %d 轮猜对了,数字是:%d\n", round, r);
				win = 1;
				break;	//猜对了,跳出本轮
			}

			count--;	//猜错一次,机会减一
			printf("本轮剩余次数:%d\n", count);
		}

		if (win == 0)
		{
			printf("很遗憾,第 %d 轮5次机会用完了,正确答案是:%d\n", round, r);
			return 0;	//任意一轮失败就返回0
		}
	}

	return 1;	//3轮全部通过
}

// 扫雷:排雷成功返回1,踩雷返回0
int saolei()
{
	char mine[ROWS][COLS] = { 0 };	//存放雷
	char show[ROWS][COLS] = { 0 };	//存放到玩家看到的棋盘

	chushihua(mine, ROWS, COLS, '0');	//mine全初始化成'0',表示没雷
	chushihua(show, ROWS, COLS, '*');	//show全初始化成'*',表示未排查

	buzhi(mine, ROW, COL);				//随机布置10个雷

	printf("\n===== 扫雷开始(坐标范围1~9,一共10个雷)=====\n");
	dayin(show, ROW, COL);

	return FindMine(mine, show, ROW, COL);	//FindMine返回1胜利、0踩雷
}

int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));	//随机数种子,整个程序调用一次就行

	do
	{
		menu();
		printf("尊贵的来宾,请做出您的选择:");
		scanf("%d", &input);

		switch (input)
		{
		case 1:
			//第一步:猜数字,3轮全对才能往下走
			if (caishuzi() == 0)
			{
				printf("\n猜数字失败,游戏结束,执行关机程序!\n");
				guanji();
				break;
			}

			//第二步:3轮都猜对,奖励一局扫雷
			printf("\n三轮猜数字全部通过!奖励你一局扫雷!\n");
			if (saolei() == 0)	//踩雷
			{
				printf("\n很遗憾,扫雷失败,执行关机程序!\n");
				guanji();
			}
			else				//排雷成功
			{
				printf("\n恭喜你,全部通关!电脑保住了!\n");
			}
			break;
		case 0:
			printf("退出游戏\n");
			printf("欢迎您的参与,小夜期待您的再次光临\n");
			break;
		default:
			printf("亲爱的客人,选择错误,请详细阅读规则后再做出您的选择\n");
			break;
		}
	} while (input);

	return 0;
}

game.h

#pragma once

//头文件
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>


//定义常量的符号
#define ROW 9
#define COL 9

#define ROWS (ROW+2)
#define COLS (COL+2)

#define EASY_COUNT 10

//函数声明

//初始化棋盘
void chushihua(char board[ROWS][COLS], int r, int c, char set);

//打印棋盘
void dayin(char board[ROWS][COLS], int r, int c);

//布置雷
void buzhi(char board[ROWS][COLS], int r, int c);

//排查雷(返回1表示排雷成功,返回0表示踩雷失败)
int FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int r, int c);

game.c

#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"

void chushihua(char board[ROWS][COLS], int r, int c, char set)
{
	int i = 0;
	for (i = 0;i < r;i++)
	{
		int j = 0;
		for (j = 0; j < c;j++)
		{
			board[i][j] = set;
		}
	}

}

void dayin(char board[ROWS][COLS], int r, int c)
{
	int i = 0;
	for (i = 0;i <=c;i++)
	{
		printf("%d", i);
	}
	printf("\n");
	for (i = 1;i <= r;i++)
	{
		int j = 0;
		printf("%d", i);
		for (j = 1;j <= c;j++)
		{
			printf("%c", board[i][j]);
		}
		printf("\n");
	}
}


void buzhi(char mine[ROWS][COLS], int r, int c)
{
//随机布置10个雷
	int count = EASY_COUNT;
	while (count)
	{
		//生成随机坐标  x  y范围均为1~9
		int x = rand() % r + 1;
		int y = rand() % c + 1;
		if ( mine [x][y] == '0')
		{
			mine[x][y] = '1';
			count--;
		}
	}
}

static int GetMineCount(char mine[ROWS][COLS], int x, int y)
{
	int i = 0;
	int j = 0;
	int c = 0;
	for (i = -1;i <= 1;i++)
	{
		for (j = -1;j <= 1;j++)
		{
			if (mine[x + i][y + j] == '1')
				c++;
		}
	}
	return c;
}


int FindMine(char mine[ROWS][COLS], char show[ROWS][COLS], int r, int c)
{
	int x = 0;
	int y = 0;
	int win = 0;
	while (win < r * c - EASY_COUNT)
	{
		printf("请输入要排查的坐标:");
		scanf("%d %d", &x, &y);
		//坐标要合法
		if (x >= 1 && x <= r && y >= 1 && y <= c)
		{
			if (mine[x][y] == '1')
			{
				printf("很遗憾,你被炸死了\n");
				dayin(mine, r, c);
				return 0;	//踩雷,返回0表示失败
			}
			else
			{
				if (show[x][y] == '*')
				{
					//统计雷的数量
					int n = GetMineCount(mine, x, y);
					show[x][y] = n + '0';
					dayin(show, r, c);
					win++;
				}
				else
				{
					printf("该坐标已经被排查过,重新输入坐标\n");
				}
			}
		
		}
		else
		{
			printf("输入的坐标非法,请重新输入\n");
		}
	}

	//能走出循环,说明所有安全格子都排完了
	printf("恭喜你,排雷成功\n");
	dayin(mine, r, c);
	return 1;	//返回1表示胜利
}
1. caishuzi() —— 猜数字
for (round = 1; round <= 3; round++)   // 循环3轮
{
    int r = rand() % 100 + 1;          // 每轮重新生成答案
    int count = 5;                     // 每轮5次机会
    while (count > 0) { ... }          // 5次猜完就退出
    if (win == 0) return 0;            // 一轮失败,直接返回0
}
return 1;                              // 3轮都过,返回1
- win = 1 表示这轮猜对了,break 跳出本轮的 while。
- 任意一轮 5 次用完还没中,return 0,主程序就调用关机。
2. saolei() —— 扫雷
chushihua(mine, ROWS, COLS, '0');  // 初始化雷盘
chushihua(show, ROWS, COLS, '*');  // 初始化玩家看到的盘
buzhi(mine, ROW, COL);             // 随机布置10个雷
dayin(show, ROW, COL);             // 打印棋盘
return FindMine(mine, show, ROW, COL);  // 1=赢,0=踩雷
这里直接复用了 game.c 里原来写好的函数,没有重写一遍。
3. guanji() —— 关机程序(公共函数)
system("shutdown -s -t 60");  // 60秒后关机
...
if (strcmp(input, "我是猪") == 0)
    system("shutdown -a");    // 取消关机
猜数字失败、扫雷踩雷都调用同一个 guanji(),这样两个失败点就“完美接”在一起了。
4. main() —— 总指挥
if (caishuzi() == 0) { guanji(); break; }   // 猜数字失败 → 关机
if (saolei() == 0)   { guanji(); }          // 扫雷失败 → 关机
else                 { 全部通关 }
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值