游戏中的人机对战是啥原理?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了游戏中的人机对战是啥原理?相关的知识,希望对你有一定的参考价值。
参考技术A 人机中的“机”就是指电脑AI,它的行为就是一系列提前设计好的行为根据不同条件租和成的,专业点叫做“行为树”程序员可以提前设计好电脑的行为,跑、跳、攻击、防守等等,然后将其与条件绑定在一起。比如玩家跑,电脑就执行跑;玩家攻击,电脑就执行防御;玩家不动,电脑就执行攻击;
人机对战的难度,其实就是电脑AI设置的难度,你觉得电脑简单,是因为这个难度设计的状态行为相对简单。
人机中的套路,基本上就是电脑的程序漏洞,除了电脑自行学习和随机要素两点之外,在A条件下必定触发B动作的情况,还是非常多的,只要玩家抓住这种技巧,就能轻松战胜电脑。各种类型的 游戏 中都能找到体现。
人机对战就是这么简单的原理
你好,我是阿恒,非常愿意解答这个问题。
首先和人机对战的人无非就三种心理。
1.体验乐趣的心理,有许多小伙伴打匹配模式打不赢玩家,老是被他人单杀,这这就让他十分恼火,感觉打不赢,所以才会去打人机,体验赢的感觉。
2.优越的心理。那些在匹配模式打不赢玩家的小伙伴,就想在人机中大杀四方,体验优越的感觉。
3.提升自己技术的心理。有的小伙伴,为了把某些英雄玩好,不坑队友,就疯狂的打人机去练习自己的技术,只为把这个英雄玩好。
如果大家觉得阿恒说的有道理,可以关注一下,非常乐意和大家一起分享 游戏 里的日常。
游戏 中的人力对战,或者说NPC(怪物也可以说成 游戏 里面的NPC)的AI主要采用“行为树”和“状态机”两种模式。(比较形象的解释,可能不太准确)行为树就像给了你很多锦囊,符合哪种条件你就开锦囊,然后按照指示继续做。状态机就像竖了几个牌,符合这个状态你就要做什么。行为树和状态机和单独使用,也可以结合使用。
我举个例子:在一个MMO 游戏 中的小怪,比如1级哥布林。他被放入了几条命令。
1:会在A→B之间来回巡逻(忽略速度)。
2:可以发现周身半径5米的敌人。
3:求救技能,可以寻找周身半径5米以内的同类来帮助,释放条件时自身血量少于50%。
4:战斗,直至死亡。
看到这几个简单的命令,我们可以想象到。我从这个哥布林身边经过,他就发现我,然后开打。打到一半发现搞不过我,就呼叫同伴来群殴(1级怪物有这个难度有点卑鄙)。不会逃跑(还好),然后力战而死。
这就是一个简单的行为树的NPC的AI设计方案。
所以以前不论是MMO的BOSS,还是MOBA、FPS、赛车等等其他类型的 游戏 ,我们可以设置很多很复杂的条件。这种情况考虑的越周密,那么玩家能够感到这个AI越难,或者越真实。总之,就是靠设计者不断地去添砖加瓦,丰富这个AI。
2、在深度学习算法出来以后,目前大多数 游戏 的怪物AI还是采用以前的模式,深度学习算法更多的被运用到匹配等规则较明确的功能当中。 游戏 中为什么不用深度学习算法来做AI呢?有几个先决条件要解决:
1:如何将你的规则明确化。深度学习算法不是万金油,你得先让电脑懂这套规则,才能开始学习。电脑不是人类,教几次就会,你得帮他总结规则。所以规则复杂的 游戏 ,有一道坎。万一你版本更新,改规则了,又得让机器知道,帮他重新迭代下。程序想要打死产品经理的节奏。
2:通过人机对战获得大数据。这个在尤其上线运营之后还好解决,不过研发阶段就得自己想办法机器和机器打了。
虽然新闻上说深度学习算的电脑可以玩星际争霸,玩dota等等。但是让他来玩我们 游戏 试试?
以上是一个门外汉的介绍,不对勿怪。
AI 游戏 里的机器人十分复杂,首先他有不同的状态,而在不同的状态条件下执行不同的行为。你要让AI像人,那你得把人的行为尽可能的用树状结构进行分类并且得出不同的执行目标。
这里就要提到机器学习,机器学习是什么呢?——使计算机无需编程即可行动的科学。深度学习是机器学习的一个子集,用非常简单的术语来说,它可以被认为是预测分析的自动化。常用的机器学习算法有:
监督学习:标记数据集,以便可以检测模式并用于标记新数据集
无监督学习:数据集未标记,并根据相似性或差异进行排序
强化学习:数据集没有标记,但在执行动作或多个动作后,AI系统会得到反馈
所以,在提到AI的时候总是和大数据相关联,没有数据的支持人工智能离人工智障不远了。
这个非常的简单其实他就是一段程序。
举个大家都比较熟悉的例子,早先还没有互联网的年代,就有了很多PC 游戏 (或者其他形式)。这种 游戏 都是单机的(受当时互联网的限制)。拿一个单机的象棋 游戏 来说,制作者想让这个 游戏 有市场,有人爱玩。那么首先要解决的就是玩家跟谁玩的问题。在那个年代,能做的事情最简单的就是用程序去模拟一个对手。至于怎么模拟,设计的人显然就是要用程序去实现一种方式,让玩家感觉“对手”像人。那么这段程序其实是“机器”在跑,只不过模拟人的行为,所以就有了人机对战这个说法。
可以算是一种人工智能算法,但是那个年代应该还没有机器学习。当然,如果一个 游戏 的“机器”代码,写的复杂一点,能不停的从跟玩家对战的行为中不断的建立自己的“数据库”,并从中演化出更深、更广的行为,其实也就是在机器学习了。我相信在现在的机器学习的词语出现前,一定有这样的 游戏 。但是 游戏 中的AI定义和目前科学上的AI定义不完全一样。
科学的AI比较偏向机器学习,也就是得学习的。
游戏 中绝大多数的AI都是定死的逻辑,也不用学习。比如最常见的就是警戒范围,在魔兽3里的有攻击性的中立单位,如果你不靠近到一定范围内,他是不会靠近攻击的。
。
段位越高人机越强,且自带透视 在皇冠局及以上没抢碰到人机基本上就是死
就是玩家和电脑bot对战
1让萌新练枪提高自己的胆识
2可以更好的帮助听声辩位
3可以算人头分
4可以提高自己的kda
有请坦克世界资深AI之父,二雷来回答。
人机就是AI, 游戏 团队设置的AI,所以他可以与你对战
井字棋(人机对战版)
游戏介绍
井字棋,英文名叫Tic-Tac-Toe,是一种在3*3格子上进行的连珠游戏,和五子棋类似。然后由分别代表O和X的两个游戏者轮流在格子里留下标记(一般来说先手者为X),任意三个标记形成一条直线(包括行、列、对角线、反对角线),则为获胜。
解决策略
重点在于电脑方如何下棋,我们采取估计棋局每个位置的权重,首先要对棋局进行分类。
---3个为空,重要性最低,权值设置为1 //视为暂时不管
---2个空1个对方,重要性次低,权值为10 //一下三个区别不大,可比较随意的设置
----1个空格1个对方1个己方,重要行较低,权值50
----2个空格1个己方,重要性较高,权值为100
---1个空格2个对方,重要性次高,权值500 //不堵住会输
---1个空格2个己方,重要性最高,权值1000 //可以直接赢
注意几点:
1、权值之间的间距可以设大一点
2、对每个空位置,权值等于行权值+列权值+对角线权值+反对角线权值,这4中权值都可以用上面的估算,但不做改进会出bug
考虑如下情况:
(1,3)-->(3,1)-->(1,1)-->(2,1)电脑就输了
---->--->-->-->人获胜
关键在于第二步,应该选择一个非角的位置,原因在于此时右上角位置的权值大于中上位置,分析权值的来源
右上角时,10+10+100(对角线己方),而中上时,10+100(行己方),所以同样是2空1己方时,己方位于行或列的权重应大于己方位于对角线。
所以按行或列计算时,2空1己方的权值可改为200
代码实现
1 #include<stdio.h> 2 #include<Windows.h> 3 4 const int ROW = 3; 5 const int COL = 3; 6 int chessboard[ROW][COL]; 7 int score[ROW][COL]; 8 9 void Initmap(); 10 void Showmap(); //打印棋局 11 bool isWin(); //判断是否有一方获胜 12 bool isFull(); //判断棋盘是否为满 13 void PcPlay(); //电脑下棋 14 void HumanPlay(); //人下棋 15 16 int main() 17 { 18 Initmap(); 19 Showmap(); 20 while ((!isFull()) && (!isWin())) 21 { 22 HumanPlay(); 23 system("cls"); 24 Showmap(); 25 if (isWin()) 26 break; 27 28 Sleep(500); //模拟实际过程,让电脑慢点,hh 29 PcPlay(); 30 system("cls"); 31 Showmap(); 32 } 33 34 if (isFull()) 35 printf(" 平局 "); 36 37 system("pause"); 38 return 0; 39 } 40 41 void Initmap() 42 { 43 for (int i = 0; i < ROW; i++) 44 for (int j = 0; j < COL; j++) 45 chessboard[i][j] = 1; 46 } 47 48 void Showmap() 49 { 50 for (int i = 0; i < ROW; i++) 51 { 52 for (int j = 0; j < COL; j++) 53 { 54 if (chessboard[i][j] == 1) //"1"代表空 55 printf("□"); 56 if (chessboard[i][j] == 2) //"2"代表人 57 printf("■"); 58 if (chessboard[i][j] == 5) //"5"代表电脑 59 printf("●"); 60 } 61 printf(" "); 62 } 63 } 64 65 bool isWin() 66 { 67 int sum = 0; 68 for (int i = 0; i < ROW; i++) //对每行判断是否获胜 69 { 70 for (int j = 0; j < COL; j++) 71 sum += chessboard[i][j]; 72 73 if (sum == 6) 74 { 75 printf("人获胜! "); 76 return true; 77 } 78 if (sum == 15) 79 { 80 printf("电脑获胜! "); 81 return true; 82 } 83 sum = 0; 84 } 85 86 for (int j = 0; j < ROW; j++) //对每列判断是否获胜 87 { 88 for (int i = 0; i < COL; i++) 89 sum += chessboard[i][j]; 90 91 if (sum == 6) 92 { 93 printf("人获胜! "); 94 return true; 95 } 96 if (sum == 15) 97 { 98 printf("电脑获胜! "); 99 return true; 100 } 101 sum = 0; 102 } 103 104 for (int i = 0; i < ROW; i++) //对对角线判断是否获胜 105 sum += chessboard[i][i]; 106 if (sum == 6) 107 { 108 printf("人获胜! "); 109 return true; 110 } 111 if (sum == 15) 112 { 113 printf("电脑获胜! "); 114 return true; 115 } 116 117 sum = 0; 118 for (int i = 0; i < ROW; i++) //对反对角线判断是否获胜 119 sum += chessboard[i][2 - i]; 120 if (sum == 6) 121 { 122 printf("人获胜! "); 123 return true; 124 } 125 if (sum == 15) 126 { 127 printf("电脑获胜! "); 128 return true; 129 } 130 131 return false; 132 } 133 134 bool isFull() 135 { 136 for (int i = 0; i < ROW; i++) 137 for (int j = 0; j < COL; j++) 138 if (chessboard[i][j] == 1) 139 return false; 140 return true; 141 } 142 143 void HumanPlay() 144 { 145 int x, y; 146 printf("请输入棋子的横坐标X:"); 147 scanf_s("%d", &x); 148 printf("请输入棋子的纵坐标Y:"); 149 scanf_s("%d", &y); 150 151 while (x < 1 || x>3 || y < 1 || y>3) 152 { 153 printf(" 请正确输入! "); 154 printf("x,y均属于1~3 "); 155 156 printf("请输入棋子的横坐标X:"); 157 scanf_s("%d", &x); 158 printf("请输入棋子的纵坐标Y:"); 159 scanf_s("%d", &y); 160 } 161 162 while (chessboard[3 - y][x - 1] != 1) 163 { 164 printf(" 该位置已被占用! "); 165 printf("请选择正确的位置 "); 166 Sleep(1000); 167 168 printf(" 请输入棋子的横坐标X:"); 169 scanf_s("%d", &x); 170 printf("请输入棋子的纵坐标Y:"); 171 scanf_s("%d", &y); 172 } 173 174 chessboard[3 - y][x - 1] = 2; 175 } 176 177 void PcPlay() 178 { 179 int sum = 0; 180 for (int i = 0; i < ROW; i++) 181 for (int j = 0; j < COL; j++) 182 score[i][j] = 0; 183 184 // 对每行进行分数统计 185 for (int i = 0; i < ROW; i++) 186 { 187 for (int j = 0; j < COL; j++) 188 sum += chessboard[i][j]; 189 190 switch (sum) 191 { 192 case 3: //1+1+1;重要性:最低;权重:1 193 for (int k = 0; k < COL; k++) 194 { 195 if (chessboard[i][k] == 1) 196 score[i][k] += 1; 197 } 198 break; 199 case 4: //1+1+2;重要性:次低;权重:10 200 for (int k = 0; k < COL; k++) 201 { 202 if (chessboard[i][k] == 1) 203 score[i][k] += 10; 204 } 205 break; 206 case 8: //1+2+5;重要性:较低,权值50 207 for (int k = 0; k < COL; k++) 208 { 209 if (chessboard[i][k] == 1) 210 score[i][k] += 50; 211 } 212 break; 213 case 7: //1+1+5;重要性:较高;权重:200 214 for (int k = 0; k < COL; k++) 215 { 216 if (chessboard[i][k] == 1) 217 score[i][k] += 200; //把行列的重要性比对角线高 218 } 219 break; 220 case 5: //1+2+2;重要性:次高;权重:500 221 for (int k = 0; k < COL; k++) 222 { 223 if (chessboard[i][k] == 1) 224 score[i][k] += 500; 225 } 226 break; 227 case 11: //1+5+5;重要性:最高;权重:1000 228 for (int k = 0; k < COL; k++) 229 { 230 if (chessboard[i][k] == 1) 231 score[i][k] += 1000; 232 } 233 break; 234 } 235 sum = 0; 236 } 237 238 // 对每列进行分数统计 239 for (int j = 0; j < COL; j++) 240 { 241 for (int i = 0; i < ROW; i++) 242 sum += chessboard[i][j]; 243 244 switch (sum) 245 { 246 case 3: 247 for (int k = 0; k < COL; k++) 248 { 249 if (chessboard[k][j] == 1) 250 score[k][j] += 1; 251 } 252 break; 253 case 4: 254 for (int k = 0; k < COL; k++) 255 { 256 if (chessboard[k][j] == 1) 257 score[k][j] += 10; 258 } 259 break; 260 case 8: 261 for (int k = 0; k < 262 COL; k++) 263 { 264 if (chessboard[k][j] == 1) 265 score[k][j] += 50; 266 } 267 break; 268 case 7: 269 for (int k = 0; k < COL; k++) 270 { 271 if (chessboard[k][j] == 1) //1+1+5;重要性:较高;权重:200 272 score[k][j] += 200; 273 } 274 break; 275 case 5: 276 for (int k = 0; k < COL; k++) 277 { 278 if (chessboard[k][j] == 1) 279 score[k][j] += 500; 280 } 281 break; 282 case 11: 283 for (int k = 0; k < COL; k++) 284 { 285 if (chessboard[k][j] == 1) 286 score[k][j] += 1000; 287 } 288 break; 289 } 290 sum = 0; 291 } 292 293 // 对对角线进行分数统计 294 for (int i = 0; i < ROW; i++) 295 sum += chessboard[i][i]; 296 switch (sum) 297 { 298 case 3: 299 for (int i = 0; i < COL; i++) 300 { 301 if (chessboard[i][i] == 1) 302 score[i][i] += 1; 303 } 304 break; 305 case 4: 306 for (int i = 0; i < COL; i++) 307 { 308 if (chessboard[i][i] == 1) 309 score[i][i] += 10; 310 } 311 break; 312 case 8: 313 for (int i = 0; i < COL; i++) 314 { 315 if (chessboard[i][i] == 1) 316 score[i][i] += 50; 317 } 318 break; 319 case 7: //1+1+5;权重:100 320 for (int i = 0; i < COL; i++) 321 { 322 if (chessboard[i][i] == 1) 323 score[i][i] += 100; 324 } 325 break; 326 case 5: 327 for (int i = 0; i < COL; i++) 328 { 329 if (chessboard[i][i] == 1) 330 score[i][i] += 500; 331 } 332 break; 333 case 11: 334 for (int i = 0; i < COL; i++) 335 { 336 if (chessboard[i][i] == 1) 337 score[i][i] += 1000; 338 } 339 break; 340 } 341 342 // 对反对角线进行分数统计 343 sum = 0; 344 for (int i = 0; i < ROW; i++) 345 sum += chessboard[i][2 - i]; 346 switch (sum) 347 { 348 case 3: 349 for (int i = 0; i < COL; i++) 350 { 351 if (chessboard[i][2 - i] == 1) 352 score[i][2 - i] += 1; 353 } 354 break; 355 case 4: 356 for (int i = 0; i < COL; i++) 357 { 358 if (chessboard[i][2 - i] == 1) 359 score[i][2 - i] += 10; 360 } 361 break; 362 case 8: 363 for (int i = 0; i < COL; i++) 364 { 365 if (chessboard[i][2 - i] == 1) 366 score[i][2 - i] += 50; 367 } 368 break; 369 case 7: 370 for (int i = 0; i < COL; i++) 371 { 372 if (chessboard[i][2 - i] == 1) //1+1+5;权重:100 373 score[i][2 - i] += 100; 374 } 375 break; 376 case 5: 377 for (int i = 0; i < COL; i++) 378 { 379 if (chessboard[i][2 - i] == 1) 380 score[i][2 - i] += 500; 381 } 382 break; 383 case 11: 384 for (int i = 0; i < COL; i++) 385 { 386 if (chessboard[i][2 - i] == 1) 387 score[i][2 - i] += 1000; 388 } 389 break; 390 } 391 392 int maxRow = 0, maxCol = 0; 393 for (int i = 0; i < ROW; i++) 394 for (int j = 0; j < COL; j++) 395 { 396 if (score[i][j] > score[maxRow][maxCol]) 397 { 398 maxRow = i; 399 maxCol = j; 400 } 401 } 402 chessboard[maxRow][maxCol] = 5; 403 }
以上是关于游戏中的人机对战是啥原理?的主要内容,如果未能解决你的问题,请参考以下文章