19

这里是背景... 在我的空闲时间,我正在设计一个名为 Staker 的炮兵战争游戏(灵感来自旧的 BASIC 游戏Tank WarsScorched Earth),我正在用 MATLAB 对其进行编程。您的第一个想法可能是“为什么选择 MATLAB?还有很多其他语言/软件包更适合游戏设计。” 你是对的。然而,我是个笨蛋,我有兴趣学习如何从头开始设计游戏的具体细节,所以我不一定想使用任何带有预制模块的东西。此外,我已经使用 MATLAB 多年,我喜欢用它来做其他人没有真正尝试过的事情的挑战。

现在到了手头的问题:我想加入人工智能,这样玩家就可以对抗电脑了。我才刚刚开始思考如何设计算法来选择方位角、仰角和弹丸速度来击中目标,然后每转一圈进行调整。我觉得我可能一开始就过度思考了这个问题,并试图让 AI 变得过于复杂,所以我想我会在这里停下来向社区询问他们如何设计算法的想法。

一些具体问题:

  1. 您是否会建议我查看有关 AI 设计的具体参考资料?

  2. 你会设计 AI 玩家以连续的方式改变难度(难度从 0(容易)到 1(困难),都仍然使用相同的通用算​​法)还是会为离散数量的 AI 玩家设计特定的算法(就像一个向随机方向射击的简单敌人或一个能够解释风影响的顽固敌人)?

  3. 您将从哪种数学算法(伪代码描述)开始?

一些附加信息:我用来模拟弹丸运动的模型结合了流体阻力和风的影响。“流体”可以是空气或水。在空气中,根据一些简单的大气模型,空气密度(以及阻力效应)随离地高度而变化。在水中,阻力非常大,以至于弹丸通常需要额外的推力。换句话说,抛射物可能会受到重力以外的力的影响。

4

7 回答 7

4

在真实的炮兵情况下,所有这些因素都可以通过公式或简单的蛮力模拟来处理:发射一个电子炮弹,施加所有相关的力量,看看它落在哪里。调整并重试,直到电子炮弹击中目标。现在你有你的号码发送到枪。

鉴于情况的复杂性,我怀疑没有比暴力破解更好的答案了。虽然您可以预先计算出预期阻力效果与速度的表格,但我认为它不值得。

当然,AI 每次都将第一个炮弹落在你头上的游戏不会很有趣。一旦你知道了正确的值,你就必须让 AI 变得糟糕透顶。对射击应用一个随机因素,然后走向目标——每次射击时将其移动到真实目标的 30+random(140)%。

编辑:

我确实同意 BCS 的概念,即随着时间的推移对其进行改进。我说过,但后来改变了如何写一堆它的想法,然后最终忘记把它放回去。它应该越硬,随机组件应该越小。

于 2009-01-10T19:52:03.630 回答
3

我现在正在处理您发布的回复:

虽然您有一般的想法,但我不相信您的方法可行 - 即使对于较低的 nSims 值,它也会收敛得太快。我怀疑您是否希望在 shell 之间进行不止一次的 get_new_guess 迭代,而且它很可能需要一些随机化。

即使您可以使用多次迭代,它们也不擅长不断增加难度,因为它们将是大步骤。在我看来,困难必须由随机性来处理。

首先,get_initial_guess:

开始时,我将有一张将世界划分为区域的表格——难度越高,区域越多。这些区域之间的边界将具有 45、60 和 75 度的预先计算的功率。做一个测试图,如果炮弹击中地形,请以更高的角度再试一次——如果 75 次击中地形,无论如何都要使用它。

初始 shell 应该在给定的下限和上限值之间的随机功率下触发。

现在,对于 get_new_guess:

炮弹击中地形了吗?增加角度。我认为需要增加多少功率以保持相同的距离会有一个恒定的比例——你需要对此进行测试。

假设它没有撞到一座山,请注意它是短的还是长的。这给了你一个界限。新的猜测介于两个界限之间(如果您缺少界限,请使用 get_initial_guess 中表中的值。)

注意目标在下限和上限影响点之间的距离百分比,并选择在下限和上限功率之间较远的功率。

这可能太准确了,可能需要一些随机化。我已经改变主意添加一个简单的随机百分比。相反,应该使用多个随机数来获得钟形曲线。

于 2009-01-11T00:38:58.247 回答
3

感谢 Loren 和 BCS,我想你已经想到了我正在考虑的一个想法(这引发了上面的问题 #2)。AI 回合的伪代码如下所示:

nSims;        % A variable storing the numbers of projectile simulations
              %    done per turn for the AI (i.e. difficulty)
prevParams;   % A variable storing the previous shot parameters
prevResults;  % A variable storing some measure of accuracy of the last shot
newParams = get_new_guess(prevParams,prevResults);
loop for nSims times,
  newResults = simulate_projectile_flight(newParams);
  newParams = get_new_guess(newParams,newResults);
end
fire_projectile(newParams);

在这种情况下,变量 nSims 本质上是衡量人工智能“智能”的指标。一个“愚蠢”的 AI 的 nSims = 0,并且每回合都会做出新的猜测(基于前一回合的结果)。“智能”人工智能会通过模拟弹丸飞行来改进其每转的猜测 nSims 时间。

由此产生了另外两个问题:

1) get_new_guess 函数包含什么?我应该如何调整三个射击参数以最小化与目标的距离?例如,如果一发子弹没有达到目标,您可以尝试通过仅调整仰角、仅调整弹丸速度或同时调整两者来使其更接近。

2) 所有 AI 的 get_new_guess 是否应该相同,而 nSims 值是“智能”的唯一决定因素?或者 get_new_guess 是否应该依赖于另一个“智能”参数(如guessAccuracy)?

于 2009-01-10T21:36:58.223 回答
3

炮兵游戏和真实炮兵情况的区别在于,各方都有 100% 的信息,并且通常有超过 2 个对手。

因此,你的评估函数应该考虑哪个对手更迫切地尝试和消除。例如,如果我有 90% 的轻松击杀几率,但有 50% 的几率击杀试图击杀我但在我附近错过了两枪的人,那么处理这个机会就更重要了。

我认为您需要某种方法来评估每个人在弹药、位置、活动、过去历史等方面对您构成的风险。

于 2009-01-10T22:01:01.573 回答
3

Loren 的蛮力解决方案很有吸引力,因为它可以通过添加更多迭代来轻松进行“智能调整”。此外,迭代的调整因子可能是智能的一部分,因为某些值会使它收敛得更快。

同样对于基本系统(无阻力、风等),有一个封闭形式的解决方案可以从基本的物理文本中得出。我会做出第一个猜测,然后每轮进行一次或多次迭代。您可能想尝试提出一个经验校正相关性来改进第一个镜头(这将使第一个镜头的分布平均值更接近正确)

于 2009-01-10T20:01:09.587 回答
1

另一个想法:我们是否正在处理一个同时只有一个 shell 处于活动状态的系统?很久以前,我实现了一个火炮游戏,你有 5 个枪管,每个枪管都有一个固定的装填时间,高于最大可能的飞行时间。

有了这个,我发现自己使用了一种在我当前的下限和上限之间的范围内发射炮弹的策略。不过,作为一个普通人,我可能没有使用最佳策略——这是实时的,一旦枪管准备好就完成一轮比确保它尽可能地瞄准更重要,因为它会收敛反正很快。我通常会在第二次齐射时将炮弹放在目标上,而第三次通常都会被击中。(杀死需要杀死目标中的所有像素。)

在人工智能的情况下,我会模拟这个和阻止一些枪管稍后发射更准确的子弹的策略。我仍然会在目标范围内展开散布,唯一的问题是我是否会使用所有枪管。

于 2009-01-11T00:47:11.427 回答
1

我亲自创建了这样一个系统 - 用于网络游戏 Zwok,使用蛮力。我朝随机方向开了很多枪,并记录了最好的结果。我不建议以任何其他方式这样做,因为时间步长等之间的差异会给你带来意想不到的结果。

于 2009-06-25T19:01:48.897 回答