在 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 的機器人。