C语言三子棋小游戏--数组的应用

注:在最后面,完整源码会以两种形式展现。在讲解时,以三个源文件的形式。


前言:三子棋,顾名思义,就是三个子连在一起就可以胜出。在本节我们要介绍的三子棋模式是这样子的:在键盘输入坐标(表示落子),和电脑对下(当前电脑设计为随机下)。

我们先看游戏执行起来的样子:

全局思路:下棋肯定需要一个棋盘,不然会显得杂乱无章;当有了棋盘之后,就需要落子,落子需要双方,一个是我们自己(手动下)另一个就是电脑(设置自动下);当每一次落子,都需要判断是否输赢,否则重复落子步骤(循环);而判断输赢也作为一块内容。因为作为小游戏,肯定需要一个游戏菜单

思路简图:设置菜单------>设置棋盘------->(玩家落子--->电脑落子)------>判断输赢

三子棋流程图:


上面是铺垫,接下来才是重头戏,该上强度了。

一、准备工作和游戏菜单

在第一个源文件(test.c)和头文件(game.h)中实现

1.准备工作

(1)建立两个源文件和一个头文件

目的:方便观察和日后的工作(不展开) 

(2)建立三个文件的联系(大致雏形)

     上面的信息大致可以让我们知道每个文件大致要存放的内容,关于引用头文件这些知识不是我们现阶段需要明白的,只需记住这样用就行。

2.游戏菜单

(1)菜单的模板

void menu()//菜单函数
{printf("####################\n");printf("###### 1.play ######\n");printf("###### 0.exit ######\n");printf("####################\n");
}
int main()
{int input = 0;do//循环菜单{menu();printf("请选择>:");scanf("%d",&input);} while (input);return 0;
}

运行结果:

1.我们把菜单封装成一个函数,放在第一个源文件中。

2.当调用完菜单之后,会有两个选择,这个时候就需要输入数据,这就需要用到scanf函数。

3.因为当结束一局游戏后,会再次出现菜单让我们选择继续与否,所以要用到do…while循环,因为这样至少会执行一次菜单。

 (2)输入数据后的选择与判断

    当我们用scanf函数输入数据后,就需要根据输入的数据选择不同的路径。

void menu()//菜单函数
{printf("####################\n");printf("###### 1.play ######\n");printf("###### 0.exit ######\n");printf("####################\n");
}
int main()
{int input = 0;do//循环菜单{menu();printf("请选择>:");scanf("%d",&input);switch (input)//用switch来判断选择{case 1:printf("你已选择继续游戏\n");break;case 0:printf("你已选择退出游戏\n");break;default:printf("选择错误,重新选择\n");//防止乱选}} while (input);return 0;
}

运行结果:

选择1:

 选择0:

 选择其他:

 根据输入数据的选择,我们就需要用到switch函数来判断。

 (3)继续游戏后的选择

 为了选择1之后就直接可以进入游戏,所以我们在后面直接跟上game函数,然后在game中函数调用各种函数接口。

void menu()//菜单函数
{printf("####################\n");printf("###### 1.play ######\n");printf("###### 0.exit ######\n");printf("####################\n");
}
void game()
{char board[ROW][COL];InitBoard(board,ROW,COL);//初始化棋盘DisplayBoard(board,ROW,COL);//打印棋盘//落子循环
}
int main()
{int input = 0;do//循环菜单{menu();printf("请选择>:");scanf("%d",&input);switch (input){case 1:printf("你已选择继续游戏\n");game();break;case 0:printf("你已选择退出游戏\n");break;default:printf("选择错误,重新选择\n");}} while (input);return 0;
}
#include<stdio.h>#define ROW 3
#define COL 3
//头文件放函数声明
//初始化函数
void InitBoard(char board[ROW][COL],int row,int col);
//打印函数
void DisplayBoard(char board[ROW][COL],int row,int col);

在我们的game函数内,放的是一些接口,功能暂未实现。

我们需要用到二维数组,然后它的行和列需要用到宏定义的常量。如果后续需要更改棋盘的大小也会很方便。

接下来我们再一一实现每个函数的功能吧

二、初始化和打印棋盘

在第二个源文件(game.c)中实现函数体内部的功能。

1.初始化棋盘

//初始化函数
InitBoard(board,ROW,COL);

初始化,因为刚开始的棋盘是空的,只需要全部赋值成空格就好。

//初始化棋盘
void InitBoard(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++){board[i][j] = ' ';//全部初始化成空格}}
}

我们可以通过调试窗口中的监视观察数组是否被成功赋值。

知识点:二维数组赋值

2.打印棋盘

//打印棋盘函数
DisplayBoard(board,ROW,COL);

如果直接将初始化好的字符数组打印出来,是看不见的,但是呢,我们可以先将空格换成其他可以看见的符号,从而可以检验我们的“打印棋盘函数”是否写对了。

要想打印出下面的这个棋盘该怎么做呢?

 这是一个九宫格,其实这个棋盘有五行五列。第一行是空格和竖线组成,第二行是横线和竖线组成组成,后面同理。

我们可以有很多种方式打印,我们列举一种

1.我们可以一行一行的打印出来,打印完一行就换行。

2.竖线有两行,横线也只有两行,他们只能打印两次。

3.数组打印三行三列,横线打印两行,竖线打印两行。

打印棋盘函数:

//打印棋盘
void DisplayBoard(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){for (j = 0; j < col; j++){printf("---");if (j < col - 1)printf("|");}}printf("\n");}
}

运行结果:

    第一层循环,控制行;那不是五行吗?为什么这里只循环三次,因为有第二层循环的控制。

总结:第一次循环(第一层):打印三次空格和两个竖线(第二层循环),第二层循环没有结束,继续换行打印横线和竖线;这里需要注意:每一行需要打印三次横线(第二次循环必须循环三次),但是只打印两横(第一层循环只能打印两次);而每一行只打印两次竖线,并且只打印两行。

三、玩家与电脑的落子

1.玩家落子(*)

因为我们所输入的坐标是从1开始,而数组的下标是从0开始,所以需要区别

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

总结:落子时,考虑位置是否合法,坐标是否被占,否则重新循环,最后再落子,落子完成再退出循环。

知识点:选择语句的条件判断与数字下标的运用

2.电脑落子(#)

电脑落子,则是需要随机产生数字作为坐标再落子,所以我们需要用到产生随机数的知识点。

生成随机数:

#include<stdlib.h>//srand所需头文件
#include<time.h>//time所需头文件
srand((unsigned)time(NULL));
int x=rand();//此时,x中的值就是随机值

其中srand函数和rand函数是配合使用的。

srand函数只需要在主函数中提到一次,srand函数中的参数设为时间,返回一个NULL,并强制类型转化。我们当前只需要计熟这句话就行。

然后我们就可以使用rand函数来产生随机数了,只需要用变量来接收即可。

当前头文件:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>#define ROW 3
#define COL 3//初始化函数
void InitBoard(char board[ROW][COL],int row,int col);
//打印函数
void DisplayBoard(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);

当前源文件(test.c):

#include"game.h"
void menu()//菜单函数
{printf("####################\n");printf("###### 1.play ######\n");printf("###### 0.exit ######\n");printf("####################\n");
}
void game()
{char ret = 0;char board[ROW][COL];InitBoard(board,ROW,COL);//初始化棋盘DisplayBoard(board,ROW,COL);//打印棋盘PlayerMove(board, ROW, COL);DisplayBoard(board, ROW, COL);//打印棋盘ComputerMove(board,ROW,COL);DisplayBoard(board, ROW, COL);//打印棋盘}
int main()
{int input = 0;srand((unsigned)time(NULL));do//循环菜单{menu();printf("请选择>:");scanf("%d",&input);switch (input){case 1:printf("你已选择继续游戏\n");game();break;case 0:printf("你已选择退出游戏\n");break;default:printf("选择错误,重新选择\n");}} while (input);return 0;
}

电脑落子函数:

//电脑落子
void ComputerMove(char board[ROW][COL], int row, int col)
{printf("电脑落子:\n");int x = 0;int y = 0;while (1){x = rand() % row;y = rand() % col;//范围0-2if (board[x][y] == ' '){board[x][y] = '#';//满足就落子,否则继续循环break;}}
}

上面的落子函数虽然已经写完,但是运行起来还是很不完整的,接下来的判赢才是重头戏。

四、判断输赢与循环落子

1.判赢

游戏的大致走向有四种:继续游戏、玩家赢、电脑赢和平局。其中,继续游戏就是循环落子的原因,知道出现一个结局。

判赢函数:

char Iswin(char board[ROW][COL], int row, int col)

我们这里规定一下,根据该函数的返回值来决定四种结果:

//*--玩家赢    #----电脑赢   P----平局    C-----游戏继续

判赢:

三子棋游戏胜利的结果就是三个子连成一条线。三子连成线的结果无非就是三种:横、竖和斜的。

//*--玩家赢    #----电脑赢   P----平局    C-----继续
char Iswin(char board[ROW][COL], int row, int col)
{int i = 0;for (i = 0; i < row; i++)//三列相等的{if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')return board[0][i];}for (i = 0; i < col; i++)//三列相等的{if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')return board[i][0];}//判断\相等if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')return board[1][1];//判断/相等if (board[2][2] == board[1][1] && board[1][1] == board[0][0] && board[1][1] != ' ')return board[1][1];return 'C';
}

1.前面两个for循环判断横与列是否相等,如果相等就返回某一个坐标的值。

2.后面两个if语句同样的效果,满足条件就返回某个坐标。

3.如果上面的都不满足,则会返回'C',也就是游戏继续

上面的代码还差一种结局,那就是平局。平局的条件莫非就是棋盘满了,但是还没有分出胜负,所以我们另外封装一个判满的函数即可。(在上面的代码基础上改进)

int IsFull(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;}
//*--玩家赢    #----电脑赢   P----平局    C-----继续
char Iswin(char board[ROW][COL], int row, int col)
{int i = 0;for (i = 0; i < row; i++)//三列相等的{if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')return board[0][i];}for (i = 0; i < col; i++)//三列相等的{if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')return board[i][0];}//判断\相等if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')return board[1][1];//判断/相等if (board[2][2] == board[1][1] && board[1][1] == board[0][0] && board[1][1] != ' ')return board[1][1];//判断平局if (IsFull(board, row, col))return 'P';return 'C';
}

现在代码完整了,只要不满足输赢或者平局,游戏就会继续。

现在函数体的内容都已经完成,接下来需要在主函数实现接收其返回值并实现循环落子。

2.用循环实现游戏继续

其实就是每下一次,就打印一次棋盘,并且判断一次游戏是否继续

char ret=0;
while (1){//玩家下棋PlayerMove(board, ROW, COL);DisplayBoard(board, ROW, COL);//打印棋盘//每走一步棋就判断一次ret = Iswin(board,ROW,COL);if (ret != 'C')//C!=C为假,不会跳出循环break;//电脑下棋ComputerMove(board, ROW, COL);DisplayBoard(board, ROW, COL);//打印棋盘//判断电脑输赢ret = Iswin(board,ROW,COL);if (ret != 'C')break;}//跳出循环,表示博弈结束,并判断结局if (ret == '*')printf("恭喜玩家获胜,再来一局吧\n");if (ret == '#')printf("电脑获胜,再来一局吧\n");if (ret == 'P')printf("恭喜平局,谁也没有获胜\n");

到这里每个阶段的内容就完成了,接下来是总体的代码。

五、完整源码

1.分装成三个文件的源码

(1)头文件(game.h)

#include<stdio.h>
#include<stdlib.h>
#include<time.h>#define ROW 3
#define COL 3//初始化函数
void InitBoard(char board[ROW][COL],int row,int col);
//打印函数
void DisplayBoard(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);
//判断输赢
char Iswin(char board[ROW][COL], int row, int col);

(2)源文件(game.c)

#include"game.h"
//初始化棋盘
void InitBoard(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++){board[i][j] = ' ';//全部初始化成空格}}
}
//打印棋盘
void DisplayBoard(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){for (j = 0; j < col; j++){printf("---");if (j < col - 1)printf("|");}}printf("\n");}
}
//玩家落子
void PlayerMove(char board[ROW][COL], int row, int col)
{int x = 0;int y = 0;printf("请输入要落子的位置:\n");while (1){printf("玩家下>:");scanf("%d%d", &x, &y);//输入下棋的坐标//判断落子位置是否合法if (x >= 1 && x <= 3 && y >= 1 && y <= 3){//判断落子位置是否被占用if (board[x - 1][y - 1] == ' '){board[x - 1][y - 1] = '*';break;}elseprintf("该位置已被占用,请重新输入\n");}elseprintf("落子位置非法\n");}
}
//电脑落子
void ComputerMove(char board[ROW][COL], int row, int col)
{printf("电脑落子:\n");int x = 0;int y = 0;while (1){x = rand() % row;y = rand() % col;//范围0-2if (board[x][y] == ' '){board[x][y] = '#';//满足就落子,否则继续循环break;}}
}
int IsFull(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;}//*--玩家赢    #----电脑赢   P----平局    C-----继续
char Iswin(char board[ROW][COL], int row, int col)
{int i = 0;for (i = 0; i < row; i++)//三列相等的{if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')return board[0][i];}for (i = 0; i < col; i++)//三列相等的{if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')return board[i][0];}//判断\相等if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')return board[1][1];//判断/相等if (board[2][2] == board[1][1] && board[1][1] == board[0][0] && board[1][1] != ' ')return board[1][1];//判断平局if (IsFull(board, row, col))return 'P';return 'C';
}

(3)源文件(test.c)

#include"game.h"
void menu()//菜单函数
{printf("####################\n");printf("###### 1.play ######\n");printf("###### 0.exit ######\n");printf("####################\n");
}
void game()
{char ret = 0;char board[ROW][COL];InitBoard(board,ROW,COL);//初始化棋盘DisplayBoard(board,ROW,COL);//打印棋盘while (1){//玩家下棋PlayerMove(board, ROW, COL);DisplayBoard(board, ROW, COL);//打印棋盘//每走一步棋就判断一次ret = Iswin(board,ROW,COL);if (ret != 'C')break;//电脑下棋ComputerMove(board, ROW, COL);DisplayBoard(board, ROW, COL);//打印棋盘//判断电脑输赢ret = Iswin(board,ROW,COL);if (ret != 'C')break;}//跳出循环,表示博弈结束,并判断结局if (ret == '*')printf("恭喜玩家获胜,再来一局吧\n");if (ret == '#')printf("电脑获胜,再来一局吧\n");if (ret == 'P')printf("恭喜平局,谁也没有获胜\n");
}
int main()
{int input = 0;srand((unsigned)time(NULL));do//循环菜单{menu();printf("请选择>:");scanf("%d",&input);switch (input){case 1:printf("你已选择继续游戏\n");game();break;case 0:printf("你已选择退出游戏\n");break;default:printf("选择错误,重新选择\n");}} while (input);return 0;
}

2.一个文件的源码

#include<stdio.h>
#include<stdlib.h>
#include<time.h>#define ROW 3
#define COL 3//初始化函数
void InitBoard(char board[ROW][COL],int row,int col);
//打印函数
void DisplayBoard(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);
//判断输赢
char Iswin(char board[ROW][COL], int row, int col);//初始化棋盘
void InitBoard(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++){board[i][j] = ' ';//全部初始化成空格}}
}
//打印棋盘
void DisplayBoard(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){for (j = 0; j < col; j++){printf("---");if (j < col - 1)printf("|");}}printf("\n");}
}
//玩家落子
void PlayerMove(char board[ROW][COL], int row, int col)
{int x = 0;int y = 0;printf("请输入要落子的位置:\n");while (1){printf("玩家下>:");scanf("%d%d", &x, &y);//输入下棋的坐标//判断落子位置是否合法if (x >= 1 && x <= 3 && y >= 1 && y <= 3){//判断落子位置是否被占用if (board[x - 1][y - 1] == ' '){board[x - 1][y - 1] = '*';break;}elseprintf("该位置已被占用,请重新输入\n");}elseprintf("落子位置非法\n");}
}
//电脑落子
void ComputerMove(char board[ROW][COL], int row, int col)
{printf("电脑落子:\n");int x = 0;int y = 0;while (1){x = rand() % row;y = rand() % col;//范围0-2if (board[x][y] == ' '){board[x][y] = '#';//满足就落子,否则继续循环break;}}
}
int IsFull(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;}//*--玩家赢    #----电脑赢   P----平局    C-----继续
char Iswin(char board[ROW][COL], int row, int col)
{int i = 0;for (i = 0; i < row; i++)//三列相等的{if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')return board[0][i];}for (i = 0; i < col; i++)//三列相等的{if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')return board[i][0];}//判断\相等if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')return board[1][1];//判断/相等if (board[2][2] == board[1][1] && board[1][1] == board[0][0] && board[1][1] != ' ')return board[1][1];//判断平局if (IsFull(board, row, col))return 'P';return 'C';
}void menu()//菜单函数
{printf("####################\n");printf("###### 1.play ######\n");printf("###### 0.exit ######\n");printf("####################\n");
}
void game()
{char ret = 0;char board[ROW][COL];InitBoard(board,ROW,COL);//初始化棋盘DisplayBoard(board,ROW,COL);//打印棋盘while (1){//玩家下棋PlayerMove(board, ROW, COL);DisplayBoard(board, ROW, COL);//打印棋盘//每走一步棋就判断一次ret = Iswin(board,ROW,COL);if (ret != 'C')break;//电脑下棋ComputerMove(board, ROW, COL);DisplayBoard(board, ROW, COL);//打印棋盘//判断电脑输赢ret = Iswin(board,ROW,COL);if (ret != 'C')break;}//跳出循环,表示博弈结束,并判断结局if (ret == '*')printf("恭喜玩家获胜,再来一局吧\n");if (ret == '#')printf("电脑获胜,再来一局吧\n");if (ret == 'P')printf("恭喜平局,谁也没有获胜\n");
}
int main()
{int input = 0;srand((unsigned)time(NULL));do//循环菜单{menu();printf("请选择>:");scanf("%d",&input);switch (input){case 1:printf("你已选择继续游戏\n");game();break;case 0:printf("你已选择退出游戏\n");break;default:printf("选择错误,重新选择\n");}} while (input);return 0;
}

六、总结

1.需要掌握产生随机数的方法。

2.游戏总的是采用二维数组实现,其中包括了二维数组的赋值和打印数据。

3.函数的返回值和各种循环结果、选择结构。


若上述源码有bug,欢迎各位大佬留言。

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

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

相关文章

HTML详解连载(3)

HTML详解连载&#xff08;3&#xff09; 专栏链接 [link](http://t.csdn.cn/xF0H3)下面进行专栏介绍 开始喽表单作用使用场景 input标签基本使用示例type属性值以及说明 input标签占位文本示例注意 单选框 radio代码示例 多选框-checkbox注意代码示例 文本域作用标签&#xff1…

【前端 | CSS】flex布局

基本概念 Flexible模型&#xff0c;通常被称为 flexbox&#xff0c;是一种一维的布局模型。它给 flexbox 的子元素之间提供了强大的空间分布和对齐能力 我们说 flexbox 是一种一维的布局&#xff0c;是因为一个 flexbox 一次只能处理一个维度上的元素布局&#xff0c;一行或者…

R语言4_安装BayesSpace

环境Ubuntu22/20, R4.1 你可能会报错说你的R语言版本没有这个库&#xff0c;但其实不然。这是一个在Bioconductor上的库。 同时我也碰到了这个问题&#xff0c;ERROR: configuration failed for package systemfonts’等诸多类似问题&#xff0c;下面的方法可以一并解决。 第…

Mr. Cappuccino的第61杯咖啡——Spring之BeanPostProcessor

Spring之BeanPostProcessor 概述基本使用项目结构项目代码运行结果源代码 常用处理器项目结构项目代码执行结果 概述 BeanPostProcessor&#xff1a;Bean对象的后置处理器&#xff0c;负责对已创建好的bean对象进行加工处理&#xff1b; BeanPostProcessor中的两个核心方法&am…

[内网渗透]CFS三层靶机渗透

文章目录 [内网渗透]CFS三层靶机渗透网络拓扑图靶机搭建Target10x01.nmap主机探活0x02.端口扫描0x03.ThinkPHP5 RCE漏洞拿shell0x04.上传msf后门(reverse_tcp)反向连接拿主机权限 内网渗透Target2&#xff08;1&#xff09;路由信息探测&#xff08;2&#xff09;msf代理配置&a…

LeetCode150道面试经典题--找出字符串中第一个匹配项的下标(简单)

1.题目 给你两个字符串 haystack 和 needle &#xff0c;请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标&#xff08;下标从 0 开始&#xff09;。如果 needle 不是 haystack 的一部分&#xff0c;则返回 -1 。 2.示例 3.思路 回溯算法&#xff1a;首先将…

LeetCode[1122]数组的相对排序

难度&#xff1a;Easy 题目&#xff1a; 给你两个数组&#xff0c;arr1 和 arr2&#xff0c;arr2 中的元素各不相同&#xff0c;arr2 中的每个元素都出现在 arr1 中。 对 arr1 中的元素进行排序&#xff0c;使 arr1 中项的相对顺序和 arr2 中的相对顺序相同。未在 arr2 中出现…

【mysql】MySQL CUP过高如何排查?

文章目录 一. 问题锁定二. QPS激增会导致CPU飘高三. 慢SQL会导致CPU飘高四. 大量空闲连接会导致CPU飘高五. MySQL问题排查常用命令 一. 问题锁定 通过top命令查看服务器CPU资源使用情况&#xff0c;明确CPU占用率较高的是否是mysqld进程&#xff0c;如果是则可以明确CUP飘高的原…

[ubuntu]创建root权限的用户 该用户登录后自动切换为root用户

一、创建新用户 1、创建新用户 sudo useradd -r -m -s /bin/bash 用户名 # -r&#xff1a;建立系统账号 -m&#xff1a;自动建立用户的登入目录 -s&#xff1a;指定用户登入后所使用的shell2、手动为用户设置密码 passwd 用户名 二、为用户增加root权限 1、添加写权限 ch…

【redis基础】

目录 一、概述 1.NoSQL 1.1 简述 1.2 类型 1.3 应用场景 1.3.1 缓存 1.3.2 分布式锁 1.3.3 计数器 1.3.4 会话管理 1.3.5 消息队列 2.Redis 2.1 简述 2.2 特性 2.3 监听端口号 2.4 数据类型 二、安装 1.编译安装 2.RPM安装 三、目录结构 1.查看 2.主配置文…

[保研/考研机试] KY163 素数判定 哈尔滨工业大学复试上机题 C++实现

题目链接&#xff1a; 素数判定https://www.nowcoder.com/share/jump/437195121691718831561 描述 给定一个数n&#xff0c;要求判断其是否为素数&#xff08;0,1&#xff0c;负数都是非素数&#xff09;。 输入描述&#xff1a; 测试数据有多组&#xff0c;每组输入一个数…

[Docker实现测试部署CI/CD----构建成功后钉钉告警(7)]

目录 15、钉钉告警创建项目群&#xff0c;然后添加机器人添加机器人Jenkins 系统配置项目配置修改Jenkinsfile文件&#xff0c;添加钉钉提示信息测试 不修改Jenkinsfile文件&#xff0c;添加钉钉提示信息测试 15、钉钉告警 创建项目群&#xff0c;然后添加机器人 首先需要在钉…

搭建 Python 环境 | Python、PyCharm

计算机 计算机能完成的工作&#xff1a; 算术运算逻辑判断数据存储网络通信…更多的更复杂的任务 以下这些都可以称为 “计算机”&#xff1a; 一台计算机主要由以下这几个重要的组件构成 CPU 中央处理器&#xff1a;大脑&#xff0c;算术运算&#xff0c;逻辑判断 存储器&…

CSS 的选择器有哪些种类?分别如何使用?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 元素选择器&#xff08;Element Selector&#xff09;⭐ 类选择器&#xff08;Class Selector&#xff09;⭐ ID 选择器&#xff08;ID Selector&#xff09;⭐ 后代选择器&#xff08;Descendant Selector&#xff09;⭐ 子元素选择器&a…

物联网的定义、原理、示例、未来

什么是物联网? 物联网 (IoT) 是指由嵌入传感器、软件和网络连接的物理设备、车辆、电器和其他物理对象组成的网络&#xff0c;允许它们收集和共享数据。这些设备(也称为“智能对象”)的范围可以从简单的“智能家居”设备(如智能恒温器)到可穿戴设备(如智能手表和支持RFID的服…

k8sday02

第四章 实战入门 本章节将介绍如何在kubernetes集群中部署一个nginx服务&#xff0c;并且能够对其进行访问。 Namespace ​ Namespace是kubernetes系统中的一种非常重要资源&#xff0c;它的主要作用是用来实现多套环境的资源隔离或者多租户的资源隔离。 ​ 默认情况下&…

springBoot的日志文件

日志是程序的重要组成部分&#xff0c;主要可以用来定位和排查问题。除此之外&#xff0c;还可以用来&#xff1a; 1. 记录用户的登录日志&#xff0c;方便分析用户是正常登录还是恶意破解&#xff1b; 2. 记录系统的操作日志&#xff0c;方便数据恢复和定位操作人&#xff1b;…

【C语言】小游戏-三字棋

大家好&#xff0c;我是深鱼~ 目录 一、游戏介绍 二、文件分装 三、代码实现步骤 1.制作简易游戏菜单 2.初始化棋盘 3.打印棋盘 4.玩家下棋 5.电脑随机下棋 6.判断输赢 7.判断棋盘是否满了 四、完整代码 game.h(相关函数的声明&#xff0c;整个代码要引用的头文件以及宏…

某大厂笔试(小*的车站的最近距离)

有一个环形的公路&#xff0c;上面共有n站&#xff0c;现在给定了顺时针第i站到第i1站之间的距离&#xff08;特殊的&#xff0c;也给出了第n站到第1站的距离&#xff09;&#xff0c;小*想着沿着公路第x站走到第y站&#xff0c;她想知道最短的距离是多少&#xff1f; 输入描述…

小程序商城开发制作

当开发一个商城小程序时&#xff0c;费用是一个非常重要的考虑因素。然而&#xff0c;准确回答这个问题是有一定困难的&#xff0c;因为开发商城小程序的费用取决于多个因素。以下是一些可能影响价格的主要因素&#xff1a; 1. 功能需求&#xff1a;商城小程序的复杂程度和功能…