CodeCombat 函数与返回值

函数返回值:编程的“超级大脑”(19-26关)

第 19 关

树精树林 (Burlwood)

战术思路分析:排除法决策

英雄必须攻击敌人,但不能攻击友好的**树精("burl")**。我们创建一个函数 `shouldAttack(target)`,让它替英雄思考:**“我应该攻击这个目标吗?”**

返回值类型:布尔值 (True/False)

函数通过返回 `True` 或 `False` 来给出明确的答案。
1. 如果目标不存在或它是树精,函数返回 `False`。
2. 否则,函数执行到底,默认返回 `True` (可以攻击)。
英雄的主代码只需要检查 `if shouldAttack(enemy):` 即可。

shouldAttack(Target)

True or False

Python 程序解法

1
def shouldAttack(target):
定义决策函数,接收目标
2
# return False 如果没有`target`
3
if not target:
如果目标不存在
4
return False
返回 False,停止执行
5
# return False 如果target.type == "burl"
6
if target.type == "burl":
如果目标是树精
7
return False
返回 False,停止执行
8
# 否则 return True
9
return True
否则返回 True
10
11
while True:
12
enemy = hero.findNearestEnemy()
13
# heroShouldAttack将被赋值为shouldAttack()返回的值!
14
heroShouldAttack = shouldAttack(enemy)
调用函数,结果是 True/False
15
if heroShouldAttack:
如果返回值为 True
16
hero.attack(enemy)
发起攻击
第 20 关

盲距 (Blind Spot)

战术思路分析:返回距离

英雄担任盲人巫师的“观测手”,需要测量并说出敌人的距离。这次函数不再返回 True/False,而是返回一个**数字**。

数值返回与哨兵值 (Sentinel Value)

`nearestEnemyDistance()` 函数会做两件事:
1. 如果有敌人,返回精确的距离 (`hero.distanceTo(enemy)`)。
2. 如果没有敌人,返回 `0`。这个 `0` 是一个特殊的**哨兵值**,告诉调用者:“虽然没找到,但别报错,结果是 0。”
主循环通过检查 `if enemyDistance > 0:` 来知道是否找到了目标。

IF Enemy: return Distance
ELSE: return 0
Say(15.42)

Python 程序解法

1
def nearestEnemyDistance():
定义返回敌人距离的函数
2
enemy = hero.findNearestEnemy()
寻找最近的敌人
3
result = 0
初始化结果为 0 (哨兵值)
4
if enemy:
如果敌人存在
5
result = hero.distanceTo(enemy)
计算并存储实际距离
6
return result
返回距离(0 或实际值)
7
8
while True:
9
# 调用nearestEnemyDistance()并
10
# 将结果保存在变量enemyDistance中。
11
enemyDistance = nearestEnemyDistance()
获取函数返回值
12
# 如果enemyDistance大于0:
13
if enemyDistance > 0:
只有当距离大于 0 (即有敌人) 时
14
# 说出enemyDistance变量的值。
15
hero.say(enemyDistance)
告诉巫师距离
第 21 关

固定打击 (Static Shock)

战术思路分析:安全范围检查

你被困住了,移动会受伤!只能在敌人靠近到攻击范围(3米)时才能反击。我们需要一个“攻击许可”函数。

多重返回路径

`inAttackRange(enemy)` 函数会计算距离,并使用 `if/else` 来决定返回路径:
- `if distance <= 3`: return True
- `else`: return False

IF Distance <= 3: return True
ELSE: return False

Python 程序解法

1
def inAttackRange(enemy):
检查是否在攻击范围内的函数
2
distance = hero.distanceTo(enemy)
计算距离
3
# 几乎所有剑的攻击范围都是3。
4
if distance <= 3:
如果距离小于等于 3
5
return True
返回 True (可以攻击)
6
else:
否则
7
return False
返回 False (不能攻击)
8
9
while True:
10
nearestEnemy = hero.findNearestEnemy()
11
# 把结果保存于canAttack变量中
12
canAttack = inAttackRange(nearestEnemy)
调用函数,结果是 True/False
13
# 如果存储在canAttack中的结果是 True, 则发起攻击!
14
if canAttack:
15
hero.attack(nearestEnemy)
第 22 关

金币猎手 (Coin Hunter)

战术思路分析:机会成本

毒药让英雄不能乱动!只有当硬币在**20米以内**,才值得冒险移动。函数 `isCoinClose(coin)` 接收一个参数 `coin`,专门针对这个硬币对象进行距离检查。

接收参数并返回布尔值

函数接收的 `coin` 参数让它具有通用性,可以检查任何物品的距离。
- 检查:`distance < 20`
- 结果:返回 `True` 或 `False`

return distance < 20

Move IF True

Python 程序解法

1
def isCoinClose(coin):
检查硬币距离的函数,接收硬币对象
2
# 确定与`coin`之间的距离。
3
distance = hero.distanceTo(coin)
计算英雄到硬币的距离
4
# 如果距离小于20:
5
if distance < 20:
6
# 返回 True
7
return True
距离够近,返回 True
8
# 否则:
9
else:
10
# 返回 False
11
return False
距离太远,返回 False
12
13
while True:
14
item = hero.findNearestItem()
15
if item:
如果找到了物品
16
# 如果isCoinClose(item)返回true:
17
if isCoinClose(item):
调用函数,如果为 True 则执行
18
hero.moveXY(item.pos.x, item.pos.y)
移动
第 23 关

返回Agrippa (Return to Agrippa)

战术思路分析:优雅出击

这是一次代码重构(Re-factoring)练习。我们将“判断是否在攻击范围内”的逻辑封装起来,让主循环的代码读起来像流水账一样简单。

函数抽离的价值

- **`enemyInRange(enemy)`:** 负责计算距离并返回 **True** 或 **False**。
- **`cleaveOrAttack(enemy)`:** 负责决定是使用 `cleave` 还是 `attack`。
主循环:`if enemy: if enemyInRange(enemy): cleaveOrAttack(enemy)`,**逻辑清晰,易于维护!**

checkDistance()
return True/False

cleaveOrAttack()

Python 程序解法

1
def enemyInRange(enemy):
检查是否在攻击范围内 (< 5米)
2
# 如果敌人的距离少于5米,则返回True值。
3
distance = hero.distanceTo(enemy)
4
if distance < 5:
5
return True
6
else:
7
return False
8
9
def cleaveOrAttack(enemy):
定义攻击方式 (范围斩或普通攻击)
10
if hero.isReady('cleave'):
如果范围斩准备好了
11
hero.cleave(enemy)
执行范围斩
12
else:
否则
13
hero.attack(enemy)
执行普通攻击
14
15
while True:
16
enemy = hero.findNearestEnemy()
17
if enemy:
如果敌人存在
18
# 调用 enemyInRange 来检查敌人的距离。
19
if enemyInRange(enemy):
如果函数返回 True (在范围内)
20
cleaveOrAttack(enemy)
执行攻击动作
第 24 关

金属探测器 (Metal Detector)

战术思路分析:测量与报告

英雄是炮兵的测距仪。你必须测量到金币的距离。如果找不到金币,则报告 `0`。

返回值类型:数字 (含 0)

- 如果 `coin` 存在,`return distance` (实际数字)。
- 否则,`return 0` (哨兵值)。
**注意:** 必须使用 `else` 语句来确保在找不到硬币时,函数能返回 `0`。

IF Coin: return Distance
ELSE: return 0

Python 程序解法

1
def coinDistance():
测距函数
2
# 找到最近的硬币,
3
coin = hero.findNearestItem()
4
# 如果有一枚硬币,返回到它的距离。
5
if coin:
如果硬币存在
6
distance = hero.distanceTo(coin)
计算距离
7
return distance
返回实际距离
8
# 否则,返回0(零)。
9
else:
否则
10
return 0
返回哨兵值 0
11
12
while True:
13
distance = coinDistance()
获取距离值 (可能是 0)
14
if distance > 0:
如果值大于 0 (即有硬币)
15
# 说`distance`。
16
hero.say(distance)
报告给炮兵
第 25 关

概念挑战. 食人魔入侵者 (Ogre Infiltrator)

战术思路分析:坐标报告

机器人需要敌人的 X 坐标才能发射激光。如果找不到敌人,函数应该返回一个不可能的坐标值,例如 **`-1`**,作为哨兵值。

返回值类型:坐标 (或 -1)

- 如果 `enemy` 存在,`return enemy.pos.x`。
- 否则,Python 函数默认会返回 `None`。为了确保返回值是数字类型(即使是哨兵值),我们需要显式地在 `if` 语句外添加 `return -1`。

IF Enemy: return X
enemyX = getEnemyX()
IF enemyX != -1: Say(X)

Python 程序解法

1
def getEnemyX():
获取敌人 X 坐标的函数
2
enemy = hero.findNearestEnemy()
3
if enemy:
如果敌人存在
4
return enemy.pos.x
返回 X 坐标
5
return -1
否则返回 -1
6
7
while True:
8
enemyX = getEnemyX()
获取 X 坐标 (可能是 -1)
9
if enemyX != -1:
如果 X 不等于 -1 (即有敌人)
10
hero.say(enemyX)
说出坐标,机器人开火
第 26 关

组合挑战. 森林风暴 (Storm)

战术思路分析:三层过滤

这是对函数和布尔逻辑的终极测试。英雄只有在满足以下所有条件时才能行动:**存在 + 距离近 + 类型正确**。

复合逻辑封装 (`isCloseType`)

我们使用嵌套的 `if` 语句将三个条件全部封装在一个函数中:
1. `if target:` (是否存在?)
2. `if distance < 15:` (是否靠近?)
3. `if target.type == type:` (是否类型匹配?)
只有通过所有检查,函数才会返回 `True`。

(Exists AND Close AND Type?)

One Function, One Final Decision.

Python 程序解法

1
def isCloseType(target, type):
定义三合一检查函数:目标和期望类型
2
if target:
检查 1: 目标是否存在
3
distance = hero.distanceTo(target)
如果存在,计算距离
4
if distance < 15:
检查 2: 距离是否小于 15 米
5
if target.type == type:
检查 3: 类型是否匹配
6
return True
所有条件满足,返回 True
7
return False
任何条件失败,返回 False
8
9
while True:
10
item = hero.findNearestItem()
寻找物品
11
if isCloseType(item, "coin"):
调用函数:如果是近距离硬币
12
hero.moveXY(item.pos.x, item.pos.y)
移动去收集
13
enemy = hero.findNearestEnemy()
寻找敌人
14
if isCloseType(enemy, "munchkin"):
调用函数:如果是近距离矮人
15
hero.attack(enemy)
攻击敌人