人工智能三子棋-人机对弈-人人对弈,谁会是最终赢家?

2024-02-12 20:36

本文主要是介绍人工智能三子棋-人机对弈-人人对弈,谁会是最终赢家?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在这里插入图片描述

✅作者简介:大家好我是原始豌豆,感谢支持。
🆔本文由 原始豌豆 原创 CSDN首发🐒 如需转载还请通知⚠
🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝​
📣系列专栏:C语言项目实践

前言

    相信大家都玩过三子棋或者五子棋游戏,但你会通过编程完美实现吗,本篇将带领你真正学会AI智能三子棋,让程序拥有人工智能,可以实现堵棋,赢棋,自由落子的功能。玩家VS电脑,玩家VS玩家。谁会是最终赢家?

文章目录

一、项目背景与目标
二、最终成果展示
三、模块化编程
四、整体结构组成
五、代码及思路讲解
     (1)控制台属性设置函数
     (2)颜色控制函数
     (3)背景音乐函数
     (4)光标函数
     (5)三子棋字幕动画函数
     (6)主菜单界面player vs computer 动画展示函数
     (7)主菜单函数
     (8)初始化棋盘函数
     (9)打印棋盘函数
     (10)玩家下棋函数
     (11)玩家下棋提示框函数
     (12)AI人工智能下棋函数
     (13)AI人工智能三连赢棋函数
     (14)AI人工智能堵棋函数
     (15)先手后手函数
     (16)遍历棋盘函数
     (17)电脑下棋提示框函数
     (18)玩家VS玩家下棋函数
     (19)人机对战中玩家赢或电脑赢或平局的提示框函数
     (20)游戏主体函数
     (21)游戏说明函数
     (22)开发人员菜单函数
     (23)退出游戏函数
     (24)主函数

六.全部源码
七.项目总结

一、项目背景与目标

  三子棋,又称为井字棋,是一种古老而简单的两人对弈游戏。在3x3的棋盘上,两位玩家轮流在空格上放置自己的标记(通常为X和#),先连成三子一线(横、竖或斜)的玩家获胜。本项目旨在使用C语言实现一个能够与人类玩家进行对战并具有一定智能水平的三子棋AI。在人机对战中这个AI会尝试找到一个胜利的模式或阻止对手胜利的模式。如果没有找到,它将会选择其余可以干扰到玩家的位置下棋。除此之外该程序还具备人人对战的功能。

二、最终成果展示

话不多说,先给大家看下做好后的最终效果!!!

三子棋游戏最终效果图GIF展示(带背景音乐)

在这里插入图片描述

三、模块化编程

实现智能三子棋代码逻辑前,我们来说说什么是模块化编程吧?

什么是模块化编程?
  传统方式编程:所有的函数均放在主函数main.c里,一个文件内会有很多的代码,不利于代码的组织和管理,而且很影响编程者的思路。
   模块化编程:把各个模块的代码放在不同的.c文件里,在.h文件里提供外部可调用函数的声明,其它.c文件想使用其中的代码时,只需要#include
"XXX.h"文件即可。使用模块化编程可极大的提高代码的可阅读性、可维护性、可移植性等。

四、整体结构组成

游戏代码主要由四部分组成。
beautify.c
   该文件内主要存放三子棋游戏的控制台设置函数,颜色控制函数,音乐播放函数,光标定位函数,游戏开场动画函数,菜单界面动画函数,主菜单界面,打印玩家赢或电脑赢或平局的提示框函数,游戏规则说明函数,开发人员菜单函数,打印玩家下棋对应的提示框函数,打印电脑下棋坐标提示框的函数,打印退出游戏动态效果
game.c
    该文件内主要存放初始化棋盘函数 ,打印棋盘函数 ,玩家下棋函数,电脑下棋函数,分别调用AI智能三连赢棋函数,AI智能堵棋函数,按比重权值范围随机落子,实现人工智能下棋,判断棋盘是否为空函数,AI人工智能三连赢棋函数,AI人工智能三连赢棋函数,玩家VS玩家下棋函数 ,判断输赢函数
test.c
   该文件内主要存放人机对战中选择玩家先手或电脑先手的函数,游戏主体函数,主函数

sanziqi.h 头文件
   声明游戏内容中所包含的所有函数

在这里插入图片描述

五、代码及思路讲解

(1)控制台属性设置函数

  智能三子棋是基于C语言编写的控制台应用程序,我们首先要把控制台的各种参数设置好,控制台显示的宽度和高度,控制台缓冲区的大小和控制台标题的设置。

//控制台属性设置
void ConsoleSet()
{system("mode con cols=141 lines=50");//窗口宽度和高度HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);//使用GetStdHandle函数来获取标准输出句柄(STD_OUTPUT_HANDLE),通常用于控制台应用程序。COORD bufferSize = { 141, 500 }; // 缓冲区大小为141*500字符  缓冲区的大小以字符宽和高为单位。//设置的控制台缓冲区大小要超过控制台大小SetConsoleScreenBufferSize(hOut, bufferSize);system("title 智能三子棋");//界面美化
}

(2)颜色控制函数

  智能三子棋游戏里使用了很多不同颜色的动态效果展示和界面,所以我们先编写一个color函数用来控制程序的各个界面的颜色,让程序运行看上去更加美观、鲜明。

//颜色控制函数
void color(short x)
{if (x >= 0 && x <= 15)SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), x);elseSetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 7);
}

(3)背景音乐函数

   我们的游戏是带有背景音乐的,所以这里我们创建一个背景音乐函数BackgroundMusic,通过调用windows api来实现音乐的播放和音效的实现,“AI-sanziqi.wav”,引号内部的内容为音频文件的名称(音频文件必须是wav格式的,音频文件放在代码对应的release文件底下程序才能有声音),在这里给
BackgroundMusic函数设置了参数x,通过参数用来控制音乐的打开或关闭。传参数e时音乐停止,音频文件我会放到本文的最后。

void BackgroundMusic(char x) //参数传s代表start,开始播放音乐,参数传e代表end,终止播放音乐
{if (x == 's'){PlaySound(TEXT("AI-sanziqi.wav"), NULL, SND_FILENAME | SND_LOOP | SND_ASYNC);//播放音频文件,循环播放,异步播放  }if (x == 'e'){PlaySound(NULL, NULL, SND_PURGE); // 停止所有声音 }
}

(4)光标函数

   从本文最开始的最终效果展示中可以看到,部分图案和文字的的打印定位是通过光标位置到指定坐标,然后开始打印的,所以我们编写一个光标控制函数。

//定位光标位置到指定坐标
void goto_xy(int x, int y)
{HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);;COORD pos = { x,y };SetConsoleCursorPosition(handle, pos);
}

(5)三子棋字幕动画函数

   游戏开场动画,用字符数组存储并通过循环搭配Sleep函数和光标函数实现显示动画和动画清除的效果,本函数有两个参数,参数传p打印图案,传c清屏图案。

//游戏开场动画,三子棋字幕显示(函数内部不带颜色)
void sanziqi(char print_or_cls)//参数传p打印图案,传c清屏图案
{char str[] ="######################################################################\n\
#                      #                      #     ##   ###   ###   #\n\
#                      #    ##                #     ##   ###   ###   #\n\
#   ###############    #    ##############    #     ##  ####   ####  #\n\
#   ###############    #    ##############    #     ##  ###########  #\n\
#                      #            ####      #  ##################  #\n\
#                      #          #####       #  #######  ##   ###   #\n\
#                      #         ####         #  #######  ########   #\n\
#                      #         ###          #    ###    ########   #\n\
#     ##        ##     # ###################  #    #####  ##   ###   #\n\
#     ############     # ###################  #   ######  ########   #\n\
#     ############     # ###################  #   ####### ########   #\n\
#                      #          ##          #  #######  ##   ###   #\n\
#                      #          ##          # ### ## ## ##   ##### #\n\
#                      #          ##          #  ## ## ############# #\n\
#                      #          ##          #     ## ############# #\n\
#  ##             ###  #          ##          #     ##    ### ####   #\n\
#  ##################  #       #####          #     ##   ###  #####  #\n\
#  ##################  #       #####          #     ## ####     #### #\n\
#                      #       ####           #     ##  ##       ##  #\n\
#                      #                      #                      #\n\
#                      #                      #                      #\n\
######################################################################";if (print_or_cls == 'p')	//参数传p代表打印图案printffor (int i = 0; i < strlen(str); i++){putchar(str[i]);if (str[i] == '\n'){Sleep(50);}}else if (print_or_cls == 'c')  //参数传c代表清除图案cls{goto_xy(0, 0);   //将坐标传到(0,0),再依次按行打印空格,以达到清屏效果for (int i = 0; i < strlen(str); i++){putchar(' ');if (str[i] == '\n'){Sleep(50);}}}
}

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

(6)主菜单界面player vs computer 动画展示函数

   从本文最开始的最终效果展示中可以看到,主菜单界面的左侧是有player vs computer 这个动态效果的展示的,所以我们编写一个player vs computer动画展示函数,用字符数组存储图案,并通过循环搭配Sleep函数和光标函数实现显示动画和动画清除的效果,我将图案分成了三部分,并设置了红,绿,蓝三种颜色对一部分每一部图案。

//游戏主菜单界面左侧player vs computer 动画展示(函数内部自带颜色,红,绿,蓝)
void player_vs_computer()
{int line = 0;//控制player vs computer在goto_xy函数操纵下的的行数位置char ch1[] ="        _  \n"" _ __  | |   __ _   _   _    ___   _ __  \n""| '_ \\ | |  / _` | | | | |  / _ \\ | '__|\n""| |_)| | | | (_| | | |_| | |  __/ | |   \n""|.__./ |_|  \\__,_|  \\__, |  \\___| | _|\n""|_|                 |___/ \n";char ch2[] =" __   __  ___ \n"" \\ \\ /  // __|\n""  \\ V /  \\__ \\\n""   \\_/   |___/\n";char ch3[] ="                                        _\n""  ___   ___   _ __ ___   _ __   _   _  | |_    ___   _ __ \n""/ __|  / _ \\ | '_ ` _ \\ | '_ \\ | | | | | __|  / _ \\ | '__|\n""| (__ | (_) || | | | | || |_) || |_| | | |_  |  __/ |  | \n""\\___ | \\___/ |_| |_| |_|| .__ / \\__,_|  \\___| \\___| | _|\n""                        |_| \n";color(4);//红色goto_xy(5, 0);for (int i = 0; i < strlen(ch1); i++){printf("%c", ch1[i]);if (ch1[i] == '\n'){Sleep(30);goto_xy(5, ++line);}}color(10);//绿色goto_xy(15, ++line);for (int i = 0; i < strlen(ch2); i++){printf("%c", ch2[i]);if (ch2[i] == '\n'){Sleep(30);goto_xy(15, ++line);}}color(3);//蓝色goto_xy(0, ++line);for (int i = 0; i < strlen(ch3); i++){printf("%c", ch3[i]);if (ch3[i] == '\n'){Sleep(30);goto_xy(0, ++line);}}
}

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

(7)主菜单函数

  我们既然做游戏,就得有一个菜单,供玩家选择开始游戏或退出游戏等功能。我们先做一个Menu菜单函数并写上每个功能,使用时在主函数里调用就可以展示给玩家了。
  菜单函数也可以设计的很精美,可以参考我的设计样式.最后的goto_xy(75, 16);是为了将输入处的光标定位在括号里面

//游戏主菜单界面菜单界面(函数内部不带颜色)
void Menu()
{goto_xy(60, 5);printf("________________________\n");  Sleep(70);goto_xy(60, 6);printf("|       1.开始游戏      |\n");  Sleep(70);goto_xy(60, 7);printf("|_______________________|\n"); Sleep(70);goto_xy(60, 8);printf("|       2.人人对战      |\n");  Sleep(70);goto_xy(60, 9);printf("|_______________________|\n"); Sleep(70);goto_xy(60, 10);printf("|       3.游戏说明      |\n"); Sleep(70);goto_xy(60, 11);printf("|_______________________|\n"); Sleep(70);goto_xy(60, 12);printf("|       4.开发人员      |\n"); Sleep(70);goto_xy(60, 13);printf("|_______________________|\n"); Sleep(70);goto_xy(60, 14);printf("|       5.退出游戏      |\n"); Sleep(70);goto_xy(60, 15);printf("|_______________________|\n"); Sleep(70);goto_xy(60, 16);printf("请输入选项->【   】");goto_xy(75, 16);//将输入处的光标定位在括号里面
}

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

(8)初始化棋盘函数

  菜单函数写好以后,游戏拥有的基本功能框架也就定位好了,接下来我们要做的就是实现菜单函数里所希望实现的所有功能,先来实现人机对战。
  创建棋盘并进行初始化,因为我们是要把符号输入到二维数组中,结合我们构造出来的图案形成三子棋的模样,所以我们需要创建一个二维数组并进行初始化(因为棋盘最开始为空白的,所以二维数组初始化的内容为空格),三子棋的棋盘一共三行三列,共有九个空可以下棋,这用一个三行三列的数组来存放每个空的数据,为了代码的灵活性,这里不要把行和列的值写死,用define定义的常量来写,方便以后代码的更新。

//初始化棋盘函数  
void InitBoard(char Board[ROW][COL], int row, int col)   // 二维数组作为参数传递给函数时,必须指明数组的列数
{for (int i = 0; i < row; i++){for (int j = 0; j < col; j++){Board[i][j] = ' ';//将棋盘的每个位置初始化为空格}}
}

(9)打印棋盘函数

  我们创建并初始化棋盘后,需要打印出三子棋的棋盘供玩家进行观察和下棋,我们同样不要把行和列写死,而是采用define定义的常量ROW和COL,这样玩家如果不想玩3*3格的三子棋,或者想把三子棋改为五子棋,只需在头文件中改变define定义的常量值,棋盘的大小也会随之改变。

//打印棋盘函数  (亮黄色棋盘)
int DisplayBoard(char Board[ROW][COL], int row, int col)
{color(14);//黄色棋盘int k = 0;  //goto_xy函数的列坐标goto_xy(50, ++k);  //棋盘打印的初始坐标for (int i = 1; i <= col; i++)//打印棋盘列序号{printf("   %d", i);}goto_xy(52, ++k);for (int i = 0; i < col; i++){printf("____");}for (int i = 0; i < row; i++)//控制行数{goto_xy(50, ++k);//k不断自增以对应棋盘不同的大小,起到换行后居中的效果printf("%d|", i + 1);//打印棋盘行序号和最左侧边框for (int j = 0; j < col; j++){printf(" %c |", Board[i][j]);//将"   |"看作一组,根据col打印}goto_xy(50, ++k);//k不断自增以对应棋盘不同的大小,起到换行后居中的效果printf(" |");//打印棋盘无序号行和最左侧边框for (int j = 0; j < col; j++){printf("---|");//将"---|"看作一组,根据col打印}}printf("\n\n");
}

三子棋棋盘ROW和COL都为3效果图:
在这里插入图片描述
例如将ROW和COL都改成9:效果图
在这里插入图片描述

(10)玩家下棋函数

  在玩家下棋这部分中,我们定义玩家通过输入坐标来进行下棋。需要注意的是:数组所定义的下标是从0开始的,而玩家认知的坐标是从1开始的(例如:玩家想输入第一行第一列的坐标是,输入的是(1,1),而不是(0,0),这里需要将玩家输入的横、纵坐标减1,转换成数组的坐标。

   在玩家输入完坐标后,我们还需要判断该坐标是否合法,如果玩家输入的坐标超过棋盘界限,或者该坐标已经下过棋了,那么需要重新输入坐标。所以我们采用while循环结构,直到玩家下棋成功,跳出循环。
这里玩家下的棋,用 X表示。定义PlayerMove用来实现玩家下棋的这部分。

//玩家下棋函数  (玩家下棋显示红色提示框)
void PlayerMove(char Board[ROW][COL], int row, int col)
{color(4);//玩家下棋显示红色提示框int i = 0, j = 0;//定义了两个整数变量i和j,用于存储玩家输入的坐标。int ch = 0;PrintPlayerMove(1);while (1)//开始一个无限循环,这样程序会持续等待玩家的输入,直到玩家输入有效的坐标并下棋break。{scanf("%d%d", &i, &j);while ((ch = getchar()) != '\n' && ch != EOF);//对玩家输入数据进行处理,防止字符造成死循环。if ((i >= 1 && i <= row) && (j >= 1 && j <= col))//如果坐标在棋盘范围内(即1到行数和1到列数之间),则执行以下代码:{if (Board[i - 1][j - 1] == ' ')//检查该坐标位置是否为空。如果为空,表示这个位置可以被下棋{Board[i - 1][j - 1] = 'X';break;//成功下棋后跳出循环}else{PrintPlayerMove(2);}}else//如果坐标不在棋盘范围内,重新输入。{PrintPlayerMove(3);}}
}

(11)玩家下棋提示框函数

   玩家下棋回合得有提示框提示玩家到下棋回合了,或者玩家坐标输入错误,或者坐标不合法都会有对应的提示框,我们单独做一个玩家下棋提示框函数来显示这些,并通过不同的参数判断该打印哪条提示框信息。上面写的玩家下棋函数就可以调用玩家提示框函数,因为后续还会有人人对战模式,所以我们这里直接把人人对战的提示框也写好。

//打印玩家下棋对应的提示框函数  (函数内部不带颜色)
void PrintPlayerMove(int n)
{if (n == 1){printf(" __________________________________\n");printf("|       玩家下棋回合, 棋子‘X’    |\n");printf("|__________________________________|\n");printf(" 输入坐标:");}else if (n == 2){printf(" __________________________________\n");printf("|      坐标被占用, 请重新输入      |\n");printf("|__________________________________|\n");printf(" 输入坐标:");//如果该位置已被占据,程序会提示玩家重新输入:}else if (n == 3)//如果坐标不在棋盘范围内,重新输入。{printf(" __________________________________\n");printf("|      坐标不合法,请重新输入       |\n");printf("|__________________________________|\n");printf(" 输入坐标:");}else if (n == 4){printf(" __________________________________\n");printf("|       玩家一下棋回合, 棋子‘X’  |\n");printf("|__________________________________|\n");printf(" 玩家一输入坐标:");}else if (n == 5){printf(" __________________________________\n");printf("|       玩家二下棋回合, 棋子‘#’  |\n");printf("|__________________________________|\n");printf(" 玩家二输入坐标:");}}

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

(12)AI人工智能下棋函数
看了CSDN大部分文章写的三子棋,都是没有智能的,玩家轻松就能击败电脑,那么如何赋予电脑智能呢?让电脑可以击败玩家或立于不败之地呢?其实并不复杂。

   电脑实现AI人工智能下棋分为三个部分:赢棋、堵棋、按权值自由落子。

   这里的优先级是赢棋>堵棋>自由落子,在写代码的时候要遵循:能赢优先赢,不能赢则优先堵,以上情况都不符合的时候自由落子。(自由落子不等于随机下棋,找到以自身坐标为中心,周围8个坐标有玩家棋子的位置进行落子,可以对玩家形成一定的干扰)

定义三个函数:

   智能三连赢棋函数:AI_WinChess(如果函数执行并落子,返回’s’;否则返回’f’)

   智能堵棋函数: AI_BlockingChess(如果函数执行并落子,返回1;否则返回0)

   自由落子函数:ComputerMove(构建整体框架,根据前两个函数的返回值来判断是否落子)

//电脑下棋函数,分别调用AI智能三连赢棋函数,AI智能堵棋函数,按比重权值范围随机落子,实现人工智能下棋
void ComputerMove(char Board[ROW][COL], int row, int col)
{int x, y;//定义了两个整数变量x和y,用于存储电脑下棋的坐标。//1.智能三连赢棋函数优先级最高,//如果智能三连赢棋函数没有成功找到可以三连的棋子则返回f,然后进入内层运行智能堵棋函数if (AI_WinChess(Board, ROW, COL) == 'f'){//智能堵棋函数优先级第二,//如果智能堵棋函数没有成功找到可以堵棋的棋子则返回0,然后进入内层进行随机落子if (AI_BlockingChess(Board, ROW, COL) == 0){//分支判断电脑是否是先手且第一步下棋,是则在中心位置下棋,if (TraverseBoard(Board, ROW, COL) == 'e'){color(15);Board[row / 2][col / 2] = '#';AI_Coordinate(row / 2, col / 2);}else if (TraverseBoard(Board, ROW, COL) == 'n')//否则则找到以自身为中心,其余八个坐标内有玩家棋子的位置进行随机下棋{while (1){color(11);//随机下棋湖蓝色x = rand() % row;//在循环内,使用rand()函数%row和col,生成一个坐标值不会越界的随机的坐标(x, y)y = rand() % col;if (Board[x][y] == ' ' && (Board[x - 1][y - 1] == 'X' || Board[x - 1][y] == 'X' || Board[x - 1][y - 1] == 'X' || Board[x][y - 1] == 'X' || Board[x][y + 1] == 'X' || Board[x + 1][y - 1] == 'X' || Board[x + 1][y] == 'X' || Board[x + 1][y + 1] == 'X')){Board[x][y] = '#';AI_Coordinate(x, y);break;}}}}}
}

(13)AI人工智能三连赢棋函数

对玩家的的落子进行分析,实现智能赢棋 (优先级最高) ,电脑下棋用‘#’表示,该函数在AI人工智能下棋函数中被调用。

1 判断所有行里是否有某行出现 #  #  空 ,  #  空  # ,空  #  #,三种情况进行智能赢棋,
2.判断所有列里是否有某列出现
  #   #   空
  #   空  #
  空  #   #
3.判断一条角线(\)里是否有出现
#     #     空
  #    空     #
    空     #     #
4.判断另一条角线(/)里是否有出现
   #     #     空
  #     空       #
空     #      #

// AI人工智能三连赢棋函数(对玩家的的落子进行分析,实现智能赢棋  (优先级最高) (亮白色提示框)
char AI_WinChess(char Board[ROW][COL], int row, int col)// 返回值s代表success电脑三连赢棋成功,返回值f代表failure电脑未找到能够三连的的棋子{int i = 0;int j = 0;color(15);//1.判断所有行里是否有某行出现 ##空 #空# 空##,三种情况进行智能赢棋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] = '#';AI_Coordinate(i, j + 2);//将下棋坐标传入AI_Coordinate函数return 's';}if (Board[i][j] == Board[i][j + 2] && Board[i][j] == '#' && Board[i][j + 1] == ' '){Board[i][j + 1] = '#';AI_Coordinate(i, j + 1);//将下棋坐标传入AI_Coordinate函数return 's';}if (Board[i][j + 1] == Board[i][j + 2] && Board[i][j + 1] == '#' && Board[i][j] == ' '){Board[i][j] = '#';AI_Coordinate(i, j);//将下棋坐标传入AI_Coordinate函数return 's';}}}//2.判断所有列里是否有某列出现  // #   #   空// #   空   #// 空   #   #//以上三种情况,进行智能三连赢棋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] = '#';AI_Coordinate(i + 2, j);//将下棋坐标传入AI_Coordinate函数return 's';}if (Board[i][j] == Board[i + 2][j] && Board[i][j] == '#' && Board[i + 1][j] == ' '){Board[i + 1][j] = '#';AI_Coordinate(i + 1, j);//将下棋坐标传入AI_Coordinate函数return 's';}if (Board[i + 1][j] == Board[i + 2][j] && Board[i + 1][j] == '#' && Board[i][j] == ' '){Board[i][j] = '#';AI_Coordinate(i, j);//将下棋坐标传入AI_Coordinate函数return 's';}}}//3.判断一条角线(\)里是否有出现//#           #              空//  #           空              #//    空           #               #//以上三种情况,进行智能赢棋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] = '#';AI_Coordinate(i + 2, j + 2);return 's';}if (Board[i][j] == Board[i + 2][j + 2] && Board[i][j] == '#' && Board[i + 1][j + 1] == ' '){Board[i + 1][j + 1] = '#';AI_Coordinate(i + 1, j + 1);return 's';}if (Board[i + 1][j + 1] == Board[i + 2][j + 2] && Board[i + 1][j + 1] == '#' && Board[i][j] == ' '){Board[i][j] = '#';AI_Coordinate(i, j);return 's';}}}//4.判断一条角线(/)里是否有出现//       #           #           空//     #           空           #//  空           #            #//以上三种情况,进行智能赢棋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] = '#';AI_Coordinate(i + 2, j - 2);return 's';//返回这个棋子的字符}if (Board[i][j] == Board[i + 2][j - 2] && Board[i][j] == '#' && Board[i + 1][j - 1] == ' '){Board[i + 1][j - 1] = '#';AI_Coordinate(i + 1, j - 1);return 's';//返回这个棋子的字符}if (Board[i + 1][j - 1] == Board[i + 2][j - 2] && Board[i + 1][j - 1] == '#' && Board[i][j] == ' '){Board[i][j] = '#';AI_Coordinate(i, j);return 's';//返回这个棋子的字符}}}return 'f';
}

(14)AI人工智能堵棋函数

(对玩家的的落子进行分析,实现智能堵棋)(优先级第二),该函数在AI人工智能下棋函数中被调用。
  堵棋的优先度在下新棋之上,在赢棋的优先度之下。

堵棋共有四种堵法:横着堵、竖着堵、左斜堵、右斜堵。
  将堵棋的大致框架写出,并且为了代码的适用性,这里的代码也不要写死,既要适用三行三列的棋盘,也要同样适用于更大的棋盘。(五行五列、十行十列等等)
  当棋盘中不需要堵棋时,返回0;而只要当其中一种情况成立,电脑便落子堵棋,返回1。

//AI人工智能堵棋函数(对玩家的的落子进行分析,实现智能堵棋)(优先级第二) (紫色提示框)
int AI_BlockingChess(char Board[ROW][COL], int row, int col)
{color(5);//紫色int i = 0;int j = 0;//判断所有行里是否有某行出现 XX空 X空X 空XX,三种情况进行智能堵棋for (i = 0; i < row; i++){for (j = 0; j < col - 2; j++){if (Board[i][j] == Board[i][j + 1] && Board[i][j] == 'X' && Board[i][j + 2] == ' '){Board[i][j + 2] = '#';AI_Coordinate(i, j + 2);//将下棋坐标传入AI_Coordinate函数return 1;}if (Board[i][j] == Board[i][j + 2] && Board[i][j] == 'X' && Board[i][j + 1] == ' '){Board[i][j + 1] = '#';AI_Coordinate(i, j + 1);//将下棋坐标传入AI_Coordinate函数return 1;}if (Board[i][j + 1] == Board[i][j + 2] && Board[i][j + 1] == 'X' && Board[i][j] == ' '){Board[i][j] = '#';AI_Coordinate(i, j);//将下棋坐标传入AI_Coordinate函数return 1;}}}//判断所有列里是否有某列出现  // X   X   空// X   空   X// 空   X   X//以上三种情况,进行智能堵棋for (j = 0; j < col; j++){for (i = 0; i < row - 2; i++){if (Board[i][j] == Board[i + 1][j] && Board[i][j] == 'X' && Board[i + 2][j] == ' '){Board[i + 2][j] = '#';AI_Coordinate(i + 2, j);//将下棋坐标传入AI_Coordinate函数return 1;}if (Board[i][j] == Board[i + 2][j] && Board[i][j] == 'X' && Board[i + 1][j] == ' '){Board[i + 1][j] = '#';AI_Coordinate(i + 1, j);//将下棋坐标传入AI_Coordinate函数return 1;}if (Board[i + 1][j] == Board[i + 2][j] && Board[i + 1][j] == 'X' && Board[i][j] == ' '){Board[i][j] = '#';AI_Coordinate(i, j);//将下棋坐标传入AI_Coordinate函数return 1;}}}//判断一条角线(\)里是否有出现//X           X              空//  X           空              X//    空           X               X//以上三种情况,进行智能堵棋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] == 'X' && Board[i + 2][j + 2] == ' '){Board[i + 2][j + 2] = '#';AI_Coordinate(i + 2, j + 2);//将下棋坐标传入AI_Coordinate函数return 1;}if (Board[i][j] == Board[i + 2][j + 2] && Board[i][j] == 'X' && Board[i + 1][j + 1] == ' '){Board[i + 1][j + 1] = '#';AI_Coordinate(i + 1, j + 1);//将下棋坐标传入AI_Coordinate函数return 1;}if (Board[i + 1][j + 1] == Board[i + 2][j + 2] && Board[i + 1][j + 1] == 'X' && Board[i][j] == ' '){Board[i][j] = '#';AI_Coordinate(i, j);//将下棋坐标传入AI_Coordinate函数return 1;}}}//判断一条角线(/)里是否有出现//       X           X           空//     X           空           X//  空           X            X//以上三种情况,进行智能堵棋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] == 'X' && Board[i + 2][j - 2] == ' '){Board[i + 2][j - 2] = '#';AI_Coordinate(i + 2, j - 2);//将下棋坐标传入AI_Coordinate函数return 1;//返回这个棋子的字符}if (Board[i][j] == Board[i + 2][j - 2] && Board[i][j] == 'X' && Board[i + 1][j - 1] == ' '){Board[i + 1][j - 1] = '#';AI_Coordinate(i + 1, j - 1);//将下棋坐标传入AI_Coordinate函数return 1;//返回这个棋子的字符}if (Board[i + 1][j - 1] == Board[i + 2][j - 2] && Board[i + 1][j - 1] == 'X' && Board[i][j] == ' '){Board[i][j] = '#';AI_Coordinate(i, j);//将下棋坐标传入AI_Coordinate函数return 1;//返回这个棋子的字符}}}return 0;
}

(15)先手后手函数

人机对战中选择玩家先手或电脑先手的函数

//人机对战中选择玩家先手或电脑先手的函数
int Xianshou_Houshou()
{int control = 0;while (1){printf(" _____________________________________\n"); Sleep(30);printf("|          1.玩家先手(简单)           |\n");  Sleep(30);printf("|          2.电脑先手(困难)           |\n");  Sleep(30);printf("|_____________________________________|\n"); Sleep(30);printf(" 请选择>:");scanf("%d", &control);while (getchar() != '\n');if (control == 1)return 1;else if (control == 2)return 2;else{printf("选择错误,重新选择");Sleep(750);system("cls");}}
}

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

(16)遍历棋盘函数

  智能三子棋游戏中,我们设置人机对战中玩家可以选择电脑先手下棋或玩家先手下棋,如果电脑先手下棋,棋盘开始时应该是空的,所以我们做一个遍历棋盘函数,根据返回值判断电脑第一步下棋时应该落子的坐标,该函数在AI人工智能下棋函数中被调用。

//遍历棋盘判断棋盘是否为空,电脑先手且棋盘为空的情况下,返回e,非空返回n。
char TraverseBoard(char Board[ROW][COL], int row, int col)
{int flag = 0;for (int i = 0; i < row; i++){for (int j = 0; j < col; j++){if (Board[i][j] != ' '){flag = 'n';    //nonempty 非空return flag;}}}return 'e'; //empty 空
}

(17)电脑下棋提示框函数

   玩家下棋回合有玩家提示框,那么电脑下棋也得有电脑下棋提示框,该函数还可以显示电脑下棋的坐标,在智能三连赢棋函数AI_WinChess,智能堵棋函数:AI_BlockingChess, 自由落子函数ComputerMove被调用。

//打印电脑下棋坐标提示框的函数,参数xy为电脑下棋位置 (函数内部不带颜色)
void AI_Coordinate(int x, int y)
{printf(" __________________________________\n");printf("|  电脑回合,棋子‘#’电脑思考中... |\n");printf("|__________________________________|\n");Sleep(100);printf(" __________________________________\n");printf("|       电脑下棋坐标(%d , %d)        |\n", x + 1, y + 1);//将电脑下棋的坐标展示给玩家。展示时横纵坐标+1后展示。printf("|__________________________________|\n");Sleep(400);
}

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

(18)玩家VS玩家下棋函数

   智能三子棋游戏中除了人机对战还有人人对战的功能,所以应该写一个玩家VS玩家下棋函数 ,来实现人人对战。

//玩家VS玩家下棋函数  (玩家一下棋显示淡绿色提示框)(玩家二下棋显示淡蓝色提示框)
void Player1_VS_Player2(char Board[ROW][COL], int row, int col, int x)
{int i = 0, j = 0;//定义了两个整数变量i和j,用于存储玩家输入的坐标。int ch = 0;if (x == 1)//玩家一{color(10);//淡绿色PrintPlayerMove(4);}if (x == 2)//玩家二{color(9);//淡蓝色PrintPlayerMove(5);}while (1)//开始一个无限循环,这样程序会持续等待玩家的输入,直到玩家输入有效的坐标并下棋break。{scanf("%d%d", &i, &j);while ((ch = getchar()) != '\n' && ch != EOF);//对玩家输入数据进行处理,防止字符造成死循环。if ((i >= 1 && i <= row) && (j >= 1 && j <= col))//如果坐标在棋盘范围内(即1到行数和1到列数之间),则执行以下代码:{if (Board[i - 1][j - 1] == ' ')//检查该坐标位置是否为空。如果为空,表示这个位置可以被下棋{if (x == 1)        //人人对战专用,玩家一回合传参x=1{Board[i - 1][j - 1] = 'X';break;//成功下棋后跳出循环}else if (x == 2)   //人人对战专用,玩家二回合传参x=2{Board[i - 1][j - 1] = '#';break;//成功下棋后跳出循环}}else{PrintPlayerMove(2);//坐标被占用提示框}}else//如果坐标不在棋盘范围内,重新输入。{PrintPlayerMove(3);}}
}

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

在这里插入图片描述
三子棋的输赢判定方式分为五种,一种是横向三个,一种是纵向三个,一种是右下倾斜(\),一种是左下倾斜(/),还有就是是否平局。也就是棋盘下满且双方皆未达成棋子三连的结果。
将框架写好,随后在for循环的内部加入判定部分即可。

//判断输赢函数
char Judgment(char Board[ROW][COL], int row, int col)
{int i = 0;int j = 0;for (i = 0; i < row; i++)//判断i行里是否有棋子连成一行的情况出现{for (j = 0; j < col - 2; j++){if (Board[i][j] == Board[i][j + 1] && Board[i][j + 1] == Board[i][j + 2] && Board[i][j] != ' ')return Board[i][j];//返回这个棋子的字符}}for (j = 0; j < col; j++)//判断j列里是否有棋子连成一列的情况出现{for (i = 0; i < row - 2; i++){if (Board[i][j] == Board[i + 1][j] && Board[i + 1][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 + 1][j + 1] == Board[i + 2][j + 2] && Board[i][j] != ' ')return Board[i][j];//返回这个棋子的字符}}//判断斜线上是否有三个棋子连线的情况出现  (/)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 + 1][j - 1] == Board[i + 2][j - 2] && Board[i][j] != ' ')return Board[i][j];//返回这个棋子的字符}}//上述四种情况都未发生的情况下,说明此时无论玩家或电脑双方皆未赢,程序才会运行到此,此时只剩下继续或平局两种情况for (i = 0; i < row; i++)//通过遍历棋盘,判断棋盘上是否已经下满了,以此判断继续还是平局{for (j = 0; j < col; j++){if (Board[i][j] == ' ')//如果有空格,说明没下满,游戏继续。return 'C';//continue}}return 'Q';//五种情况都未发生,平局。
}

(19)人机对战中玩家赢或电脑赢或平局的提示框函数

 无论是哪一方赢,总得有个结果,所以这里我们做一个提示框函数,作为赢方的结束动画展示。

//打印人机对战中玩家赢或电脑赢或平局的提示框(函数内部不带颜色)
void display_win_or_lost(char x)  //参数传w代表win,打印ch1[],参数传l代表lost,打印ch2[],参数传p代表平局,打印ch3[]
{char ch1[] ="__   __                          _\n""\\ \\ / /                         (_)\n"" \\ V /   ___   _   _  __      __ _  _ __\n""  \\ /  /  _ \\ | | | | \\ \\/ \\ / /| || '_ \\ \n""  | |  | (_) || |_| |  \\ V  V / | || | | |\n""  \\_/   \\___/  \\__,_|   \\_/\\_/  |_||_| |_|\n";char ch2[] ="__   __                   _               _\n""\\ \\ / /                  | |            | |  \n"" \\ V /   ___   _   _     | |  ___   ___ | |_\n""  \\ /  /  _ \\ | | | |    | | / _ \\ / __|| __|\n""  | |  | (_)| | |_| |    | | |(_) |\\__ \\| |_ \n""  \\_/   \\___/  \\__,_|    |_| \\___/ |___/ \\__|\n";char ch3[] ="                                                                                     \n""   #################                             \n""           #                 ###############     \n""    #      #      #         ###           ##     \n""    ##     #     ##         ##            ##     \n""    ###    #     ##         ################     \n""     ##    #    ##          ##                   \n""     ###   #   ###          ##                   \n""      ##   #  ###           #################    \n""       ##  # ###            ##             ##    \n""       ##  # ##             ##  #########  ##    \n""        #  #                ##  ##     ##  ##    \n""  ###################       ##  #       #  ##    \n""           #                ##  #       #  ##    \n""           #                ##  #       #  ##    \n""           #                ##  ##     ##  ##    \n""           #                ##  #########  ##    \n""           #               ##            ##      \n""           #               ##       ########     \n""           #             ##       #######        \n";if (x == 'w')//参数传w代表win,打印ch1[]{for (int i = 0; i < strlen(ch1) - 1; i++){printf("%c", ch1[i]);if (ch1[i] == '\n'){Sleep(50);}}}else if (x == 'l')//参数传w代表lost,打印ch2[]{for (int i = 0; i < strlen(ch2) - 1; i++){printf("%c", ch2[i]);if (ch1[i] == '\n'){Sleep(50);}}}else if (x == 'p')//参数传p代表平局,打印ch3[]{for (int i = 0; i < strlen(ch3) - 1; i++){printf("%c", ch3[i]);if (ch3[i] == '\n'){Sleep(10);}}}
}

效果图展示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(20)游戏主体函数

这块是游戏的重点部分,上面写的所有函数都是为了这里做准备工作,上面所有的逻辑写好以后,我们就可以编写游戏主体函数了,按照一定次序排列,实现整个下棋逻辑。通过不同的参数判断玩家选择是人机对战或人人对战,玩家电脑依次下棋,直到有一方胜出为止,或玩家一,玩家二依次下棋,直到有一方胜出为止。

void Game(int n)//游戏主体函数
{char ret = 0;                    //用于接收判断输赢函数的返回值,返回的四种字符对应棋局的四种情况,定义在头文件中char Board[ROW][COL] = { 0 };    //定义二维数组InitBoard(Board, ROW, COL);      //初始化二维数组DisplayBoard(Board, ROW, COL);   //打印棋盘while (1)//循环内部为人机双方下棋过程或人人对战过程{if (n == 1)//人机对战玩家先手PlayerMove(Board, ROW, COL);if (n == 2)//人机对战电脑先手ComputerMove(Board, ROW, COL);if (n == 3) //人人对战玩家一Player1_VS_Player2(Board, ROW, COL, 1);ret = Judgment(Board, ROW, COL); //判断输赢if (ret != 'C')                  //等于C棋局继续,不等于C跳出循环,根据ret的值判断输赢{break;}system("cls");                   //确认落子后清屏,再打印棋盘DisplayBoard(Board, ROW, COL);   //打印棋盘if (n == 1)//人机对战电脑后手ComputerMove(Board, ROW, COL);if (n == 2)   //人机对战玩家后手PlayerMove(Board, ROW, COL);if (n == 3)  //人人对战玩家二Player1_VS_Player2(Board, ROW, COL, 2);ret = Judgment(Board, ROW, COL);if (ret != 'C'){break;}system("cls");DisplayBoard(Board, ROW, COL);//打印棋盘}if (n == 1 || n == 2)//人机对战的情况下{if (ret == 'X'){display_win_or_lost('w');}else if (ret == '#'){display_win_or_lost('l');}else{color(0XA);display_win_or_lost('p');}}else    //人人对战的情况下{if (ret == 'X'){printf("\n  玩家一胜利\n");}else if (ret == '#'){printf("\n  玩家二胜利\n");}else{color(0XA);display_win_or_lost('p');}}DisplayBoard(Board, ROW, COL);//打印棋盘
}

(21)游戏说明函数

  菜单函数编写好并且游戏主体函数也编写好后,基本的功能框架算是基本完成了了,接下来我们要做的就是实现菜单函数里所希望实现的其他功能,
先实现菜单函数里的游戏说明功能。

void Introduction()
{printf("\n1.游戏分为人机对战和人人对战,双方依次在9宫格棋盘上摆放棋子。\n");printf("\n2.双方轮流落子,每次只能在一个格子上放置一个棋子。\n");printf("\n3.如果将自己的3个棋子连成一条线,则宣告胜利。连线的方向可以是水平、垂直或对角线。\n");printf("\n4.如果在棋盘上形成平局,即双方都没有机会将自己的3个棋子连成一条线,那么游戏结束。\n\n");
}

(22)开发人员菜单函数

  此函数对应主菜单界面的第4个选项开发人员,介绍了版本号,作者信息(我本人),和制作时间,背景音乐等信息,该函数可以控制程序内的音乐打开或关闭。

//开发人员菜单函数(开发人员信息和背景音乐控制)
void kaifa()
{int control = 0;do{system("color B0");printf(" ________________________________________________________\n"); Sleep(30);printf("| 智能三子棋版本v1.1       作者   --->原始豌豆           |\n");  Sleep(30);printf("|                                                        |\n");  Sleep(30);printf("| 制作时间 2024.2.11        音乐   --->纯音乐            |\n");  Sleep(30);printf("|________________________________________________________|\n"); Sleep(30);printf("**************1.开启音乐    0.关闭音乐********************\n");printf("**************      2.回到主界面     *********************\n");printf("请选择>:");scanf("%d", &control);while (getchar() != '\n');switch (control){case 1:BackgroundMusic('s');break;case 0:BackgroundMusic('e');break;case 2:system("cls");//回到主界面前先清屏break;default:printf("\n          选择错误,请重新输入!");system("pause");//界面美化---->控制台停留,实现按任意键继续的效果system("cls"); //界面美化---->清屏,防止玩家多次输入错误造成屏幕占满		break;}} while (control != 2);
}

(23)退出游戏函数

  此函数对应主菜单界面的第5个选项退出游戏,在玩家退出游戏时打印由符号组成的退出两个汉字。

//打印退出游戏字幕
void GameOver()
{char str[] = "                                                                                           \n""    #      ############                    ##                  \n""   ###    ##############                   ##                  \n""   ###    ###        ###         ##        ##        ##\n""    ###   ##          ##         ##        ##        ##\n""     ##     ##            ##          ##        ##         ##\n""     ###  ##############         ##        ##        ##\n""      ##  ##############         ##        ##        ##\n""          ##          ##         ##        ##        ##\n""          ##          ##         ##        ##        ##\n"" ######   ##############         ##        ##        ##\n""  ######  ##############         ###       ##        ##\n""      ##  ######                  #####################\n""      ##  ## ####      ##         #################### \n""      ##  ##  ####    ###        #         ##         #\n""      ##  ##   ####  ####       ###        ##         ##\n""      ##  ##    #######         ###        ##         ##\n""      ##  ##      ####          ###        ##         ##\n""      ##  ##       ###          ###        ##         ##\n""      ##  ##  ###   ###         ###        ##         ##\n""      ##  ## ####    ####       ###        ##         ##\n""     ###  ######      ###       ###        ##         ##\n""    ##### ####         ###      ###        ##         ##\n""   #########                    ###        ##         ##\n"" ##### ###################       #######################\n"" ####    ##################       #####################\n\n";for (int i = 0; i < strlen(str) - 1; i++){printf("%c", str[i]);if (str[i] == '\n'){Sleep(10);}}
}

(24)主函数

上述函数都写好后,在主函数中调用各个函数,即可完成智能三子棋游戏游戏的制作

int main()
{int n = 0;ConsoleSet();//控制台设置BackgroundMusic('s');srand((unsigned int)time(NULL));//生成随机数生成起点//time函数参数是指针,返回值是time_t类型,而srand的参数是无符号整型,所以强制类型转换一下。system("color 02");sanziqi('p');Sleep(2000);sanziqi('c');int input = 0;do {player_vs_computer();color(14);//将菜单界面设置为亮黄色。Menu();//打印菜单scanf("%d", &input);while (getchar() != '\n');system("cls");switch (input){case 1:n = Xianshou_Houshou();Game(n);   //gamegoto_xy(50, 12);system("pause");Sleep(1000);system("cls");break;case 2:Game(3);goto_xy(50, 12);system("pause");Sleep(1000);system("cls");break;case 3:system("color 70");Introduction();system("pause");system("cls");system("color 0E");break;case 4:kaifa();system("cls");system("color 0E");break;case 5:color(8);GameOver();break;default:goto_xy(64, 16);//将输入处的光标定位在括号里面printf("选择错误,重新选择");Sleep(800);system("cls");}} while (input != 5);//当input==5时退出游戏return 0;
}

六、全部源码

后续会发出来,敬请期待

七、项目总结

  经过多次测试和调整,我们的AI在三子棋游戏中展现出了较高的智能水平。它能够在电脑先手的大多数情况下战胜人类玩家,并且具有一定的战术意识和预判能力。虽然我们的AI在三子棋游戏中已经取得了一定的成绩,但仍有很大的提升空间。未来,我们可以进一步优化评估函数和搜索算法,提高AI的智能水平和对抗性。同时,也可以尝试将本项目应用到其他类似的棋类游戏中,以检验算法的通用性和可扩展性。

全文完,感谢观看!

这篇关于人工智能三子棋-人机对弈-人人对弈,谁会是最终赢家?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/703532

相关文章

基于人工智能的图像分类系统

目录 引言项目背景环境准备 硬件要求软件安装与配置系统设计 系统架构关键技术代码示例 数据预处理模型训练模型预测应用场景结论 1. 引言 图像分类是计算机视觉中的一个重要任务,目标是自动识别图像中的对象类别。通过卷积神经网络(CNN)等深度学习技术,我们可以构建高效的图像分类系统,广泛应用于自动驾驶、医疗影像诊断、监控分析等领域。本文将介绍如何构建一个基于人工智能的图像分类系统,包括环境

Codeforces Beta Round #47 C凸包 (最终写法)

题意慢慢看。 typedef long long LL ;int cmp(double x){if(fabs(x) < 1e-8) return 0 ;return x > 0 ? 1 : -1 ;}struct point{double x , y ;point(){}point(double _x , double _y):x(_x) , y(_y){}point op

基于人工智能的智能家居语音控制系统

目录 引言项目背景环境准备 硬件要求软件安装与配置系统设计 系统架构关键技术代码示例 数据预处理模型训练模型预测应用场景结论 1. 引言 随着物联网(IoT)和人工智能技术的发展,智能家居语音控制系统已经成为现代家庭的一部分。通过语音控制设备,用户可以轻松实现对灯光、空调、门锁等家电的控制,提升生活的便捷性和舒适性。本文将介绍如何构建一个基于人工智能的智能家居语音控制系统,包括环境准备

从希腊神话到好莱坞大片,人工智能的七大历史时期值得铭记

本文选自historyextra,机器之心编译出品,参与成员:Angulia、小樱、柒柒、孟婷 你可能听过「技术奇点」,即本世纪某个阶段将出现超级智能,那时,技术将会以人类难以想象的速度飞速发展。同样,黑洞也是一个奇点,在其上任何物理定律都不适用;因此,技术奇点也是超越未来理解范围的一点。 然而,在我们到达那个奇点之前(假设我们能到达),还存在另一个极大的不连续问题,我将它称之

[Day 73] 區塊鏈與人工智能的聯動應用:理論、技術與實踐

AI在健康管理中的應用實例 1. 引言 隨著健康管理需求的提升,人工智能(AI)在該領域的應用越來越普遍。AI可以幫助醫療機構提升效率、精準診斷疾病、個性化治療方案,以及進行健康數據分析,從而改善病患的健康狀況。這篇文章將探討AI如何應用於健康管理,並通過具體代碼示例說明其技術實現。 2. AI在健康管理中的主要應用場景 個性化健康建議:通過分析用戶的健康數據,如飲食、運動、睡眠等,AI可

2024年高教社杯数学建模国赛最后一步——结果检验-事关最终奖项

2024年国赛已经来到了最后一天,有必要去给大家讲解一下,我们不需要过多的去关注模型的结果,因为模型的结果的分值设定项最多不到20分。但是如果大家真的非常关注的话,那有必要给大家讲解一下论文结果相关的问题。很多的论文,上至国赛优秀论文下至不获奖的论文并不是所有的论文都可以进行完整的复现求解,大部分数模论文都为存在一个灰色地带。         白色地带即认为所有的代码均可运行、公开

知名AIGC人工智能专家培训讲师唐兴通谈AI大模型数字化转型数字新媒体营销与数字化销售

在过去的二十年里,中国企业在数字营销领域经历了一场惊心动魄的变革。从最初的懵懂无知到如今的游刃有余,这一路走来,既有模仿学习的艰辛,也有创新突破的喜悦。然而,站在人工智能时代的门槛上,我们不禁要问:下一个十年,中国企业将如何在数字营销的浪潮中乘风破浪? 一、从跟风到精通:中国数字营销的进化史 回顾过去,中国企业在数字营销领域的发展可谓是一部"跟风学习"的编年史。从最初的搜索引擎营销(SEM),

通学人工智能一

AI 工具 1. 语言与内容创作工具 Heygen: 全球语言转换,创建逼真的数字人。系统主要是英文的,但可以通过微软小冰实现中文支持。 Predis.ai: 制作图文内容以及简单的视频。 通义听悟 & 讯飞语记: 帮助收集灵感并将其整理成文案。 2. 设计与图片生成 Pic Copilot: 自动生成电商网站。 Codia AI: 擅长将截图 1:1 复制成原图,并生成相关代码。 In

人工智能时代开启ai代写模式,让创作变得更加简单!

随着人工智能技术的飞速发展,我们的生活和工作方式正在发生翻天覆地的变化。在这个信息爆炸的时代,内容创作领域也迎来了新的变革——ai代写。这一模式的出现,让文章写作变得更加简单高效,为创作者们打开了新的可能。   一、ai代写的优势   提高写作效率   在传统写作过程中,创作者需要花费大量时间和精力进行资料搜集、构思和撰写。而ai代写能够在短时间内完成这些工作,大大提高了写作效率。创

[Day 72] 區塊鏈與人工智能的聯動應用:理論、技術與實踐

區塊鏈在跨境支付中的應用 跨境支付一直是全球經濟中極具挑戰的領域。傳統的跨境支付系統通常需要數天時間來處理交易,涉及的中間機構多且手續費昂貴。然而,區塊鏈技術的出現為解決這些問題提供了一條嶄新的途徑。本文將探討區塊鏈在跨境支付中的應用,並通過代碼示例展示如何使用區塊鏈技術來優化跨境支付流程。 1. 區塊鏈在跨境支付中的優勢 區塊鏈技術具有去中心化、透明、高效和安全等特性,使其在跨境支付領域具