C语言趣味小游戏---利用二维数组实现三子棋游戏

news2025/1/11 14:46:06

学习了C语言中的二维数组,本照着学以致用的原则,现在利用对二维数组的操作来实现一个简单版的三子棋游戏。

三子棋其实我们都玩过,在我们这边又叫"一条龙"。就是一个九空格,下棋的双方依次在九个空格里面下棋,直到有一方在九宫格的某一行或者某一列,或者对角线下了同样的棋,那么这一方就会取得胜利。

如下图:

创建文件

这里需要三个文件:

  • test.c 用于测试游戏的逻辑
  • game.c 用于游戏代码的实现
  • game.h 用于游戏代码的声明(函数声明、符号定义)

游戏逻辑分析

1、写出游戏主逻辑
2、创建并初始化棋盘
3、打印棋盘
4、玩家下棋
5、电脑下棋
6、判断输赢

第一步:写出游戏主逻辑(test.c)

首先需要创建个menu()菜单,菜单里面包含三子棋游戏。玩家选择1表示玩游戏,玩家选择0表示退出游戏,所以需要switch语句。如果玩家玩了一次,感觉不过瘾,继续选择1,然后接着玩游戏,所以这里需要do…while语句。

代码实现:

game.h文件

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

test.c

#include "game.h"

void menu()
{
	printf("**********************************\n");
	printf("********* 1. 玩游戏  *************\n");
	printf("********* 0.退出游戏 *************\n");
	printf("**********************************\n");
}

void game()
{
	printf("玩游戏\n");
}

int main()
{
	int input = 0;
	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;
 }

测试:
在这里插入图片描述

第二步:创建并初始化棋盘

棋盘的样子:

在这里插入图片描述

创建棋盘,很简单,无非就是创建一个3行3列的二维数组。那如何初始化棋盘呢?如上图,其实也很简单就是在每一个格格里面用空格填充就可以了。

代码实现:

test.c

#include "game.h"

void menu()
{
	printf("**********************************\n");
	printf("********* 1. 玩游戏  *************\n");
	printf("********* 0.退出游戏 *************\n");
	printf("**********************************\n");
}

void game()
{
	char board[ROW][COL] = { 0 };
	InitBoard(board,ROW,COL);
}

int main()
{
	int input = 0;
	do
	{
		menu();
		printf("请选择:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 2:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误!\n");
			break;
		}
	} while(input);
	return 0;
 }

game.c

#include "game.h"

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

game.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

#define ROW 3
#define COL 3
//声明初始化棋盘
void InitBoard(char board[ROW][COL], int row, int col);

第三步:打印棋盘(版本一:代码有局限性,但是可以使用)

test.c

#include "game.h"

void menu()
{
	printf("**********************************\n");
	printf("********* 1. 玩游戏  *************\n");
	printf("********* 0.退出游戏 *************\n");
	printf("**********************************\n");
}

void game()
{
	char board[ROW][COL] = { 0 };
	//初始化棋盘
	InitBoard(board,ROW,COL);
	//打印棋盘
	DisplayBoard(board, ROW, COL);
}

int main()
{
	int input = 0;
	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;
 }

game.c

#include "game.h"

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

//打印棋盘
void DisplayBoard(char board[ROW][COL], int row, int col)
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		//打印数据
		printf(" %c | %c | %c \n",board[i][0],board[i][1],board[i][2]);
		//打印分隔符
		if (i < row - 1)
		{
			printf("---|---|---\n");
		}
	}
}

game.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#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.c

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)
		{
			int j = 0;
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
				{
					printf("|");
				}
			}
			printf("\n");
		}
	}
}

第四步:玩家下棋

这一步实现玩家下棋,并且玩家每下一步棋后需要在打印棋盘。我们想一想下棋是两个人游戏,玩家下过之后,就需要电脑下棋,然后玩家下,电脑下…一直循环往复,直到判断出一方输赢然后停止游戏。那这个就需要在一个while循环语句中。

代码如下:(重复代码已省略)

test.c

//玩家下棋
	while (1)
	{
		PlayerMove(board, ROW, COL);
		DisplayBoard(board, ROW, COL);
	}

game.h

//玩家下棋
void PlayerMove(char baord[ROW][COL], int row, int col);

game.c

//玩家下棋
//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	//判断坐标输入是否合法
	while (1)
	{
		printf("玩家下棋:>\n");
		printf("请输入坐标:>");
		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");
		}
	}
}

第五步:电脑下棋

这里实现电脑下棋采用随机的方式进行下棋。所以说需要引入几个关于时间,生成随机数的库函数。除此之外其它思路和玩家下棋思路一样。

代码如下:(重复代码已省略)

test.c

...
int main()
{
	srand((unsigned int)time(NULL));
	...
	return 0;
 }

game.h

...
#include <stdlib.h>
#include <time.h>
...
//声明电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col);

game.c

//电脑下棋
...
void ComputerMove(char board[ROW][COL], int row, int col)
{
	printf("电脑下棋:>\n");
	int x = 0;
	int y = 0;
	while (1)
	{
		//随机生成横坐标 ,范围是0~2
		x = rand() % row;
		//随机生成纵坐标 ,范围是0~2
		y = rand() % col;
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
}

第六步:判断输赢

判断输赢的动作应该在玩家或者电脑下过棋之后的动作。
判断输赢有以下几个内容:

  • 玩家赢
  • 电脑赢
  • 平局
  • 继续游戏

其中赢,又分为几部分:

任意一列全部一样为赢
任意一行全部一样为赢
对角线全部一样为赢

test.c

#include "game.h"

void menu()
{
	printf("**********************************\n");
	printf("********* 1. 玩游戏  *************\n");
	printf("********* 0.退出游戏 *************\n");
	printf("**********************************\n");
}

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

int main()
{
	srand((unsigned int)time(NULL));
	int input = 0;
	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;
 }

game.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#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 baord[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);


game.c

#include "game.h"

//初始化棋盘
void InitBoard(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++)
		{
			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)
		{
			int j = 0;
			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;
	//判断坐标输入是否合法
	while (1)
	{
		printf("玩家下棋:>\n");
		printf("请输入坐标:>");
		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");
	int x = 0;
	int y = 0;
	while (1)
	{
		//随机生成横坐标 ,范围是0~2
		x = rand() % row;
		//随机生成纵坐标 ,范围是0~2
		y = rand() % col;
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
}


//如果棋盘满了返回1,不满返回0
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;
}

//判断输赢
char IsWin(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][1] != ' ')
		{
			return board[i][1];
		}

	}
	//判断是否为列的赢
	int j = 0;
	for (j = 0; j < col; j++)
	{
		if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[1][j] != ' ')
		{
			return board[1][j];
		}
	}
	//判断是否为对角线的赢
	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 (IsFull(board, row, col))
	{
		return 'Q';
	}
	//游戏继续
	return 'C';
}


全部代码展示

test.c

#define _CRT_SECURE_NO_WARNINGS
#include "game.h"
void menu()
{
	printf("*****************************\n");
	printf("******1. 进入游戏 0. 退出****\n");
	printf("*****************************\n");
}

void game()
{
	char ret = 0;
	char board[ROW][COL] = { 0 };
	//初始化棋盘的函数
	InitBoard(board, ROW, COL);

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

	//下棋
	while (1)
	{
		//玩家下棋
		PlayerMove(board,ROW,COL);
		//判断输赢
		ret = IsWin(board,ROW,COL);
		if (ret != 'C')
		{
			break;
		}
		DisplayBoard(board, ROW, COL);
		//电脑下棋
		ComputeMove(board,ROW,COL);
		//判断输赢
		ret = IsWin(board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
		DisplayBoard(board, ROW, COL);
	}
	if (ret == '*')
	{
		printf("玩家赢\n");
		DisplayBoard(board, ROW, COL);
	}
	else if (ret == '#')
	{
		printf("电脑赢\n");
		DisplayBoard(board, ROW, COL);
	}
	else
	{
		printf("平局\n");
		DisplayBoard(board, ROW, COL);
	}
}

int main()
{
	srand((unsigned int)time(NULL));//设置随机数的生成起点
	int input = 0;
	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;
}

game.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define ROW 3
#define COL 3
#include <stdlib.h>
#include <time.h>

//初始化棋盘
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 ComputeMove(char board[ROW][COL], int row, int col);

//判断输赢,包含四种情况:
//玩家赢-'*'
//电脑赢-'#'
//平局-'Q'
//继续-'C'
char IsWin(char board[ROW][COL], int row, int col);


game.c

#include "game.h"

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

第一个版本
//void DisplayBoard(char board[ROW][COL], int row, int col)
//{
//	int i = 0;
//	for (i = 0; i < row; i++)
//	{
//		打印数据
//		printf(" %c | %c | %c \n", board[i][0], board[i][1], board[i][2]);
//		打印分割信息
//		if (i < row - 1)
//		{
//			printf("---|---|---\n");
//		}
//	}
//}

//打印棋盘
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;
	while (1)
	{
		printf("玩家下棋\n");
		printf("请输入坐标:>");
		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 ComputeMove(char board[ROW][COL], int row, int col)
{
	printf("电脑下棋:>\n");
	int x = 0;
	int y = 0;
	while (1)
	{
		x = rand() % row;   //0~2
		y = rand() % col;   //0~2
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
}

//平局的函数,返回1表示填满了,返回0表示未填满
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;
}


//判断输赢
char IsWin(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][1] != ' ')
		{
			return board[i][1];
		}
	}

	//判断在列中赢的
	int j = 0;
	for (j = 0; j < col; j++)
	{
		if (board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[1][j] != ' ')
		{
			return board[1][j];
		}
	}

	//判断对角线赢的
	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 (IsFull(board,ROW,COL))
	{
		return 'Q';
	}
	//游戏继续
	return 'C';
}


效果展示:
在这里插入图片描述

在这里插入图片描述

总结

三子棋游戏可以很好的锻炼二维数组的知识。此游戏的根本就是对二维数组的操作。此代码只是实现了最基本的游戏功能,部分代码还可以优化,还可以更加灵活,比如说:可以让电脑玩家更加智能。从而是游戏增加难度等等。

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

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

相关文章

Jetson Nano之ROS入门 - - SLAM之Gmapping建图与路径规划

文章目录 前言一、Gmapping建图算法1、Gmapping算法流程原理2、Gmapping建图实操 二、AMCL蒙特卡洛定位1、自适应蒙特卡洛定位算法原理2、AMCL定位实操 三、move_base路径规划1、路径规划算法简介2、代价地图简介2、move_base路径规划实操 总结 前言 SLAM&#xff08;Simultane…

Water valve concept流水法判断D-separation

Water valve concept流水法判断D-separation 文章目录 Water valve concept流水法判断D-separationD-separation流水法判断例子 D-separation 概率图模型中的D-separation是一种刻画随机变量之间条件独立性的方法。具体来说&#xff0c;给定一个概率图模型&#xff0c;如果其中…

Yarn【关于配置yarn-site.xml的注意事项】

注意事项 配置文件的<description>表签内容可以删&#xff0c;不影响配置文件的读取。最重要的<name><value>标签中间的内容一定要好好检查&#xff0c;尤其是在复制别人的配置信息的时候格外要注意&#xff1a;value中有没有空格、有没有因为你打开工具的不…

【IT经验实战】教你如何真正有效地学习一门IT技术

前言 在写博客之前&#xff0c;我在CSDN中搜寻了一下 “如何系统学习一门it技术” &#xff0c;琳琅满目&#xff0c;有些借鉴了ChatGPT生成的内容&#xff08;几乎一模一样&#xff09;、有些写得比较笼统没有针对性、有的偏向理论难以实操。 下文内容着实强调求学经历和过程…

SpringCloud组件介绍

一&#xff1a;什么是微服务&#xff08;Microservice&#xff09; 微服务英文名称Microservice&#xff0c;Microservice架构模式就是将整个Web应用组织为一系列小的Web服务。这些小的Web服务可以独立地编译及部署&#xff0c;并通过各自暴露的API接口相互通讯。它们彼此相互协…

小作文--流程图(练习1)

【【雅思写作】带你打破小作文‘流程图’的传说】 https://www.bilibili.com/video/BV1QP411Q7Gh/?share_sourcecopy_web&vd_source78768d4ae65c35ff26534bbaa8afc267 雅思小作文-流程图, 看这一篇就够了! - 冯凯文的文章 - 知乎 https://zhuanlan.zhihu.com/p/35868880 …

跳出零和博弈,AIGC是元宇宙的“催命符”还是“续命丹”?

文 | 智能相对论 作者 | 青月 从科幻小说《雪崩》里走出来的元宇宙&#xff0c;如今正在上演“地价雪崩”。 CoinGecko的一项调查显示&#xff0c;Otherdeed for Otherside、The Sandbox、Decentraland、Somnium Space和Voxels Metaverse 这五款知名元宇宙土地价格近期均出现…

Linux发送接收邮件

目录 一、实验 1.linux用户发送给linux中的其它用户 2.linux用户发送给外网用户 一、实验 1.linux用户发送给linux中的其它用户 &#xff08;1&#xff09;使用命令 yum install -y sendmail 安装sendmail软件 &#xff08;2&#xff09;使用yum install -y mailx 安装 mail…

获奖名单公布|Builder House首尔站及首次线下黑客松圆满收官!

由Sui基金会举办的Builder House首尔站于6月4日圆满收官&#xff0c;为期两天半的活动吸引了来自全球各地的区块链专业人士和Sui生态项目爱好者前来参加。 出席本次活动的Sui基金会成员有活动负责人Anthony、开发者关系工程师Will & Henry & Shayan、增长负责人Koh &a…

高校毕业就业信息管理系统

基于SpringSpringMVCMybatis实现的高校毕业就业信息管理系统 主要模块&#xff1a; 1&#xff09;学生模块&#xff1a; 已投简历、未投简历、录入简历、浏览招聘中岗位、 浏览已投岗位、未提交面试问卷、已提交面试问卷、 收到的就业协议、签订成功的就业协议、个人基本信…

mac docker桌面版k8s启动成功却无法访问

1. 问题复现 在mac使用docker桌面版搭建k8s 成功 但是 kubectl 控制k8s集群命令却无法使用 报错信息如下 使用登录的用户访问 ~ kubectl version W0607 14:32:39.410809 54201 loader.go:221] Config not found: /etc/kubernetes/a…

【Docker】2.Docker安装

文章目录 DockerDocker Official WebsiteDocker InstallDocker Change ImageDocker Change Dir Docker Docker本质其实时LXC之类的增强版&#xff0c;它本身不是容器&#xff0c;而是容器的易用工具。Docker时让容器技术普及开来的最成功的实现。它的主要目标是"Build, S…

6款AI绘画生成器,让你的创作更有灵感

人工智能绘画听起来很高深&#xff0c;其原理是通过集成文本、图片和其他大数据数据来生成信息库&#xff0c;在输入文本描述的要求后&#xff0c;可以找到相应的视觉元素&#xff0c;然后拼凑起来生成符合文本描述的图片。 本文介绍非常好用的6款AI绘画生成工具 1.即时 AI 绘…

从C语言到C++_17(list的模拟实现)list不是原生指针的迭代器

目录 1. list 的基本框架 1.1 list 的结点 1.2 list 构造函数 1.3 push_back 2. list 迭代器的实现 2.1 迭代器的构造 2.2 begin() 和 end() 2.3 重载 ! 和 * 和 2.4 遍历测试&#xff1a; 2.6 operator-> 2.7 operator-- 2.8 const 迭代器 3. list 的增删…

Vulnhub 靶机渗透:SICKOS: 1.2

SICKOS: 1.2 一级目录二级目录三级目录 nmap 扫描端口扫描详细扫描漏洞扫描 web渗透gobuster扫描nikto漏洞扫描思考继续 获得立足点提权总结 一级目录 二级目录 三级目录 https://www.vulnhub.com/entry/sickos-12,144/ 靶机IP&#xff1a;192.168.54.30 kali IP: 192.168.5…

如何修复 SSH Client_loop: send disconnect: Broken pipe Error

动动发财的小手&#xff0c;点个赞吧&#xff01; SSH 是 Secure Shell 的缩写&#xff0c;是一种远程网络协议&#xff0c;用于通过 TCP/IP 网络安全地连接到远程设备&#xff0c;例如服务器和网络设备。 它是一种加密网络协议&#xff0c;可提供强大的加密技术和散列法来保护…

SpringSecurity多源认证之全部交给spring容器

文章目录 一. 前言二. 配置流程2.1 SecurityConfig.class2.2 JwtAuthenticationTokenFilter2.3 AuthenticationManagerProcessingFilter 疑问 一. 前言 相关文章: 认证/支付/优惠劵策略模式-security多源认证 这篇文章没有将自定义的认证管理器注入容器. spring-security2.6.…

【计算机网络详解】——运输层(学习笔记)

&#x1f4d6; 前言&#xff1a;两台主机的通信&#xff0c;实际上两台主机中的应用进程进行通信&#xff0c;而在一台计算机中&#xff0c;用不同的端口号标识不同的应用进程。本节将介绍传输层的相关内容&#xff0c;包括端口号的分配方法、端口号的复用与分用、以及传输层的…

吴恩达 ChatGPT Prompt Engineering for Developers 系列课程笔记--07 Expanding

07 Expanding 本节示例如何用ChatGPT生成一封电子邮件的回复。 1) 定制化情绪 给定客户评论&#xff0c;我们根据评论内容和情绪产生定制的回复。下面是给定情感&#xff08;positive/negative&#xff09;&#xff0c;让ChatGPT产生相应回复的prompt。 """…

Solidwoks PDM Add-ins (C#) 创建Add-ins

本主题演示如何在Microsoft Visual Studio Enterprise 中使用Visual C#创建并调试add-in。 注意&#xff1a; 因为 SOLIDWORKS PDM Professional无法强制重新加载在 .NET 中编写的add-in程序&#xff0c;则必须重新启动所有客户端计算机&#xff0c;以确保使用最新版本的add-i…