长达22643字的博客:自定义游戏三子棋超详细解说手把手式教学,人机大战,PVP玩家对战功能制作详解

news2024/11/25 12:25:43

    🦒这个游戏相信大家都听过,三子棋,不就是井字棋吗?那么今天我们就来亲手制作一个三子棋游戏,实现人机“智能”大战以及玩家PVP对战。

    🐒三子棋的基本功能构思

    🦒面对一个较大的游戏程序我们要做的第一步并不是抓紧时间上手去敲代码,反而应该放慢自己的节奏仔细思考。思考游戏的设计思路,以及基本的功能,最好可以在草稿上将自己要做的事情用程序框架图表示出来,这样等到我们亲自上手敲代码的时候就会水到渠成了。那么我们先来梳理一下思路,对于我们的三子棋游戏来说,思路主要分为以下几步:

              🐎 STEP 1 : 设计游戏菜单

     🦒游戏菜单的设计可以提醒我们游戏需要具有哪些功能。

              🐎 STEP 2 : 初始化游戏棋盘

     🦒对于我们的三子棋游戏刚开始制作的时候肯定需要打印出来一个棋盘供玩家或者电脑下棋。

              🐎 STEP 3 : 游戏功能函数的封装

     🦒这一步是我们整个游戏设计的主体,将各部分功能封装为一个个密闭的函数,便于调用。

                           🐆功能一:人机对战

                           🐆功能二:PVP玩家对战

                           🐆功能三:游戏说明及技巧提示

    🦒以上就是我们本次设计游戏的整体内容,我们同样也可以根据这些内容进行合理设计程序流程。例如:

                   🐆 针对我们的菜单打印操作自定义一个函数 meun();

                   🐆针对我们的游戏期盼的初始化及打印操作可以设计出函数 BoardInit();                         和BoardPrint();

                   🐆针对玩家操作设计出 Player1Move(); 以及 Player2Move();

                   🐆电脑操作可以封装出一个 ComputerMove();

                   🐆对于我们游戏输赢的判断可以再将其拆解成一个 is_win(); 函数。

    🦒将其设计成思维导图的形式也就是一下形式:

    🦒整理好我们主要的思维逻辑之后就可以进行我们的下一个步骤了——文件的创建。

    🐒文件的创建

    🦒很多小伙伴们可能会说文件创建有什么学的?不是很简单嘛?不,我们在这里说的不是一般的创建,我们需要的不仅仅是一个单独的文件而是三个或者多个文件。不同的文件执行相应的功能,共同协作。就比如我们这次需要创建的 test.c ,game.c,game.h,这三个文件发挥着不同的功能。我们一次解析一下他们各自的功能:

     🐎 test.c文件:

    🦒这个文件当中主要放的是主函数,使用者可以通过这个文件明白游戏大致的进行步骤,但是并不会完全显示个步骤的具体内容。

     🐎 game.c文件:

    🦒这个文件当中进行的步骤主要是函数的实现,也就是 test.c 文件中各部分内容的具体实现。

     🐎 game.h文件:

    🦒我们在 game.h 中进行函数实现之后要想在 test.c 文件当中使用的话就必须引用并创建一个头文件,就像是我们的 game.h 文件一样。只有引用头文件之后才可以使用我们在game.c中制作好的函数,就像是我们再正常程序书写时需要引用头文件一样,只不过我们引用的方式为双引号引用。

    🦒你可能又会想,将这三部分分开创建有什么用呢?

        🦁分开创建文件的优点:

            🐅首先使主调文件 test.c 结构更加清晰,只有我们总结的具体步骤,方便理解                   与观察。

            🐅其次可以增加了函数的隐蔽性,在后期我们还可以对我们的部分文件进行隐                   藏,这样的话就保护了我们自身的知识产权,使利益最大化。

            🐅最后一点就是方便修改,当函数接口不变化时不需要改变客户接口。

    🦒经过了上面的解释之后相信你已经了解了文件创建的重要价值,那么我们就来亲自实践一下。

    🐒正式游戏制作

    🦒当我们创建好三个文件之后可以将我们 test.c 文件拖到右方进行书写,方便我们进行对照以及转换。

    🦒那么我们就要开始我们的第一步了!打印菜单。

            🦓 STEP 1 :打印菜单

        🦒首先在test.c文件中创建一个主函数,为了是我们的主函数内容更加清晰,我们将进一步操作全部封装为 test() 函数放置于test.c文件当中。我们将我们需要用到的所有头文件以及函数声明全部放入 game.h 当中即可。这样就可以在引用 game.h 头文件之后不需要重复进行定义。之后我们需要将我们的程序逻辑完善起来。我们想让我们的程序至少进行一次,那么我们需要使用do_while循环,是我们的游戏在玩过一次之后可以继续进行选择,并利用分支语句 switch 进行选择跳转至开始游戏界面,游戏说明界面,游戏技巧界面,在此步骤我们需要利用printf在 game.c 文件中实现 meun 函数以及 introduction 函数以及 skills 函数,实现之后需要将这部分函数声明放入game.h 头文件中,便于我们 test.c 文件进行使用。

    🦒程序运行效果:

 

    🦒需要特别注意的是:再写一个比较长的程序的过程中一定要边写程序边进行程序的效果验证,观察代码是否存在错误,存在错误需要及时修改,避免一错再错,整个程序写完有几十个错误使得心态爆炸。 

    🦒代码呈现:

//test.c文件
#define _CRT_SECURE_NO_WARNINGS
#include"game.h"

void test()
{
	int input = 0;
	//打印菜单
	do
	{
		meun();
		scanf("%d", &input);
		switch (input)
		{
			case 1:
				printf("开始游戏\n");
				break;
			case 2:
				introduction();
				break;
			case 3:
				skills();
				break;
			case 0:
				break;
			default:
				printf("选择错误,请重新输入。\n");
				break;
		}
	} while (input);
}


int main()
{
	test();
	return 0;
}
//game.h文件    (函数声明)
#define _CRT_SECURE_NO_WARNINGS

#include<stdio.h>
#include<Windows.h>

//打印菜单
void meun();
//游戏介绍
void introduction();
//游戏技巧
void skills();
//game.c文件           (函数的实现)
#define _CRT_SECURE_NO_WARNINGS
#include"game.h"

void meun()
{
	printf("********************************************\n");
	printf("***                                      ***\n");
	printf("***   1.游戏模式         2.游戏说明      ***\n");
	printf("***                                      ***\n");
	printf("***   3.游戏技巧         0.退出游戏      ***\n");
	printf("***                                      ***\n");
	printf("********************************************\n");
}

void introduction()
{
	printf("************************************************\n");
	printf("*** 游戏介绍:                               ***\n");
	printf("***      三子棋是一种民间传统游戏,又叫      ***\n");
	printf("***      九宫棋、圈圈叉叉棋、一条龙、井      ***\n");
	printf("***      字棋等。游戏分为双方对战,双方      ***\n");
	printf("***      依次在9宫格棋盘上摆放棋子,率       ***\n");
	printf("***      先将自己的三个棋子走成一条线就      ***\n");
	printf("***      视为胜利,而对方就算输了,但是      ***\n"); 
	printf("***      三子棋在很多时候会出现和棋的局      ***\n");
	printf("***      面。                                ***\n");
	printf("************************************************\n");
	printf("你有十秒钟的阅读时间\n");
	Sleep(10000);
	system("cls");
}

void skills()
{
	printf("************************************************\n");
	printf("*** 三子棋技巧:                             ***\n");
	printf("***   1、先手:正中间,对面如果走边中间      ***\n");
	printf("***      位置,就落子在紧贴对方棋子的角位置。***\n");
	printf("***                                          ***\n");
	printf("***   2、对方必定堵你,然后你就落子在刚才    ***\n");
	printf("***      自己角位置棋子的旁边,必赢。        ***\n");
	printf("***                                          ***\n");
	printf("***   3、如果对方也会玩,就会先落子在角位    ***\n");
	printf("***      置,基本最后就是和棋。              ***\n");
	printf("***                                          ***\n");
	printf("***   4、后手:对方中间,你就在角位置,然    ***\n");
	printf("***      后堵对方就行,就是和棋。            ***\n");
	printf("************************************************\n");
	printf("你有十秒钟的阅读时间\n");
	Sleep(10000);
	system("cls");
}

                 🦓 STEP 2 :初始化并打印棋盘

    🦒上面的步骤中我们的游戏开始界面只是简单的开始游戏字样,但是我们真是的游戏并不完全是这样的,因此我们将程序完善,将打印字样改为 game() 在 主函数中实现,之后进行游戏棋盘的初始化操作。实现这一步操作的时候我们需要先对我们的棋盘进行分析:

    🦒我们需要对这样一个棋盘进行打印,每一个单位元素(棋子)初始化的棋盘由三个空格组成,我们每一行的分割界限也由三个减号为边界。

    🦒首先我们进行此操作的时候需要先进行棋盘中的元素进行宏定义,方便我们后续对棋盘大小的修改。

    🦒之后创建一个字符型二维数组以我们的ROW(行),COL(列)为数组的元素进行定义数组。

    🦒接下来我们就可以将我们的二维数组,以及行数,列数作为函数参数传给 BoardInit 函数和BoardPrint函数。

    🦒最后将我们的 BoardInit 函数以及BoardPrint函数在 game.h 中声明,在 game.c 中实现。效果如下:

    🦒代码呈现:

//test.c
#define _CRT_SECURE_NO_WARNINGS
#include"game.h"

void game()
{
	char board[ROW][COL];
	//初始化棋盘
	BoardInit(board,ROW,COL);
	//打印棋盘
	BoardPrint(board, ROW, COL);
}

void test()
{
	int input = 0;
	//打印菜单
	do
	{
		meun();
		scanf("%d", &input);
		switch (input)
		{
			case 1:
				game();
				break;
			case 2:
				introduction();
				break;
			case 3:
				skills();
				break;
			case 0:
				break;
			default:
				printf("选择错误,请重新输入。\n");
				break;
		}
	} while (input);
}


int main()
{
	test();
	return 0;
}
//game.h
#define _CRT_SECURE_NO_WARNINGS

#define COL 3  //列
#define ROW 3  //行

#include<stdio.h>
#include<Windows.h>

//打印菜单
void meun();
//游戏介绍
void introduction();
//游戏技巧
void skills();
//棋盘初始化
void BoardInit(char board[ROW][COL],int row,int col);
//棋盘的打印
void BoardPrint(char board[ROW][COL], int row, int col);

 

//game.h
#define _CRT_SECURE_NO_WARNINGS
#include"game.h"

void meun()
{
	printf("********************************************\n");
	printf("***                                      ***\n");
	printf("***   1.游戏模式         2.游戏说明      ***\n");
	printf("***                                      ***\n");
	printf("***   3.游戏技巧         0.退出游戏      ***\n");
	printf("***                                      ***\n");
	printf("********************************************\n");
}

void introduction()
{
	printf("************************************************\n");
	printf("*** 游戏介绍:                               ***\n");
	printf("***      三子棋是一种民间传统游戏,又叫      ***\n");
	printf("***      九宫棋、圈圈叉叉棋、一条龙、井      ***\n");
	printf("***      字棋等。游戏分为双方对战,双方      ***\n");
	printf("***      依次在9宫格棋盘上摆放棋子,率       ***\n");
	printf("***      先将自己的三个棋子走成一条线就      ***\n");
	printf("***      视为胜利,而对方就算输了,但是      ***\n"); 
	printf("***      三子棋在很多时候会出现和棋的局      ***\n");
	printf("***      面。                                ***\n");
	printf("************************************************\n");
	printf("你有十秒钟的阅读时间\n");
	Sleep(10000);
	system("cls");
}

void skills()
{
	printf("************************************************\n");
	printf("*** 三子棋技巧:                             ***\n");
	printf("***   1、先手:正中间,对面如果走边中间      ***\n");
	printf("***      位置,就落子在紧贴对方棋子的角位置。***\n");
	printf("***                                          ***\n");
	printf("***   2、对方必定堵你,然后你就落子在刚才    ***\n");
	printf("***      自己角位置棋子的旁边,必赢。        ***\n");
	printf("***                                          ***\n");
	printf("***   3、如果对方也会玩,就会先落子在角位    ***\n");
	printf("***      置,基本最后就是和棋。              ***\n");
	printf("***                                          ***\n");
	printf("***   4、后手:对方中间,你就在角位置,然    ***\n");
	printf("***      后堵对方就行,就是和棋。            ***\n");
	printf("************************************************\n");
	printf("你有十秒钟的阅读时间\n");
	Sleep(10000);
	system("cls");
}

void BoardInit(char board[ROW][COL], int row, int col)
{
	int i = 0, j = 0;
	for (i = 0; i < ROW; i++)
	{
		for (j = 0; j < COL; j++)
		{
			board[i][j] = ' ';
		}
	}
}

void BoardPrint(char board[ROW][COL], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		int j = 0;
		for (j = 0; j < col; j++)
		{
			printf(" %c ", board[i][j]);
			if (j < col - 1)
				printf("|");
		}
		printf("\n");
		if (i < row - 1)
		{
			//printf("---|---|---\n");
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
					printf("|");
			}
			printf("\n");
		}
	}
}

    🦒经过我们上面的操作已经将棋盘初始化完毕并打印出来了,那么下一步就轮到我们对玩家下棋的程序编写了。 

                 🦓 STEP 3 :玩家1下棋

    🦒这个步骤的核心就是数组元素改写,我们需要对之前初始化为空格的 3*3 数组进行元素改写,以 [ 0 ] [ 0 ] 元素为原点画一个坐标轴,使得玩家只需要输入坐标就可以将棋下到指定的位置。如图:

    🦒当玩家输入坐标之后我们只需要对相应坐标的数组内容进行改写就好了。在我们进行改写操作之后再一次将棋盘进行打印,之后就可以验证我们的思路是否正确了。

    🦒对于这一步操作我们的编码思路是:

          🐅 首先我们需要打印请玩家输入下棋坐标字样,提示玩家下棋。

          🐅 其次在玩家输入坐标之后需要对坐标进行坐标合法性检查,如果坐标不                          合法就得请玩家重新输入坐标,那么这里我们就又需要一个循环语句,                          我们可以将这个内容设置为死循环即while(1)直到玩家输入正确的坐                          标之后才可以跳出循环。

           🐅之后需要做的就是对坐标进行判断坐标是否已经被占用,如果坐标已经                          被占用的话就需要重新输入新的坐标。

    🦒我们将我们上述的操作转换为代码的形式展示给大家:

//test.c
#define _CRT_SECURE_NO_WARNINGS
#include"game.h"

void game()
{
	char board[ROW][COL];
	//初始化棋盘
	BoardInit(board,ROW,COL);
	//打印棋盘
	BoardPrint(board, ROW, COL);
	//玩家下棋
	PlayerMove(board, ROW, COL);
	BoardPrint(board, ROW, COL);
}

void test()
{
	int input = 0;
	//打印菜单
	do
	{
		meun();
		scanf("%d", &input);
		switch (input)
		{
			case 1:
				game();
				break;
			case 2:
				introduction();
				break;
			case 3:
				skills();
				break;
			case 0:
				break;
			default:
				printf("选择错误,请重新输入。\n");
				break;
		}
	} while (input);
}


int main()
{
	test();
	return 0;
}

 

//game.h
#define _CRT_SECURE_NO_WARNINGS

#define COL 3  //列
#define ROW 3  //行

#include<stdio.h>
#include<Windows.h>

//打印菜单
void meun();
//游戏介绍
void introduction();
//游戏技巧
void skills();
//棋盘初始化
void BoardInit(char board[ROW][COL],int row,int col);
//棋盘的打印
void BoardPrint(char board[ROW][COL], int row, int col);
//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col);
//game.c
#define _CRT_SECURE_NO_WARNINGS
#include"game.h"

void meun()
{
	printf("********************************************\n");
	printf("***                                      ***\n");
	printf("***   1.游戏模式         2.游戏说明      ***\n");
	printf("***                                      ***\n");
	printf("***   3.游戏技巧         0.退出游戏      ***\n");
	printf("***                                      ***\n");
	printf("********************************************\n");
}

void introduction()
{
	printf("************************************************\n");
	printf("*** 游戏介绍:                               ***\n");
	printf("***      三子棋是一种民间传统游戏,又叫      ***\n");
	printf("***      九宫棋、圈圈叉叉棋、一条龙、井      ***\n");
	printf("***      字棋等。游戏分为双方对战,双方      ***\n");
	printf("***      依次在9宫格棋盘上摆放棋子,率       ***\n");
	printf("***      先将自己的三个棋子走成一条线就      ***\n");
	printf("***      视为胜利,而对方就算输了,但是      ***\n"); 
	printf("***      三子棋在很多时候会出现和棋的局      ***\n");
	printf("***      面。                                ***\n");
	printf("************************************************\n");
	printf("你有十秒钟的阅读时间\n");
	Sleep(10000);
	system("cls");
}

void skills()
{
	printf("************************************************\n");
	printf("*** 三子棋技巧:                             ***\n");
	printf("***   1、先手:正中间,对面如果走边中间      ***\n");
	printf("***      位置,就落子在紧贴对方棋子的角位置。***\n");
	printf("***                                          ***\n");
	printf("***   2、对方必定堵你,然后你就落子在刚才    ***\n");
	printf("***      自己角位置棋子的旁边,必赢。        ***\n");
	printf("***                                          ***\n");
	printf("***   3、如果对方也会玩,就会先落子在角位    ***\n");
	printf("***      置,基本最后就是和棋。              ***\n");
	printf("***                                          ***\n");
	printf("***   4、后手:对方中间,你就在角位置,然    ***\n");
	printf("***      后堵对方就行,就是和棋。            ***\n");
	printf("************************************************\n");
	printf("你有十秒钟的阅读时间\n");
	Sleep(10000);
	system("cls");
}

void BoardInit(char board[ROW][COL], int row, int col)
{
	int i = 0, j = 0;
	for (i = 0; i < ROW; i++)
	{
		for (j = 0; j < COL; j++)
		{
			board[i][j] = ' ';
		}
	}
}

void BoardPrint(char board[ROW][COL], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		int j = 0;
		for (j = 0; j < col; j++)
		{
			printf(" %c ", board[i][j]);
			if (j < col - 1)
				printf("|");
		}
		printf("\n");
		if (i < row - 1)
		{
			//printf("---|---|---\n");
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
					printf("|");
			}
			printf("\n");
		}
	}
}

void PlayerMove(char board[ROW][COL], int row, int col)
{
	printf("玩家下棋\n");
	while (1)
	{
		printf("请输入要下棋的坐标:>");
		int x = 0;
		int y = 0;
		scanf("%d %d", &x, &y);
		//坐标合法
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (board[x - 1][y - 1] == ' ')
			{
				board[x - 1][y - 1] = '*';
				break;
			}
			else
			{
				printf("该坐标被占用,请重新输入\n");
			}
		}
		else//坐标非法
		{
			printf("坐标非法\n");
		}
	}
}

     🦒上面就是我们玩家下棋的执行操作了,那么下一步我们需要做的就是让电脑进行下棋。

                 🦓 STEP 4 :电脑下棋

    🦒还记得我们之前设计过的猜数字游戏吗?其实这个电脑下棋的思路和那个随机生成数字很相似,我们需要做的操作只是随机生成两个数字取模上我们的行和列之后就会得到一个坐标,这个就是我们电脑将要下棋的位置。同样的道理,我们需要对电脑下棋的坐标进行判断,检查所要修改的坐标上是否已经被下过棋了,如果下过就重新生成两个随机数,直到找到合适坐标位置。由于思路和上面的玩家下棋很相似我们就不多讲了,直接展示我们代码的运行效果并呈现我们的代码。

 

//test.c
#define _CRT_SECURE_NO_WARNINGS
#include"game.h"

void game()
{
	char board[ROW][COL];
	//初始化棋盘
	BoardInit(board,ROW,COL);
	//打印棋盘
	BoardPrint(board, ROW, COL);
	//玩家下棋
	PlayerMove(board, ROW, COL);
	BoardPrint(board, ROW, COL);
	//电脑下棋
	ComputerMove(board, ROW, COL);
	BoardPrint(board, ROW, COL);
}

void test()
{
	int input = 0;
	//打印菜单
	do
	{
		meun();
		scanf("%d", &input);
		switch (input)
		{
			case 1:
				game();
				break;
			case 2:
				introduction();
				break;
			case 3:
				skills();
				break;
			case 0:
				break;
			default:
				printf("选择错误,请重新输入。\n");
				break;
		}
	} while (input);
}


int main()
{
	test();
	return 0;
}

 

//game.h
#define _CRT_SECURE_NO_WARNINGS

#define COL 3  //列
#define ROW 3  //行

#include<stdio.h>
#include<Windows.h>

//打印菜单
void meun();
//游戏介绍
void introduction();
//游戏技巧
void skills();
//棋盘初始化
void BoardInit(char board[ROW][COL],int row,int col);
//棋盘的打印
void BoardPrint(char board[ROW][COL], int row, int col);
//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col);
//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col);
#define _CRT_SECURE_NO_WARNINGS
#include"game.h"

void meun()
{
	printf("********************************************\n");
	printf("***                                      ***\n");
	printf("***   1.游戏模式         2.游戏说明      ***\n");
	printf("***                                      ***\n");
	printf("***   3.游戏技巧         0.退出游戏      ***\n");
	printf("***                                      ***\n");
	printf("********************************************\n");
}

void introduction()
{
	printf("************************************************\n");
	printf("*** 游戏介绍:                               ***\n");
	printf("***      三子棋是一种民间传统游戏,又叫      ***\n");
	printf("***      九宫棋、圈圈叉叉棋、一条龙、井      ***\n");
	printf("***      字棋等。游戏分为双方对战,双方      ***\n");
	printf("***      依次在9宫格棋盘上摆放棋子,率       ***\n");
	printf("***      先将自己的三个棋子走成一条线就      ***\n");
	printf("***      视为胜利,而对方就算输了,但是      ***\n"); 
	printf("***      三子棋在很多时候会出现和棋的局      ***\n");
	printf("***      面。                                ***\n");
	printf("************************************************\n");
	printf("你有十秒钟的阅读时间\n");
	Sleep(10000);
	system("cls");
}

void skills()
{
	printf("************************************************\n");
	printf("*** 三子棋技巧:                             ***\n");
	printf("***   1、先手:正中间,对面如果走边中间      ***\n");
	printf("***      位置,就落子在紧贴对方棋子的角位置。***\n");
	printf("***                                          ***\n");
	printf("***   2、对方必定堵你,然后你就落子在刚才    ***\n");
	printf("***      自己角位置棋子的旁边,必赢。        ***\n");
	printf("***                                          ***\n");
	printf("***   3、如果对方也会玩,就会先落子在角位    ***\n");
	printf("***      置,基本最后就是和棋。              ***\n");
	printf("***                                          ***\n");
	printf("***   4、后手:对方中间,你就在角位置,然    ***\n");
	printf("***      后堵对方就行,就是和棋。            ***\n");
	printf("************************************************\n");
	printf("你有十秒钟的阅读时间\n");
	Sleep(10000);
	system("cls");
}

void BoardInit(char board[ROW][COL], int row, int col)
{
	int i = 0, j = 0;
	for (i = 0; i < ROW; i++)
	{
		for (j = 0; j < COL; j++)
		{
			board[i][j] = ' ';
		}
	}
}

void BoardPrint(char board[ROW][COL], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		int j = 0;
		for (j = 0; j < col; j++)
		{
			printf(" %c ", board[i][j]);
			if (j < col - 1)
				printf("|");
		}
		printf("\n");
		if (i < row - 1)
		{
			//printf("---|---|---\n");
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
					printf("|");
			}
			printf("\n");
		}
	}
}

void PlayerMove(char board[ROW][COL], int row, int col)
{
	printf("玩家下棋\n");
	while (1)
	{
		printf("请输入要下棋的坐标:>");
		int x = 0;
		int y = 0;
		scanf("%d %d", &x, &y);
		//坐标合法
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (board[x - 1][y - 1] == ' ')
			{
				board[x - 1][y - 1] = '*';
				break;
			}
			else
			{
				printf("该坐标被占用,请重新输入\n");
			}
		}
		else//坐标非法
		{
			printf("坐标非法\n");
		}
	}
}

void ComputerMove(char board[ROW][COL], int row, int col)
{
	//电脑下棋
//随机生成坐标,只要坐标没有被占用,就下棋
		printf("电脑下棋:\n");
		while (1)
		{
			int x = rand() % row;
			int y = rand() % col;

			if (board[x][y] == ' ')
			{
				board[x][y] = '#';
				break;
			}
		}
}

    🦒在这一步我们需要进行一个额外的操作就是对玩家和电脑下棋进行重复操作直到出现胜者或平局为止,因此我们需要将玩家下棋和电脑下棋操作放到一个循环中,符合条件就跳出循环,这个改变在我们后面的代码中进行体现。

                 🦓 STEP 5 :判断输赢

    🦒对于我们的人机对战的部分判断输赢就是最后一个操作步骤了。那么我们应该怎样书写我们的 is_win 函数呢?我们可以通过 is_win 函数的返回值来判断,

    🦒将 is_win 函数的返回值设置成字符类型,判断三行或者三列或者对角线当中的符号相等(除空格外)如果相等的话就返回当前的字符,判断是电脑获胜了还是玩家获胜了。

    🦒在这个函数中我们还需要判断平局的情况也就是棋盘是否满了,并且找不到任何一方获胜。那么就返回一个 Q 字符给出系统提示游戏平局。否则游戏就继续。我们在这里将判断棋盘是否放满操作单独列出封装成为一个函数。

    🦒那么将上述的内容化作代码的形式也就是下面的情况:

//test.c
#define _CRT_SECURE_NO_WARNINGS
#include"game.h"

void game()
{
	char ret = 0;
	char board[ROW][COL];
	//初始化棋盘
	BoardInit(board,ROW,COL);
	//打印棋盘
	BoardPrint(board, ROW, COL);
	while (1)
	{
		//玩家下棋
		PlayerMove(board, ROW, COL);
		BoardPrint(board, ROW, COL);
		//判断输赢
		ret = is_win(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
		//电脑下棋
		ComputerMove(board, ROW, COL);
		BoardPrint(board, ROW, COL);
		//判断输赢
		ret = is_win(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
	}
	if (ret == '#')
		printf("电脑赢了\n");
	else if (ret == '*')
		printf("玩家赢了\n");
	else if (ret == 'Q')
		printf("平局\n");
}

void test()
{
	int input = 0;
	//打印菜单
	do
	{
		meun();
		scanf("%d", &input);
		switch (input)
		{
			case 1:
				game();
				break;
			case 2:
				introduction();
				break;
			case 3:
				skills();
				break;
			case 0:
				break;
			default:
				printf("选择错误,请重新输入。\n");
				break;
		}
	} while (input);
}


int main()
{
	test();
	return 0;
}

 

//game.h

#define _CRT_SECURE_NO_WARNINGS

#define COL 3  //列
#define ROW 3  //行

#include<stdio.h>
#include<Windows.h>

//打印菜单
void meun();
//游戏介绍
void introduction();
//游戏技巧
void skills();
//棋盘初始化
void BoardInit(char board[ROW][COL],int row,int col);
//棋盘的打印
void BoardPrint(char board[ROW][COL], int row, int col);
//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col);
//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col);

 

//game.c
#define _CRT_SECURE_NO_WARNINGS
#include"game.h"

void meun()
{
	printf("********************************************\n");
	printf("***                                      ***\n");
	printf("***   1.游戏模式         2.游戏说明      ***\n");
	printf("***                                      ***\n");
	printf("***   3.游戏技巧         0.退出游戏      ***\n");
	printf("***                                      ***\n");
	printf("********************************************\n");
}

void introduction()
{
	printf("************************************************\n");
	printf("*** 游戏介绍:                               ***\n");
	printf("***      三子棋是一种民间传统游戏,又叫      ***\n");
	printf("***      九宫棋、圈圈叉叉棋、一条龙、井      ***\n");
	printf("***      字棋等。游戏分为双方对战,双方      ***\n");
	printf("***      依次在9宫格棋盘上摆放棋子,率       ***\n");
	printf("***      先将自己的三个棋子走成一条线就      ***\n");
	printf("***      视为胜利,而对方就算输了,但是      ***\n"); 
	printf("***      三子棋在很多时候会出现和棋的局      ***\n");
	printf("***      面。                                ***\n");
	printf("************************************************\n");
	printf("你有十秒钟的阅读时间\n");
	Sleep(10000);
	system("cls");
}

void skills()
{
	printf("************************************************\n");
	printf("*** 三子棋技巧:                             ***\n");
	printf("***   1、先手:正中间,对面如果走边中间      ***\n");
	printf("***      位置,就落子在紧贴对方棋子的角位置。***\n");
	printf("***                                          ***\n");
	printf("***   2、对方必定堵你,然后你就落子在刚才    ***\n");
	printf("***      自己角位置棋子的旁边,必赢。        ***\n");
	printf("***                                          ***\n");
	printf("***   3、如果对方也会玩,就会先落子在角位    ***\n");
	printf("***      置,基本最后就是和棋。              ***\n");
	printf("***                                          ***\n");
	printf("***   4、后手:对方中间,你就在角位置,然    ***\n");
	printf("***      后堵对方就行,就是和棋。            ***\n");
	printf("************************************************\n");
	printf("你有十秒钟的阅读时间\n");
	Sleep(10000);
	system("cls");
}

void BoardInit(char board[ROW][COL], int row, int col)
{
	int i = 0, j = 0;
	for (i = 0; i < ROW; i++)
	{
		for (j = 0; j < COL; j++)
		{
			board[i][j] = ' ';
		}
	}
}

void BoardPrint(char board[ROW][COL], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		int j = 0;
		for (j = 0; j < col; j++)
		{
			printf(" %c ", board[i][j]);
			if (j < col - 1)
				printf("|");
		}
		printf("\n");
		if (i < row - 1)
		{
			//printf("---|---|---\n");
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
					printf("|");
			}
			printf("\n");
		}
	}
}

void PlayerMove(char board[ROW][COL], int row, int col)
{
	printf("玩家下棋\n");
	while (1)
	{
		printf("请输入要下棋的坐标:>");
		int x = 0;
		int y = 0;
		scanf("%d %d", &x, &y);
		//坐标合法
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (board[x - 1][y - 1] == ' ')
			{
				board[x - 1][y - 1] = '*';
				break;
			}
			else
			{
				printf("该坐标被占用,请重新输入\n");
			}
		}
		else//坐标非法
		{
			printf("坐标非法\n");
		}
	}
}

void ComputerMove(char board[ROW][COL], int row, int col)
{
	//电脑下棋
//随机生成坐标,只要坐标没有被占用,就下棋
		printf("电脑下棋:\n");
		while (1)
		{
			int x = rand() % row;
			int y = rand() % col;

			if (board[x][y] == ' ')
			{
				board[x][y] = '#';
				break;
			}
		}
}

//判断棋盘是否满了
static int is_full(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			if (board[i][j] == ' ')
				return 0;
		}
	}
	return 1;
}

char is_win(char board[ROW][COL], int row, int col)
{
	int i = 0;
	//判断三行
	for (i = 0; i < row; i++)
	{
		if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')
		{
			return board[i][0];
		}
	}
	//判断三列
	for (i = 0; i < col; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
		{
			return board[0][i];
		}
	}
	//对角线
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
	{
		return board[1][1];
	}
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
	{
		return board[1][1];
	}

	//平局?
	if (is_full(board, row, col) == 1)
	{
		return 'Q';
	}

	//继续
	//没有玩家或者电脑赢,也没有平局,游戏继续
	return 'C';
}

    🦒上面就是我们人机对战的所有代码,那么我们接下来实现我们的另一个功能,PVP玩家对战。 

                 🦓 STEP 6 :PVP对战

    🦒对于这一部分我们只需要给我们上面已经完成的代码重新增添一点新的内容就可以了。我们需要做的是当我们选择游戏模式的时候可以跳出一个选择选项,可以让我们选择是人机对战还是PVP对战,那么我们只需要更改我们主函数的最后循环玩家和电脑轮流下棋的步骤即可。我们玩家2的下棋代码可以直接套用我们之前设计好的玩家1的下棋运行代码,只需要将我们的标志改为 # 即可。那么就来看一下我们的运行成果吧!

    🦒代码呈现:

//test.c
#define _CRT_SECURE_NO_WARNINGS
#include"game.h"

void game()
{
	meun1();
	char ret = 0;
	int choice = 0;
	scanf("%d", &choice);
	char board[ROW][COL];
	//初始化棋盘
	BoardInit(board,ROW,COL);
	//打印棋盘
	BoardPrint(board, ROW, COL);
	if (choice == 2)
	{
		while (1)
		{
			//玩家下棋
			PlayerMove(board, ROW, COL);
			BoardPrint(board, ROW, COL);
			//判断输赢
			ret = is_win(board, ROW, COL);
			if (ret != 'C')
			{
				break;
			}
			//电脑下棋
			ComputerMove(board, ROW, COL);
			BoardPrint(board, ROW, COL);
			//判断输赢
			ret = is_win(board, ROW, COL);
			if (ret != 'C')
			{
				break;
			}
		}
		if (ret == '#')
			printf("电脑赢了\n");
		else if (ret == '*')
			printf("玩家赢了\n");
		else if (ret == 'Q')
			printf("平局\n");
	}
	else
	{
		while (1)
		{
			//玩家下棋
			PlayerMove(board, ROW, COL);
			BoardPrint(board, ROW, COL);
			//判断输赢
			ret = is_win(board, ROW, COL);
			if (ret != 'C')
			{
				break;
			}
			//玩家2下棋
			Player2Move(board, ROW, COL);
			BoardPrint(board, ROW, COL);
			//判断输赢
			ret = is_win(board, ROW, COL);
			if (ret != 'C')
			{
				break;
			}
		}
		if (ret == '#')
			printf("玩家2赢了\n");
		else if (ret == '*')
			printf("玩家1赢了\n");
		else if (ret == 'Q')
			printf("平局\n");
	}
}

void test()
{
	int input = 0;
	//打印菜单
	do
	{
		meun();
		scanf("%d", &input);
		switch (input)
		{
			case 1:
				game();
				break;
			case 2:
				introduction();
				break;
			case 3:
				skills();
				break;
			case 0:
				break;
			default:
				printf("选择错误,请重新输入。\n");
				break;
		}
	} while (input);
}


int main()
{
	test();
	return 0;
}
//game.h
#define _CRT_SECURE_NO_WARNINGS

#define COL 3  //列
#define ROW 3  //行

#include<stdio.h>
#include<Windows.h>

//打印菜单
void meun();

//选择对战模式
void meun1();

//游戏介绍
void introduction();
//游戏技巧
void skills();
//棋盘初始化
void BoardInit(char board[ROW][COL],int row,int col);
//棋盘的打印
void BoardPrint(char board[ROW][COL], int row, int col);
//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col);
//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col);

//玩家2下棋
void Player2Move(char board[ROW][COL], int row, int col);
//game.c
#define _CRT_SECURE_NO_WARNINGS
#include"game.h"

void meun()
{
	printf("********************************************\n");
	printf("***                                      ***\n");
	printf("***   1.游戏模式         2.游戏说明      ***\n");
	printf("***                                      ***\n");
	printf("***   3.游戏技巧         0.退出游戏      ***\n");
	printf("***                                      ***\n");
	printf("********************************************\n");
}

void meun1()
{
	printf("********************************\n");
	printf("**        1. PVP玩家对战      **\n");
	printf("**        2. 人机对战         **\n");
	printf("********************************\n");
}

void introduction()
{
	printf("************************************************\n");
	printf("*** 游戏介绍:                               ***\n");
	printf("***      三子棋是一种民间传统游戏,又叫      ***\n");
	printf("***      九宫棋、圈圈叉叉棋、一条龙、井      ***\n");
	printf("***      字棋等。游戏分为双方对战,双方      ***\n");
	printf("***      依次在9宫格棋盘上摆放棋子,率       ***\n");
	printf("***      先将自己的三个棋子走成一条线就      ***\n");
	printf("***      视为胜利,而对方就算输了,但是      ***\n"); 
	printf("***      三子棋在很多时候会出现和棋的局      ***\n");
	printf("***      面。                                ***\n");
	printf("************************************************\n");
	printf("你有十秒钟的阅读时间\n");
	Sleep(10000);
	system("cls");
}

void skills()
{
	printf("************************************************\n");
	printf("*** 三子棋技巧:                             ***\n");
	printf("***   1、先手:正中间,对面如果走边中间      ***\n");
	printf("***      位置,就落子在紧贴对方棋子的角位置。***\n");
	printf("***                                          ***\n");
	printf("***   2、对方必定堵你,然后你就落子在刚才    ***\n");
	printf("***      自己角位置棋子的旁边,必赢。        ***\n");
	printf("***                                          ***\n");
	printf("***   3、如果对方也会玩,就会先落子在角位    ***\n");
	printf("***      置,基本最后就是和棋。              ***\n");
	printf("***                                          ***\n");
	printf("***   4、后手:对方中间,你就在角位置,然    ***\n");
	printf("***      后堵对方就行,就是和棋。            ***\n");
	printf("************************************************\n");
	printf("你有十秒钟的阅读时间\n");
	Sleep(10000);
	system("cls");
}

void BoardInit(char board[ROW][COL], int row, int col)
{
	int i = 0, j = 0;
	for (i = 0; i < ROW; i++)
	{
		for (j = 0; j < COL; j++)
		{
			board[i][j] = ' ';
		}
	}
}

void BoardPrint(char board[ROW][COL], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		int j = 0;
		for (j = 0; j < col; j++)
		{
			printf(" %c ", board[i][j]);
			if (j < col - 1)
				printf("|");
		}
		printf("\n");
		if (i < row - 1)
		{
			//printf("---|---|---\n");
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
					printf("|");
			}
			printf("\n");
		}
	}
}

void PlayerMove(char board[ROW][COL], int row, int col)
{
	printf("玩家1下棋\n");
	while (1)
	{
		printf("请输入要下棋的坐标:>");
		int x = 0;
		int y = 0;
		scanf("%d %d", &x, &y);
		//坐标合法
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (board[x - 1][y - 1] == ' ')
			{
				board[x - 1][y - 1] = '*';
				break;
			}
			else
			{
				printf("该坐标被占用,请重新输入\n");
			}
		}
		else//坐标非法
		{
			printf("坐标非法\n");
		}
	}
}

void ComputerMove(char board[ROW][COL], int row, int col)
{
	//电脑下棋
//随机生成坐标,只要坐标没有被占用,就下棋
		printf("电脑下棋:\n");
		while (1)
		{
			int x = rand() % row;
			int y = rand() % col;

			if (board[x][y] == ' ')
			{
				board[x][y] = '#';
				break;
			}
		}
}

//判断棋盘是否满了
static int is_full(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			if (board[i][j] == ' ')
				return 0;
		}
	}
	return 1;
}

char is_win(char board[ROW][COL], int row, int col)
{
	int i = 0;
	//判断三行
	for (i = 0; i < row; i++)
	{
		if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')
		{
			return board[i][0];
		}
	}
	//判断三列
	for (i = 0; i < col; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
		{
			return board[0][i];
		}
	}
	//对角线
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
	{
		return board[1][1];
	}
	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
	{
		return board[1][1];
	}

	//平局?
	if (is_full(board, row, col) == 1)
	{
		return 'Q';
	}

	//继续
	//没有玩家或者电脑赢,也没有平局,游戏继续
	return 'C';
}

void Player2Move(char board[ROW][COL], int row, int col)
{
	printf("玩家2下棋\n");
	while (1)
	{
		printf("请输入要下棋的坐标:>");
		int x = 0;
		int y = 0;
		scanf("%d %d", &x, &y);
		//坐标合法
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (board[x - 1][y - 1] == ' ')
			{
				board[x - 1][y - 1] = '#';
				break;
			}
			else
			{
				printf("该坐标被占用,请重新输入\n");
			}
		}
		else//坐标非法
		{
			printf("坐标非法\n");
		}
	}
}

    🦒上面就是我们本次博客的全部内容了,相信一定可以帮到大家吧!感谢大家的观看,祝大家天天开心。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/102104.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

(附源码)Springboot社区疫情防控管理系统 毕业设计 164621

Springboot 社区疫情防控管理系统 摘 要 信息化社会内需要与之针对性的信息获取途径&#xff0c;但是途径的扩展基本上为人们所努力的方向&#xff0c;由于站在的角度存在偏差&#xff0c;人们经常能够获得不同类型信息&#xff0c;这也是技术最为难以攻克的课题。针对社区疫情…

校园生活互助网站

开发工具(eclipse/idea/vscode等)&#xff1a; 数据库(sqlite/mysql/sqlserver等)&#xff1a; 功能模块(请用文字描述&#xff0c;至少200字)&#xff1a; 体智慧校园生活互助系统主要实现以下功能&#xff1a; (一)网站前台&#xff1a;关于我们、联系我们、公告信息、求助信…

DataGear 添加 Http 数据集是请求头 JSON 的格式说明

背景 玩了一下 DataGear &#xff0c;添加了一个 Http 接口的数据集&#xff0c;由于目标接口请求必须包含 Token 信息&#xff0c;所以按照配置提示添加 JSON 格式的头信息时&#xff0c;想象成了 JSON 对象&#xff0c;结果预览请求始终报错。 DataGear 的后台异常信息&…

【JUC】JMM内存模型

JMM是什么 JMM是Java内存模型&#xff0c;也就是Java Memory Model&#xff0c;简称JMM&#xff0c;本身是一种抽象的概念,并不真实存在&#xff0c;它描述的是一组规则或规范&#xff0c;通过这组规范定义了程序中各个变量&#xff08;包括实例字段&#xff0c;静态字段和构成…

Graphviz 排版思路 Graphviz 如何控制节点位置

有个画图需求是需要生成特定排版的关系图。 graphviz 对于一般情况都是自动排的&#xff0c;有时候会抽风&#xff0c;比如这种情况&#xff1a; 而我们想要这样&#xff1a; 对初学者提一下 &#xff0c;如何实现 3 2 5 &#xff0c;1467 从左到右排列呢&#xff1f;待会会顺…

HTML小游戏18 —— html5版街头霸王游戏(附完整源码)

&#x1f482; 网站推荐:【神级源码资源网】【摸鱼小游戏】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 想寻找共同学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】&#x1f4ac; 免费且实用的计…

【Three.js】Three.js快速上手教程

1. Three.js简介 官网对 Three.js 的介绍非常简单&#xff1a;“Javascript 3D library”。 即&#xff1a;three.js是JavaScript编写的WebGL第三方库。提供了非常多的3D显示功能&#xff0c;是一个常见的web 3D库。 相关概念解释&#xff1a;three.js > webGL > openG…

QT QTabWidget 控件 使用详解

本文详细的介绍了QTabWidget控件的各种操作&#xff0c;例如&#xff1a;新建界面、设置页面名字、设置提示信息、设置页面激活、设置标题栏位置、设置页面关闭按钮、设置页面关闭按钮、获取页面下标、获取页面总数、清空所有页面、删除某个页面、设置拖拽移动、设置显示页面、…

全国职业技能大赛网络安全-金砖技能大赛——应急响应内存镜像分析(超详细解析)

全国职业技能大赛网络安全-金砖技能大赛——应急响应内存镜像分析&#xff08;超详细解析&#xff09; 背景&#xff1a;作为信息安全技术人员必须能够掌握内容镜像分析、重要数据恢复、 恶意文件分析等相关技能&#xff0c;利用这些技能我们能够第一时间分析相关恶意文件、 分…

美少女怒肝20天用C语言写出的排序集合

文章目录 排序的概念一、常见的排序算法二、代码实现总结排序的概念 排序&#xff1a;所谓排序&#xff0c;就是使一串记录&#xff0c;按照其中的某个或某些关键字的大小&#xff0c;递增或递减的排列起来的操作。稳定性&#xff1a;假定在待排序的记录序列中&#xff0c;存在…

作为前端,你是否了解链表这种数据结构?

在面试中只要被问到React Hooks就常被问到为什么Hooks不能在循环和条件判断嵌套函数当中使用&#xff1b;相信很多人都知道标准答案&#xff0c;【因为声明的Hooks保存在链表当中】&#xff0c;但是你真的知道链表吗&#xff1f; 什么是链表 我们先看来看一个简单的单向链表结…

华为珍藏版:SpringBoot全优笔记,面面俱到太全了

前言 作为开发人员&#xff0c;对于Spring全家桶肯定是不陌生的&#xff0c;而来自于Spring大家族的Spring Boot&#xff0c;作为Spring团队提供的流行框架&#xff0c;它的存在解决的Spring框架使用较为繁琐的问题&#xff0c;所以掌握SpringBoot是精通Spring必不可少的一个过…

[附源码]Python计算机毕业设计Django血库管理系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

[附源码]计算机毕业设计Node.js-Bigbaby美食网站(程序+LW)

项目运行 环境配置&#xff1a; Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境&#xff1a;最好是Nodejs最新版&#xff0c;我…

《Go语言并发之道》读书笔记

《Go语言并发之道》第一章&#xff1a; 并发概述第二章&#xff1a;对你的代码建模&#xff1a;通信顺序进程第三章&#xff1a;GO语言并发组件由于不怎么熟悉GO&#xff0c;只做简单的摘录&#xff0c;敲敲示例代码 鸭子类型&#xff1a;当看到一只鸟走起来像鸭子、游泳起来像…

微服务框架 SpringCloud微服务架构 多级缓存 49 缓存同步 49.3 监听Canal

微服务框架 【SpringCloudRabbitMQDockerRedis搜索分布式&#xff0c;系统详解springcloud微服务技术栈课程|黑马程序员Java微服务】 多级缓存 文章目录微服务框架多级缓存49 缓存同步49.3 监听Canal49.3.1 Canal 客户端49 缓存同步 49.3 监听Canal 49.3.1 Canal 客户端 C…

深耕无线通讯细分领域 可信华成产品受市场青睐

深圳市可信华成通信科技有限公司&#xff08;以下简称可信华成&#xff09;&#xff0c;成立于2010年&#xff0c;是一家在无线通信领域中崛起的集研发、智能制造、销售为一体的国家高新技术企业&#xff0c;深圳市专精特新企业&#xff1b; 注册资金2200万元&#xff0c;员工8…

【图像压缩】余弦变换及霍夫曼编码jpeg压缩和解压【含Matlab源码 2086期】

⛄一、DCT图像无损压缩简介 1 图像压缩 图像压缩按照压缩过程中是否有信息的损失以及解压后与原始图像是否有误差可以分为无损压缩和有损压缩两大类。无损压缩是指不损失图像质量的压缩&#xff0c;它是对文件的存储方式进行优化&#xff0c;采用某种算法表示重复的数据信息&a…

网络安全——【收藏】网络设备安全加固规范

一、Cisco网络设备安全基线规范 本建议用于Cisco路由器和基于Cisco IOS的交换机及其三层处理模块&#xff0c;其软件版本为CISCO IOS 12.0及以上版本。加固前应该先备份系统配置文件。 01 账号管理、认证授权 1.1.本机认证和授权 初始模式下&#xff0c;设备内一般建有没有…

Linux——用户、组的管理以及文件的权限设置

一、用户和组 Linux系统中的用户唯一的标识码为用户ID&#xff0c;即UID&#xff0c;每个用户至少属于一个组&#xff0c;即为用户分组。用户分组存在唯一的标识码&#xff0c;为GID。不同的用户拥有不同的权限。 1&#xff0e;认识用户账号文件/etc/passwd和用户影子文件/et…