智能失误:如何让AI不那么聪明(下)
原文:Intelligent Mistakes: How to Incorporate Stupidity Into Your AI Code
作者:Mick West
翻译:Tommo
隐藏的缺陷
电脑象棋专家Steven Lopez是在描述人与人之间的象棋对弈时说:一个高段的棋手与一个低段的棋手对弈时,高段的棋手可以在开始前让给对方几个棋子。这样一来,就算高段棋手倾尽全力而不是故意在棋局当中“放水”给对手机会,比赛也不会呈一边倒的局势。
尽管如此,人与电脑之间的对弈并不是像这样依靠“让子”来取得平衡,而是选择“水平”大致相近的AI对手。
电脑棋手Fritz的作者采用了这样的办法:AI先是故意设下一个人类对手(在一些考虑后)可以取得优势的局面,比如棋子或是位置。一旦人类玩家获得了这个优势,AI就恢复到“全力争胜”的模式。
AI从来不会真的“秀逗”,也许有时看起来像,但它实际上是在进行着数量更多的计算,这些计算往往也比“正常”的时候更为复杂。
至此,AI的目标已经从“赢得比赛”转换到“佯装要赢,但留给人类一线之机,然后再赢回来”对于AI来说,它真的需要些“大智”才能“若愚”。
扑克的AI

我在给 Left Field’s World Series of Poker编写AI的时候, 每个难度下的AI的计算基本上是一样的:电脑会在已知牌面的基础上推算出胜利的可能性,然后根据对手的下注历史来推断对手的牌的好坏。这些可能性之后被用于计算回报率,并最终决定是放弃、跟注还是加注。
实际上还有一些特殊的规则和例外,但上面所说的是最基本的。所有的AI玩家都会进行相同的计算,通过数万种假设的牌面可能来计算回报率。在这些计算完成之后,每个AI才开始执行各自不同的计算。这时,最“聪明”的玩家会选择最优的行动,而较“笨”的玩家则可能会“放水”。
对于比较弱的扑克AI来说,想要“放水”需要先明确自己应该做什么,然后故意不做,并且要让这种行为看起来不是那么“白痴”。
比如,如果人类玩家刚刚加了一个大注,而你又知道有75%的机会你手里的牌是最好的,这时要“放水”的话,选择“放弃”就可以了。尽管AI玩家拥有很高的赢面,但它正在模拟一个比较弱的人类玩家——这样的玩家在不清楚自己的赢面又看到对方加大注时,往往选择放弃。
相反的,较弱的人类玩家在赢面较小的时候也经常会跟注。这是一种很自然的行为,同时也是我们削弱AI强度的一种好办法,而且它看起来也不是什么“弱智”的行为。
智能的失误以一种概率化形式来实现。“放水”的AI不会总是在人类玩家虚张声势的时候放弃——它们只是更倾向于这么做。
这个AI在高随机性的扑克游戏当中运行得很好,因为人类玩家无法在情报有限的情况分辨出电脑是否正在“放水”。
因为AI一直在进行完整的上百万次的计算,所以它不可能做出人类无法理解的失误,而同时,利用“鲁莽”的决策让AI变得“愚蠢”则可以让游戏更为均势,这让水平一般或较差的玩家也可以乐在其中。
人为的失准
在桌球或是射击游戏当中,电脑AI可以保持无往不胜的准确性。射击AI可以把弹道精确到万分之一英寸,并在五公里外打飞你的帽子。而在桌球里,AI知道所有球的精确座标,并可以在击球前知道所有球之后的走位。
当我在实现我自己的斯诺克AI时,它可以完美地反弹两次然后打落任何球,而且几乎可以每次都打满147分(除非白球落袋,因为没有控制走位)
显然,这家伙不是什么有趣的对手,所以就算在最高等级的难度当中,准确性依然需要降低,而反弹击球更是要被严格地限制。
简单地降低AI的准度并不总是改善游戏性的最优解。就好像我在开篇时提到的“不存在的走位控制”,随机的输出很可能让电脑的行为看起来是“有意的”。如果白球停在了一个有利的位置,又或者幸运地叫到了黑桃同花顺,人们会认为这是不公平的甚至会认为AI在作弊。
所以,在棋类游戏当中,与其降低准度,倒不如提高准确率,同时让AI创造出玩家可以获益的局面,以此让游戏过程变得刺激;在台球游戏中,不要无所顾虑盲目地击球,AI应该在故意打偏的时候让白球走到一个更加利于玩家的位置; 而在射击游戏里,敌人不能总是随机地高呼“向我开炮”然后跳出掩体。他们应该只是“偶尔大意”地把自己扔到枪口下,并且应该是在最尊贵的观众——玩家——靠近自己的时候。
Luck of the Draw
(注:一种桌面游戏,玩家需要拿起铅笔来画画。先从题材卡里抽一张,然后扔骰子选出一个题材,比如“长城”,然后以沙漏计时,在限时内完成自己的作品,再把所有作品洗混,翻开放到桌面上,并放置不同颜色的标记,这时再扔骰子决定抽多少张投票卡,依次抽出,玩家各拿取一个投票轮盘,秘密选出心目中的佳作,但是投票的选项都是很奇怪的,比如最丑的、最可怕的、最混乱的、最扣人心弦的,最没有艺术性的,所以看来并不是画的好才能获奖,投票后得票最多的可以获得投票卡,表示1分,若获得的相同投票数,则得到半分。根据玩家人数拿到一定数量的投票卡则结束,最多投票卡的玩家获胜。)
和一个完美的对手比赛并不有趣,但是与一个残疾的对手比赛也一样。为了更加有趣的游戏性,我们需要引入“人工愚蠢”和智能失误。
智能失误看起来像是写坏了的AI,但它们实际上同样需要仔细的计算才能为人类玩家提供更多的娱乐性。智能失误并不是要消除困难,因为玩家仍然需要一定的技巧才能胜出。
对于程序员来说,增加智能失误要比简单地降低AI的准确性复杂得多,但这些额外的努力才带来更完善的玩家体验。
参考资源:
Liden, Lars. “Artificial Stupidity: The Art of Intentional Mistakes,” in AI Game Programming Wisdom 2, Charles River Media, 2004.
http://lars.liden.cc/Publications/Downloads/2003_AIWisdom.pdf
Lopez, Steven. “Intelligent Mistakes,” Chessbase News, 2005.
http://www.chessbase.com/newsdetail.asp?newsid=2579
REPLY))
好文好译!
呵呵,有阵子没到你这来逛了,一上来就发现站点改版了,贺一个。
REPLY))
如果有兴趣你也可以来发点东西,网站后台换成了Wordpress,使用上要比以前舒服不少。
:)
REPLY))
开始关注这里了…
译文很强大~收获很多…
我想学习游戏开发,
只使用过rmxp、krkr这类开发工具,没有接触过主流编程语言…
但是…我肯学…
能否给些建议?
比如语言、引擎、或者开发工具的选择?
p.s:貌似曾经在chinaavg里发现过博主…
REPLY))
@sad.eyed.kid
这看你希望做些什么了。 专业的游戏程序需要学习的东西和独立开发需要的东西还是有不小的区别的。
应该还是从脚本语言开始,因为这样可以比较快看到效果。脚本语言学lua或是python都是很好的,因为它们都是相当普及的语言,可以让你一直受用。
lua有一个简单的2D引擎叫love的,pyGame则是python圈比较流行的引擎。
除了游戏方面的东西,通用的编程知识也该学一些,像数据结构之类的。
如果英文好的话,那就天天Google吧,到处都有东西可以学。
@PS: chinaavg现在不常去了,没时间玩AVG……