智能三子棋(人机大战)—— 你会是最终赢家吗?万字讲解让你实现与自己对弈

news2024/10/6 6:41:54

在这里插入图片描述

  • 魔王的介绍:😶‍🌫️一名双非本科大一小白。
  • 魔王的目标:🤯努力赶上周围卷王的脚步。
  • 魔王的主页:🔥🔥🔥大魔王.🔥🔥🔥
    在这里插入图片描述
    ❤️‍🔥大魔王与你分享:罗曼罗兰说过:这个世上只有一种真正的英雄主义,那就是认清生活的真相并且任然热爱他。

文章目录

  • 一、前言
  • 二、文件介绍
  • 三、代码实现
    • 1.完成test.c文件模板
    • 2.创建棋盘并进行初始化
    • 3.打印棋盘
    • 4.玩家下棋
    • 5.电脑下棋
    • 6.判断输赢
    • 7.判断是否满了
    • 8.电脑智能下棋
  • 四、对于初学者较陌生的知识
    • 1.休眠函数
    • 2.清屏函数
    • 3.随机数函数
  • 五、总代码
    • game.h
    • 2.game.c
    • 3.test.c
    • 4.效果展示图
  • 六、总结

一、前言

相信大家都玩过三子棋或者五子棋游戏,但你会通过编程完美实现吗,本篇将带领你真正学会三子棋,并与你自己编译出来的程序分出胜负。


二、文件介绍

test.c:测试文件
game.c:源文件,进行函数的定义
game.h:头文件(只进行声明)

我们用测试文件调用game.h声明、game.c文件中实现的函数,这就是三个文件的关系。

为了使三者联系起来,我们需要让两个源文件(.c)文件都包含头文件,这样他们中的函数就可以一起使用了。


三、代码实现

1.完成test.c文件模板

模板介绍:我们在玩游戏时,首先肯定需要看到菜单,然后菜单中有选线供玩家选择,等玩家选择完成后,就要根据玩家的选择展开不同的路线来执行程序。为了使游戏可以重复完,我们还需要让程序能够玩完一次继续玩,直到玩家不想玩选择退出程序,程序再结束。

#include "game.h"

void menu()
{
	printf("********************\n");
	printf("****** 1.play ******\n");
	printf("****** 0.exit ******\n");
	printf("********************\n");
}
void test()
{
	int input = 0;
	do
	{
		menu();
		printf("请选择:> ");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("开始游戏\n");
			game();
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		case 0:
			printf("退出游戏\n");
		}
	} while (input);
}
int main()
{
	test();
	return 0;
}

2.创建棋盘并进行初始化

因为我们是要把符号输入到二维数组中,结合我们构造出来的图案形成三子棋的模样,所以我们需要创建一个二维数组并进行初始化(因为棋盘最开始为空白的,所以二维数组初始化的内容为空格)。

我们先在test.c文件中创建一个棋盘然后再调用game.c文件中初始化棋盘的代码。

  • 初始化棋盘代码如下:
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] = ' ';
		}
	}
}

3.打印棋盘

我们创建并初始化棋盘后,需要打印出三子棋图供玩家进行观察和下棋,如果玩家想玩不只3*3格的三子棋,或者想把三子棋改为五子棋,也就是说当规模较大时,为了方便玩家,我们给每行每列开头都给定标号,便利玩家。

//打印棋盘
void PrintBoard(char board[ROW][COL], int row, int col)
{
	int k = 0;
	printf(" ");
	printf(" ");
	for (k = 0; k < col; k++)
	{
		printf(" ");
		printf("%d", k + 1);
		printf(" ");
		printf(" ");
	}
	printf("\n");
	int i = 0;
	for (i = 0; i < row; i++)//打印row行
	{
		int j = 0;
		printf("%-2d", i + 1);//打印每行开头的行数
		for (j = 0; j < col; j++)//第一种行中的那一小段(空格、数组、空格)
		{
			printf(" ");
			printf("%c", board[i][j]);
			printf(" ");
			if (j < col - 1)
				printf("|");//打印一个|
		}
		printf("\n");
		if (i < row - 1)//第二种行中的那一小段(-、-、-)
		{
			printf(" ");
			printf(" ");//对应补齐每行开头的行数(不然棋盘会错一位)
			for (j = 0; j < col; j++)
			{
				printf("-");
				printf("-");
				printf("-");
				if (j < col - 1)
					printf("|");//打印一个|
			}
			printf("\n");
		}
	}
}

4.玩家下棋

游戏是由程序员编译的,但是玩家可能是个小白,玩家并不知道数组下标是从0开始的,所以我们需要让玩家输入的两个值都减去1才是玩家真实想填入的地方。但是我们在填入时,首先需要判断输入的坐标是否合法,也就是说是否为坐标范围之外的值,如果是,需要重新输入,判断完这个,我们还需要判断这个坐标是否已经被使用,只有这两个条件都满足,我们才可以将棋子落入玩家想下的地方。

//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	while (1)
	{
		printf("玩家下棋,请输入坐标:> ");
		scanf("%d %d", &i, &j);
		if ((i > 0 && i <= row) && (j > 0 && j <= col))
		{
			if (board[i - 1][j - 1] == ' ')
			{
				board[i - 1][j - 1] = '*';
				break;
			}
			else
				printf("输入坐标已经使用,请重新输入\n");
		}
		else
			printf("输入坐标不在范围内,请重新输入\n");
	}
}

5.电脑下棋

电脑下棋需要用到随机数rand(),最后会统一讲对初学者比较陌生的库函数。和玩家下棋很相似,不过不用减一了,因为这是电脑操作的。但是还需要判断是否已被占用,若已被占用,就重新给定一组值,直到电脑成功下一个棋。

//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col)
{
	while (1)
	{
		int i = rand() % row;
		int j = rand() % col;
		if (board[i][j] == ' ')
		{
			board[i][j] = '#';
			break;
		}
	}
}

6.判断输赢

三子棋的胜利分为四种形式,一种是横向三个,一种是纵向三个,一种是右下倾斜(\),一种是左下倾斜(/),这四种方式我们都会采用遍历法实现。

//判断输赢
char JudgeGame(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 - 2; j++)
		{
			if (board[i][j] == board[i][j + 1] && board[i][j] == board[i][j + 2] && board[i][j] != ' ')
				return board[i][j];
		}
	}
	//竖
	for (j = 0; j < col; j++)
	{
		for (i = 0; i < row - 2; i++)
		{
			if (board[i][j] == board[i+1][j] && board[i][j] == board[i+2][j] && board[i][j] != ' ')
				return board[i][j];
		}
	}
	//右下方向(\)
	for (i = 0; i < row - 2; i++)
	{
		for (j = 0; j < col - 2; j++)
		{
			if (board[i][j] == board[i+1][j + 1] && board[i][j] == board[i+2][j + 2] && board[i][j] != ' ')
			{
				return board[i][j];
			}
		}
	}
	//左下方向(/)
	for (i = 0; i <row; i++)
	{
		for (j = col - 1; j > 1; j--)
		{
			if (board[i][j] == board[i+1][j - 1] && board[i][j] == board[i+2][j - 2] && board[i][j] != ' ')
				return board[i][j];
		}
	}
	return 0;
}

7.判断是否满了

每次判断完是否胜利后,如果没有胜利,我们不能直接让另一个下棋,我们还要判断是否已经满了,如果满了还没分出胜负(因为是先判断输赢,再判断是否满的,所以这一点不用用管就是这样),那就是平局。

//判断是否棋盘已经下满
int is_full(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++)
		{
			if (board[i][j] == ' ')
				return 0;
		}
	}
	return 1;
}

8.电脑智能下棋

我们如果不给电脑赋一点智商,他真的好笨,让他赢都赢不了,难受啊,但又没办法给他说话,那么就让我们的思想赋给电脑,这样就是两个你在对比输赢了,哈哈哈哈。

说实话让电脑智能一点其实自己想的时候没有思路,于是看了安 度 因(点击安度因可以跳转到他的文章)大佬的智能三子棋,但是真的,就瞄一眼思路瞬间就出来了,我们只要想到从获胜那里提取思路,真的一下就出来了,无非就是:那四种情况下有两个棋子,所谓的两个棋子又分为三种情况:比如说###获胜,那么情况就有三个,##空、#空#、空##,都是这三种情况,代码如下:

//电脑智能下棋
int intelligent_move(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 - 2; j++)
		{
			if (board[i][j] == board[i][j + 1] && board[i][j] != ' ' && board[i][j + 2] == ' ')
			{
				board[i][j+2] = '#';
				return 1;
			}
			if (board[i][j] == board[i][j + 2] && board[i][j] != ' ' && board[i][j + 1] == ' ')
			{
				board[i][j+1] = '#';
				return 1;
			}
			if (board[i][j + 1] == board[i][j + 2] && board[i][j + 1] != ' ' && board[i][j] == ' ')
			{
				board[i][j] = '#';
				return 1;
			}
		}
	}
	//纵行拦截/下棋
	for (j = 0; j < col; j++)
	{
		for (i = 0; i < row - 2; i++)
		{
			if (board[i][j] == board[i+1][j] && board[i][j] != ' ' && board[i+2][j] == ' ')
			{
				board[i+2][j] = '#';
				return 1;
			}
			if (board[i][j] == board[i+2][j] && board[i][j] != ' ' && board[i+1][j] == ' ')
			{
				board[i+1][j] = '#';
				return 1;
			}
			if (board[i+1][j] == board[i+2][j] && board[i+1][j] != ' ' && board[i][j] == ' ')
			{
				board[i][j] = '#';
				return 1;
			}
		}
	}
	//右下方向拦截/下棋
	for (i = 0; i < row - 2; i++)
	{
		for (j = 0; j < col - 2; j++)
		{
			if (board[i][j] == board[i + 1][j + 1] && board[i][j] != ' ' && board[i + 2][j + 2] == ' ')
			{
				board[i + 2][j + 2] = '#';
				return 1;
			}
			if (board[i][j] == board[i + 2][j + 2] && board[i][j] != ' ' && board[i + 1][j + 1] == ' ')
			{
				board[i + 1][j + 1] = '#';
				return 1;
			}
			if (board[i+2][j+2] == board[i + 1][j + 1] && board[i+2][j+2] != ' ' && board[i][j] == ' ')
			{
				board[i][j] = '#';
				return 1;
			}
		}
	}
	//左下方向拦截/下棋
	for (i = 0; i < row - 2; i++)
	{
		for (j = col-1; j > 1; j--)
		{
			if (board[i][j] == board[i + 1][j - 1] && board[i][j] != ' ' && board[i + 2][j - 2] == ' ')
			{
				board[i + 2][j - 2] = '#';
				return 1;
			}
			if (board[i][j] == board[i + 2][j - 2] && board[i][j] != ' ' && board[i + 1][j - 1] == ' ')
			{
				board[i + 1][j - 1] = '#';
				return 1;
			}
			if (board[i+2][j-2] == board[i + 1][j - 1] && board[i+2][j-2] != ' ' && board[i][j] == ' ')
			{
				board[i][j] = '#';
				return 1;
			}
		}
	}
	return 0;
}

四、对于初学者较陌生的知识

1.休眠函数

睡眠函数:我们在玩时是不是觉得电脑反应好快,我们明明已经给他赋上智慧了,他却还那么快,这不就比我们都聪明了,为了让他笨一点,我们让他下的时候反应一秒,这就引入了睡眠函数,C语言库里是小写sleep,但是VS必须开头大写,也就是Sleep,我们按小写说,那就是sleep(unsigned int),里面的无符号整型单位是ms毫秒,所以我们写1000,实际就是每次走到这个程序停顿1秒。对应的头文件是<windows.h>

2.清屏函数

清屏函数:每次棋盘被修改,我们都要打印一次,但是这次打印出来上次的不就没用了吗,让他们一直留着好麻烦,所以我们引入一个清屏函数,system(“cls”);对应的头文件是<windows.h>

3.随机数函数

  • 随机数函数rand:
  1. rand函数原型:
    一、#include <stdlib.h>;
    二、int rand(void);

  2. rand函数调用:
    一、rand()函数每次调用前会查询是否调用过srand(seed),是否给seed设定了一个值,如果有那么它会自动调用srand(seed)一次来初始化它的起始值。
    二、若之前没有调用srand(seed),那么系统会自动给seed赋初始值,即srand(1)自动调用它一次。

  • srand函数:
  1. 一、srand函数是随机数发生器的初始化函数,原型:
    void srand(unsigned int seed);
    二、这个函数需要提供一个种子,如srand(1),用1来初始化种子。
    三、rand函数产生随机数时,如果srand(seed)播下种子之后,一旦种子相同,产生的随机数将是相同的。但是我们很多时候都是要让rand()产生一个随机数,那么这就意味着我们需要让种子值时刻发生变化,所以就可以这样赋值:srand(time(NULL)),那么我们就又引入了时间函数,详细如下

  • time函数:
  1. 我们常常使用系统时间来初始化,使用time函数来获取系统时间,得到的值是一个时间戳,即从1970年1月1日到现在时间的秒数,然后将得到的time_t类型数据转化为(unsigned int)的数,然后再传给srand函数,用法如下:
    一、srand(unsigned int)time(NULL);对应的头文件:<time.h>,我们在使用rand和srand时,主要使用的就是这一种初始化方法。
    二、如果感觉时间间隔太小,可以让这个整体乘上一个数:srand((unsigned)time(NULL)*10)
    三、time的参数传NULL表示不需要经过参数获得的time_t数据。
    四、time函数原型如下:
    time_t time(time_t * tloc); time_t类型被定义为一个长整型
    五、详细的rand讲解可以点击这里进入该文章

五、总代码

game.h

#pragma once

#include <stdio.h>
#include <windows.h>
#include <time.h>
#include <stdlib.h>

#define ROW 3
#define COL 3

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

//打印棋盘
void PrintBoard(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 JudgeGame(char board[ROW][COL], int row, int col);

//判断是否棋盘已经下满
int is_full(char board[ROW][COL], int row, int col);

//电脑智能下棋
int intelligent_move(char board[ROW][COL], int row, int col);

2.game.c

#define _CRT_SECURE_NO_WARNINGS 1

#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 PrintBoard(char board[ROW][COL], int row, int col)
{
	int k = 0;
	printf(" ");
	printf(" ");
	for (k = 0; k < col; k++)
	{
		printf(" ");
		printf("%d", k + 1);
		printf(" ");
		printf(" ");
	}
	printf("\n");
	int i = 0;
	for (i = 0; i < row; i++)//打印row行
	{
		int j = 0;
		printf("%-2d", i + 1);//打印每行开头的行数
		for (j = 0; j < col; j++)//第一种行中的那一小段(空格、数组、空格)
		{
			printf(" ");
			printf("%c", board[i][j]);
			printf(" ");
			if (j < col - 1)
				printf("|");//打印一个|
		}
		printf("\n");
		if (i < row - 1)//第二种行中的那一小段(-、-、-)
		{
			printf(" ");
			printf(" ");//对应补齐每行开头的行数(不然棋盘会错一位)
			for (j = 0; j < col; j++)
			{
				printf("-");
				printf("-");
				printf("-");
				if (j < col - 1)
					printf("|");//打印一个|
			}
			printf("\n");
		}
	}
}

//玩家下棋
void PlayerMove(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	while (1)
	{
		printf("玩家下棋,请输入坐标:> ");
		scanf("%d %d", &i, &j);
		if ((i > 0 && i <= row) && (j > 0 && j <= col))
		{
			if (board[i - 1][j - 1] == ' ')
			{
				board[i - 1][j - 1] = '*';
				break;
			}
			else
				printf("输入坐标已经使用,请重新输入\n");
		}
		else
			printf("输入坐标不在范围内,请重新输入\n");
	}
}

//电脑下棋
void ComputerMove(char board[ROW][COL], int row, int col)
{
	while (1)
	{
		int i = rand() % row;
		int j = rand() % col;
		if (board[i][j] == ' ')
		{
			board[i][j] = '#';
			break;
		}
	}
}

//判断输赢
char JudgeGame(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 - 2; j++)
		{
			if (board[i][j] == board[i][j + 1] && board[i][j] == board[i][j + 2] && board[i][j] != ' ')
				return board[i][j];
		}
	}
	//竖
	for (j = 0; j < col; j++)
	{
		for (i = 0; i < row - 2; i++)
		{
			if (board[i][j] == board[i+1][j] && board[i][j] == board[i+2][j] && board[i][j] != ' ')
				return board[i][j];
		}
	}
	//右下方向(\)
	for (i = 0; i < row - 2; i++)
	{
		for (j = 0; j < col - 2; j++)
		{
			if (board[i][j] == board[i+1][j + 1] && board[i][j] == board[i+2][j + 2] && board[i][j] != ' ')
			{
				return board[i][j];
			}
		}
	}
	//左下方向(/)
	for (i = 0; i <row; i++)
	{
		for (j = col - 1; j > 1; j--)
		{
			if (board[i][j] == board[i+1][j - 1] && board[i][j] == board[i+2][j - 2] && board[i][j] != ' ')
				return board[i][j];
		}
	}
	return 0;
}

//判断是否棋盘已经下满
int is_full(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++)
		{
			if (board[i][j] == ' ')
				return 0;
		}
	}
	return 1;
}

//电脑智能下棋
int intelligent_move(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 - 2; j++)
		{
			if (board[i][j] == board[i][j + 1] && board[i][j] != ' ' && board[i][j + 2] == ' ')
			{
				board[i][j+2] = '#';
				return 1;
			}
			if (board[i][j] == board[i][j + 2] && board[i][j] != ' ' && board[i][j + 1] == ' ')
			{
				board[i][j+1] = '#';
				return 1;
			}
			if (board[i][j + 1] == board[i][j + 2] && board[i][j + 1] != ' ' && board[i][j] == ' ')
			{
				board[i][j] = '#';
				return 1;
			}
		}
	}
	//纵行拦截/下棋
	for (j = 0; j < col; j++)
	{
		for (i = 0; i < row - 2; i++)
		{
			if (board[i][j] == board[i+1][j] && board[i][j] != ' ' && board[i+2][j] == ' ')
			{
				board[i+2][j] = '#';
				return 1;
			}
			if (board[i][j] == board[i+2][j] && board[i][j] != ' ' && board[i+1][j] == ' ')
			{
				board[i+1][j] = '#';
				return 1;
			}
			if (board[i+1][j] == board[i+2][j] && board[i+1][j] != ' ' && board[i][j] == ' ')
			{
				board[i][j] = '#';
				return 1;
			}
		}
	}
	//右下方向拦截\下棋
	for (i = 0; i < row - 2; i++)
	{
		for (j = 0; j < col - 2; j++)
		{
			if (board[i][j] == board[i + 1][j + 1] && board[i][j] != ' ' && board[i + 2][j + 2] == ' ')
			{
				board[i + 2][j + 2] = '#';
				return 1;
			}
			if (board[i][j] == board[i + 2][j + 2] && board[i][j] != ' ' && board[i + 1][j + 1] == ' ')
			{
				board[i + 1][j + 1] = '#';
				return 1;
			}
			if (board[i+2][j+2] == board[i + 1][j + 1] && board[i+2][j+2] != ' ' && board[i][j] == ' ')
			{
				board[i][j] = '#';
				return 1;
			}
		}
	}
	//左下方向拦截/下棋
	for (i = 0; i < row - 2; i++)
	{
		for (j = col-1; j > 1; j--)
		{
			if (board[i][j] == board[i + 1][j - 1] && board[i][j] != ' ' && board[i + 2][j - 2] == ' ')
			{
				board[i + 2][j - 2] = '#';
				return 1;
			}
			if (board[i][j] == board[i + 2][j - 2] && board[i][j] != ' ' && board[i + 1][j - 1] == ' ')
			{
				board[i + 1][j - 1] = '#';
				return 1;
			}
			if (board[i+2][j-2] == board[i + 1][j - 1] && board[i+2][j-2] != ' ' && board[i][j] == ' ')
			{
				board[i][j] = '#';
				return 1;
			}
		}
	}
	return 0;
}

3.test.c

#define _CRT_SECURE_NO_WARNINGS 1

#include "game.h"


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

void game()
{
	char board[ROW][COL];//创建棋盘

	InitBoard(board, ROW, COL);//初始化棋盘

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

	char ret = 0;
	while (1)
	{
		PlayerMove(board, ROW, COL);//玩家下棋,玩家为*

		system("cls");//清屏

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

		ret = JudgeGame(board, ROW, COL);//判断输赢
		if (ret != 0)
			break;
		if (ret = is_full(board, ROW, COL) == 1)
			break;

		int flag = intelligent_move(board, ROW, COL);//如果这一步电脑智能下棋确实下了,那么flag为1,否则为0

		if(flag==0)//flag为0,说明没有智能下棋,那么就进行随机下棋
		ComputerMove(board, ROW, COL);//电脑下棋,电脑为#

		Sleep(1000);//休眠一秒(让电脑思考一会,哈哈哈哈哈)

		system("cls");//清屏

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

		ret = JudgeGame(board, ROW, COL);//判断输赢
		if (ret != 0)
			break;
		if (ret = is_full(board, ROW, COL) == 1)
			break;
		
	}

	if (ret == '*')
		printf("恭喜你赢啦!!!\n");
	else if (ret == '#')
		printf("好遗憾,你连自己设置的电脑都玩不赢!!!\n");
	else
		printf("棋盘下满了,未分出胜负,电脑表示不服!!!\n");
}
void test()
{
	int input = 0;
	do
	{
		menu();
		printf("请选择:> ");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("开始游戏\n");
			game();
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		case 0:
			printf("退出游戏\n");
		}
	} while (input);
}

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

4.效果展示图

请添加图片描述

六、总结

在这里插入图片描述

💘原创不易,还希望各位佬佬支持一下 \textcolor{colourful}{💘原创不易,还希望各位佬佬支持一下} 💘原创不易,还希望各位佬佬支持一下

💓点赞,你的认可是我创作的动力! \textcolor{red}{💓点赞,你的认可是我创作的动力!} 💓点赞,你的认可是我创作的动力!

💕收藏,你的青睐是我努力的方向! \textcolor{orange}{💕收藏,你的青睐是我努力的方向!} 💕收藏,你的青睐是我努力的方向!

💞评论,你的意见是我进步的财富! \textcolor{aqua}{💞评论,你的意见是我进步的财富!} 💞评论,你的意见是我进步的财富!

✨请点击下面进入主页关注大魔王
如果感觉对你有用的话,就点我进入主页关注我吧!

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

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

相关文章

2023年湖北建设厅七大员八大员报名怎么收费呢?

建设厅七大员八大员全国统一报名网站&#xff0c;证书全国通用&#xff0c;无需调转&#xff0c;这点还是很方便的&#xff0c;所有在湖北考的证书全国都能用呢。 八大员报考机构很多&#xff0c;收费也是层次不齐&#xff0c;这里需要提醒大家注意的是&#xff0c;咨询八大员的…

如何持续架构治理?我们和 ChatGPT 聊了一会?

在上周的 QCon 北京 2022 大会上&#xff0c;我和我的同事黄雨青一起分享了《组织级架构治理的正确方式》&#xff0c;以帮助开发人员对组织级架构治理体系全貌一瞥&#xff0c;并厘清治理工具的设计思路和核心功能内容。结合我们在 ArchGuard 的探索经验&#xff0c;我们&…

自有APP上如何运行小游戏?

近年来小程序游戏迎来了爆发式增长。微信、支付宝、抖音等各大平台小程序游戏愈加丰富&#xff0c;你是否也让自己的App也拥有运行丰富的小游戏的能力&#xff1f;今天就来带大家看看如何实现。 我们先来看看各互联网巨头关于小游戏生态的特征&#xff1a; 「微信」 率先推出…

open3d点云配准函数registration_icp

文章目录基本原理open3d调用绘图基本原理 ICP, 即Iterative Closest Point, 迭代点算法。 ICP算法有多种形式&#xff0c;其中最简单的思路就是比较点与点之间的距离&#xff0c;对于点云P{pi},Q{qi}P\{p_i\}, Q\{q_i\}P{pi​},Q{qi​}而言&#xff0c;如果二者是同一目标&am…

如何将一张纹理图贴在模型上

前言 小伙伴们是否有过这样的场景:看到一个精美的3D模型&#xff0c;很想知道它是如何被创作出来的&#xff1f;于是开始了一番搜索引擎查找之后&#xff0c;得知需要建模工具来完成&#xff0c;例如3D Max、Maya、Blender、Photoshop。那么本篇就使用这些工具来完成一个精美的…

Redis【包括Redis 的安装+本地远程连接】

Redis 一、为什么要用缓存&#xff1f; 缓存定义 缓存是一个高速数据交换的存储器&#xff0c;使用它可以快速的访问和操作数据。 程序中的缓存 在我们程序中&#xff0c;如果没有使用缓存&#xff0c;程序的调用流程是直接访问数据库的&#xff1b; 如果多个程序调用一个数…

如何在原始的认知上找回自己

认知、欲望加恐惧&#xff0c;这三种要素在我们对一个事物的判断中都在起作用&#xff0c;只不过配比不一样&#xff0c;导致你的判断不一样。我们通常以为有了认知能力&#xff0c;就产生了认知&#xff0c;就如同面前有一个东西&#xff0c;你用照相机拍下来就成了一张照片—…

【算法基础】高精度除法

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前是C语言 算法学习者 ✈️专栏&#xff1a;【C/C】算法 &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章对你有帮助的话 欢迎 评论&#x1f4ac…

PN外加电场后电场变化

没有外加电场时&#xff08;下面都是以外加反向电场分析&#xff09; 中间两条实线假设是PN节在没有外加电场的情况下形成的一个内部电场边界。 形成原因 实用的半导体一般是混合物 P型半导体&#xff0c;实际上是一种4价和3价元素的混合物。化学中都知道达到4或8的外层电子…

论文浅尝 | KGE by Adaptive Limit Scoring Loss Using DWS

笔记整理&#xff1a;陈磊&#xff0c;天津大学硕士链接&#xff1a;https://ieeexplore.ieee.org/ielx7/6287639/7859429/08057770.pdf动机设计一个强大而有效的损失框架对于知识图嵌入模型区分正确和不正确的三元组至关重要。经典的基于边距的排名损失将正负三元组的分数限制…

极智AI | 算能SDK架构

欢迎关注我的公众号 [极智视界]&#xff0c;获取我的更多经验分享 大家好&#xff0c;我是极智视界&#xff0c;本文介绍一下 算能SDK架构。 邀您加入我的知识星球「极智视界」&#xff0c;星球内有超多好玩的项目实战源码下载&#xff0c;链接&#xff1a;https://t.zsxq.com…

华芯微特开发环境搭建-SWM34SVET6为例

SWM34S系列是cortex-M33&#xff0c;内核是arm-v8指令集&#xff0c;和其他cortex系列有差异&#xff0c;要新的工具版本支持&#xff08;jlink要升级到V9以上&#xff0c;keil要升级到5.32以上&#xff09;。 1.Keil要先安装5.36的版本&#xff0c;并取得版权&#xff08;5.3…

【MYSQL中级篇】数据库数据查询学习

&#x1f341;博主简介 &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; 相关文章 文章名文章地址【MYSQL初级篇】入门…

网络安全-Kali更新源(APT)

网络安全-Kali更新源(APT&#xff09; 这篇东东很少内容 Kali是基于乌班图开发出来的 这个APT不是攻击的那个APT 这个APT和centos里面的YUM是一样的 下面是介绍的一些国内的APT包&#xff0c;我自己用的阿里云 通俗点怎么理解呢&#xff0c;你手机里面的应用市场&#xff0c;苹…

【闲聊】我用ChatGPT参加了大数据面试

用Chat GPT试了试面试题&#xff0c;回答得比较简单。 问&#xff1a;你可以以应聘者的身份参加一场大数据程序员面试吗 答&#xff1a;可以 &#xff0c;如果您符合面试要求&#xff0c;可以参加大数据程序员面试。 问&#xff1a;那么为什么你要投递大数据开发这个岗位 答&am…

数据结构总结

数据结构总结排序算法冒泡排序选择排序插入排序希尔排序堆排序快速排序算法归并排序计数排序基数排序树红黑树基本概念规则B树基础知识规则B树图回溯算法并查集拓扑排序其他算法KMP算法例题数组类求最大和子数组求子数组最大乘积删除重复链表元素十大排序算法参考 排序算法 冒…

16:00面试,16:09就出来了 ,问的实在是太...

从外包出来&#xff0c;没想到算法死在另一家厂子 自从加入这家公司&#xff0c;每天都在加班&#xff0c;钱倒是给的不少&#xff0c;所以也就忍了。没想到8月一纸通知&#xff0c;所有人不许加班&#xff0c;薪资直降30%&#xff0c;顿时有吃不起饭的赶脚。 好在有个兄弟内…

情人节快到了,我部署了一套情侣头像小程序,并过审了

最近在学习如何部署微信小程序&#xff0c;目的就是像拥有一个属于自己的小程序 之前做的是一个微信公众号&#xff0c;靠自然的流量虽然也开通了流量主&#xff0c;但是每天收益就是那0.0几的,所有寻思看能不能做一个小程序出来。不会写小程序的我&#xff0c;也只能用现成的…

IO流01_字节字符流、缓冲流、标准输入、输出流、打印流

文章目录①. IO流概述及分类②. 字节输入流 - FileInputStream③. 字节输出流 - FileOutputStream④. 字符输入流 - FileReader⑤. 字符输出流 - FileWriter⑥. 字节缓冲流 - Buffered⑦. 掌握 - 相关流习题操作⑧. 标准输入、输出流(了解)⑨. 打印流 - PrintStream、PrintWrit…

Retinanet网络与focal loss损失

1.损失函数 1&#xff09;原理 本文一个核心的贡献点就是 focal loss。总损失依然分为两部分&#xff0c;一部分是分类损失&#xff0c;一部分是回归损失。 在讲分类损失之前&#xff0c;我们来回顾一下二分类交叉熵损失 &#xff08;binary_cross_entropy&#xff09;。 计…