在 Python Battle 中,坐标系统的范围从 (1,1) 到 (10,10)。和之前的 Pygame 一 样,坐标的原点在左上角。游戏区域的四面都被墙围住。我们可以用 self.robot.position
来找到机器人在坐标系统中的位置。
方向
使用数字 0~3 来存储方向。0 是上(北),1 是右(东),2 是下(南),3 是左(西)。当机器人右转时,方向的值加 1;当机器人左转时,方向的值减 1。这样用起来很简单。我们可以使用 self.robot.rotation
来获取机器人的方向。
calculateCoordinates
calculateCoordinates
函数接受三个参数:distance
、direction
和 position
。它用于查找在 direction
方向上离 position
距离为 distance
的方块。例如,calculateCoordinates(2,3,(5,5))
用于查找距离 (5,5) 左边(左边方向值为 3)2 个方块远的方块。
现在我们可以想出一个策略。我采用一个很简单的策略:
1. 向着敌人所在的方向前进。
2. 如果可能,则发动攻击。
我们从前一个机器人的一些基础代码开始:
class AI: def __init__(self):pass def turn(self):if self.robot.lookInFront == "bot": self.robot.attack
这段代码会处理我们策略的第二部分:“如果可能,则发动攻击。”现在我们需要处理第一部分。我们将下面的代码加到 turn
函数中:
else: self.goTowards(self.robot.locateEnemy[0])
这会调用 AI 类的方法 self.goTowards
并传入敌人的位置作为参数。self.robot.locateEnemy
方法会返回一个包含敌人位置和方向的列表。如果你运行这段代码,它不会正常工作,因为我们还没有定义 self.goTowards
。现在我们来定义它:
def goTowards(self,enemyLocation): myLocation = self.robot.position delta = (enemyLocation[0]-myLocation[0], enemyLocation[1]-myLocation[1])
首先算出 delta,即目标位置和机器人位置的差距。然后,你需要知道要想面向敌人,机器人应该面向哪个方向:
现在你需要沿着这个方向走。如果已经面向这个方向的话,则很简单:
if self.robot.rotation == targetOrientation: self.robot.goForth
否则,你需要找到应该往哪个方向转。首先,你需要知道如果要转到正确的方向,需要左转多少次:
else: leftTurnsNeeded = (self.robot.rotation - targetOrientation) % 4
接下来,需要转到正确的方向。如果需要左转 2 次以上,则可以只右转 1 次:
if leftTurnsNeeded <= 2: self.robot.turnLeftelse: self.robot.turnRight
以下是机器人的完整代码。
代码清单 26-2 更复杂的机器人
现在,我们来试着挑战一下 CircleAI。我确信我们的辛苦工作会得到回报,我们一定能打败它。将 AI 保存为 morecomplicatedai.py,然后重新运行 Python Battle:
>>>Enter red AI: circleaiEnter blue AI: morecomplicatedai . . .Red wins with 10 health!
我想我们需要稍微修订一下策略以便打败 CircleAI。CircleAI 这么难打败,主要是因为我们很难打到它。如果你打算从侧面或者后面攻击它,那么在你第二次打到它之前它就会跑掉。同时,因为它靠墙走,所以你只有一个侧面可以攻击。如果你从前面攻击的话,它就很可能拿到第一次攻击的机会并最终获胜。尽管 CircleAI 不是最高级的策略,但它确实很难打败。
你也许能设计出一个可以稳妥打败 CircleAI 的 AI,但前提是你知道自己要对付的 AI 是 CircleAI。如果你不知道对方 AI 将要使用的策略,打败它将更加困难!
你学到了什么
在这一章,你学到了以下内容。
游戏是怎么运用 AI 让敌人变聪明的。
如何在 Python Battle 游戏中创建自己的 AI。
动手试一试
修订我的策略,尝试设计出一个能打败 CircleAI 的机器人。