c语言第六周(一)扫雷及操作符复习

一、扫雷程序

头文件
#include <stdio.h>
#include <windows.h>

#define EASY_count 10  //简易难度下的雷的个数 设为10

#define ROW 9          //雷盘的行数
#define COL 9          //雷盘的列数

#define ROWS 11        //实际定义雷盘数组的行数和列数
#define COLS 11        //往大了定义是为了排查雷时不出现数组越界的情况


int win_s;             //win_s用于记录标记了多少正确的的雷                      
                       //当win_s == EASY_count时,则游戏胜利

void game();

//初始化棋盘
void Intboard(char board[ROWS][COLS], int rows, int cols, char aim);

//打印棋盘
void Displayboard(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);

//优化排查雷
void get_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y, int row, int col, int* p);

//标记雷
void Setnote(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y, int row, int col);
具体函数
#define _CRT_SECURE_NO_WARNINGS
#include"源.h"
//初始化棋盘
void Intboard(char board[ROWS][COLS], int rows, int cols, char aim)
{
	int a, b;
	for (a = 0; a < rows; a++)
	{
		for (b = 0; b < cols; b++)
		{
			board[a][b] = aim;
		}
	}
}

//打印棋盘

void Displayboard(char board[ROWS][COLS], int row, int col)
{
	int a, b;
	for (a = 0; a <= col; a++)
	{
		if (a == 0)
			printf("    ");
		else
			printf("%d ", a);
	}
	printf("\n");
	for (a = 0; a <= col; a++)
	{
		if (a == 0)
			printf("    ");
		else
			printf("%c ", 'v');
	}
	printf("\n");
	for (a = 1; a <= row; a++)
	{
		printf("%d > ", a);
		for (b = 1; b <= col; b++)
		{
			printf("%c ", board[a][b]);
		}
		printf("\n");
	}
}


//布置雷
void Setmine(char board[ROWS][COLS], int row, int col)
{
	int count = EASY_count;
	while (count)
	{
		int x = rand() % row + 1;
		int y = rand() % col + 1;
		if (board[x][y] != '1')
		{
			board[x][y] = '1';
			count--;
		}
	}
}


//排查周围八格总计的雷数
static int get_mine_count(char mine[ROWS][COLS], int x, int y)
{
	return mine[x - 1][y - 1] +
		mine[x - 1][y] +
		mine[x - 1][y + 1] +
		mine[x][y - 1] +
		mine[x][y + 1] +
		mine[x + 1][y - 1] +
		mine[x + 1][y] +
		mine[x + 1][y + 1] - 8 * '0';
}

//游戏排查雷的主函数
void Findmine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	//选择要进行排查雷或标记雷
	//输入要排查的坐标或要标记的坐标
	//判断输入的坐标是否合理
	int x = 0, y = 0, flag = 0, note = 0, win = 0;
	int* p = &win;
	while (1)
	{
		printf("请选择要:0.排查雷  1.标记雷\n");
		scanf("%d", &note);
		switch (note)
		{
		case 0:
		opt:
			printf("请输入要排查的雷\n坐标(行号 列号):");
			scanf("%d %d", &x, &y);
			system("cls");
			if (x >= 1 && x <= row && y >= 1 && y <= col)
			{
				if (mine[x][y] == '1')
				{
					printf("很遗憾,你被炸死了\n");
					Displayboard(mine, row, col);
					do
					{
						printf("输入0进行下一步操作:");
						scanf("%d", &flag);
						if (flag == 0)
							goto exit;
						else
						{
							printf("输入错误,请重新输入\n");
							Displayboard(show, row, col);
						}
						Sleep(2500);
					} while (flag);
					break;
				}
				else
				{
					//用递归实现自动排查周围无雷的格子
					get_mine(mine, show, x, y, row, col, p);
					//显示排查的信息
					Displayboard(show, row, col);

				}
			}
			else
			{
				printf("坐标不合法,请重新输入\n");
				Displayboard(show, row, col);
				goto opt;
			}

			break;
		case 1:
			Setnote(mine, show, x, y, row, col);
			break;

		}
		if (win == row * col - EASY_count || win_s == EASY_count)
		{
			printf("恭喜你,排雷成功\n");
			win = 0;
			win_s = 0;
			Sleep(5000);
		exit:
			system("cls");
			break;
		}
	}
}

//定义递归函数
void get_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y, int row, int col, int* p)
{

	if (x > 0 && x <= row && y > 0 && y <= col)
	{
		int count = get_mine_count(mine, x, y);
		if (count == 0)
		{
			(*p)++;
			int a, b;
			show[x][y] = '0';
			for (a = -1; a <= 1; a++)
			{
				for (b = -1; b <= 1; b++)
				{
					if (show[x + a][y + b] == '*')
						get_mine(mine, show, x + a, y + b, row, col, p);
				}
			}
		}
		else
		{
			(*p)++;
			show[x][y] = count + '0';
		}
	}
}

//标记雷的函数定义
void Setnote(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y, int row, int col)
{
	while (1)
	{
		printf("请输入要标记的雷的坐标:");
		scanf("%d %d", &x, &y);
		system("cls");
		if (x >= 1 && x <= row && y >= 1 && y <= col && show[x][y] != '0' && show[x][y] != '1')
		{
			show[x][y] = '@';
			if (mine[x][y] == '1')
				win_s++;
			break;
		}
		else
		{
			printf("输入坐标不合法,请重新输入\n");
			Displayboard(show, row, col);
		}
	}
	Displayboard(show, row, col);
}
主程序
#define _CRT_SECURE_NO_WARNINGS
#include"源.h"
void Description()
{
	int n;
	printf("欢迎来到C语言扫雷游戏,此处为游戏说明\n在游戏中,‘0’表示无雷,‘1’表示有雷\n");
	printf("'*'表示未被排查的区域,‘@’表示自己所标记的雷的位置\n");
	printf("如果您已悉知,请按‘任意键+回车键’确定正式进入游戏选择界面");
	scanf("%d", &n);
	system("cls");
}

void menu()
{
	printf("                              \n");
	printf("                              \n");
	printf("                              \n");
	printf("          扫雷游戏            \n");
	printf("           1.开始             \n");
	printf("           0.退出             \n");
	printf("                              \n");
	printf("                              \n");
	printf("                              \n");
}

void game()
{
	Sleep(1000);
	system("cls");
	char mine[ROWS][COLS] = { 0 };//存放布置好的雷的信息
	char show[ROWS][COLS] = { 0 };//存放排查出的雷的信息

	//初始化棋盘
	Intboard(mine, ROWS, COLS, '0');
	Intboard(show, ROWS, COLS, '*');

	//打印棋盘
	//Displayboard(mine, ROW, COL);用于检测雷是否正常布置
	Displayboard(show, ROW, COL);

	//布置雷
	Setmine(mine, ROW, COL);
	Displayboard(mine, ROW, COL);//必要时显示雷盘,便于测试

	//排查雷
	Findmine(mine, show, ROW, COL);
}
int main()
{
	srand((unsigned int)time(NULL));
	int input = 0;
	Description();
	do
	{
		menu();
		printf("请选择:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}
	} while (input);
	return 0;
}

二、操作符

 &按2进制位与:同1
 |按2进制位或:同0,或1(有1就输出1)
 ^按2进制位异或:同0,异1
int main()
{
	int a = 3;//补码00000000 00000000 00000000 00000011
	int b = -6;//   10000000 00000000 00000000 00000110—>
	          //补码11111111 11111111 11111111 11111010
	int c = a & b;//00000000 00000000 00000000 00000010
	int d = a | b;//11111111 11111111 11111111 11111011—>101
	int f = a ^ b;//11111111 11111111 11111111 11111001—>111
	printf("c=%d\n", c);
	printf("d=%d\n", d);
	printf("f=%d\n", f);
	return 0;
}

例题:不能创建临时变量,实现两个数的交换

int main()
{
	int a = 3;
	int b = 5;
	printf("a=%d b=%d\n", a, b);
	a = a + b;
	b = a - b;
	a = a - b;
	printf("a=%d b=%d\n", a, b);
	return 0;
}

异或支持交换律

3^3=000->a^a=0
0^5=101=5->0^a=a
3^3^5=5
3^5^3=101=5
int main()
{
	int a = 3;
	int b = 5;
	printf("a=%d b=%d\n", a, b);
	a = a ^ b;//3^5
	b = a ^ b;//3^5^5=3
	a = a ^ b;//3^5^3=5
	printf("a=%d b=%d\n", a, b);
	return 0;
}

求补码二进制中1的个数

int count_ones(int num) {
    int count = 0;
    unsigned int n = num; // 转换为无符号数,确保负数正确处理

    while (n) {
        count += n & 1; // 用位与取最低位(代替 n % 2)
        n >>= 1;        // 用右移一位(代替 n / 2)
    }

    return count;
}

int main() {
    int num;
    printf("请输入一个整数: ");
    scanf("%d", &num);
    printf("%d 的二进制补码中有 %d 个1\n", num, count_ones(num));
    return 0;
}

~二进制取反

int main()
{
	int a = 0;       //00000000 00000000 00000000 00000000
	printf("%d\n", ~a);//11111111 11111111 11111111 11111111—>补码—>原码—>10000000 00000000 00000000 00000001
	int c = 5;
	c <<= 1;//二进制左移1
	printf("%d", ~c);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值