C++ C++;人工智能设计问题
我目前正在为MMORPG编写一个机器人。不过,目前我一直在努力找出如何很好地实现这一点。设计问题与按正确顺序施法有关。这里有一个简单的例子来说明我需要归档的内容。这与铸造它们无关,而是按照正确的顺序进行。我会知道如何简单地随机施放它们,通过检查哪个技能尚未施放,但按照GUI中显示的正确顺序,不是真的 注意:技能数量可能有所不同,但并不总是3,最多10 CharacternameC++ C++;人工智能设计问题,c++,artificial-intelligence,bots,C++,Artificial Intelligence,Bots,我目前正在为MMORPG编写一个机器人。不过,目前我一直在努力找出如何很好地实现这一点。设计问题与按正确顺序施法有关。这里有一个简单的例子来说明我需要归档的内容。这与铸造它们无关,而是按照正确的顺序进行。我会知道如何简单地随机施放它们,通过检查哪个技能尚未施放,但按照GUI中显示的正确顺序,不是真的 注意:技能数量可能有所不同,但并不总是3,最多10 Charactername有3项技能 技能1:名称(随机1)冷却时间(1000毫秒)施放持续时间(500毫秒) 技能2:名称(随机2)冷却时间(1
谢谢。也许您需要一个包含计划任务的队列。您需要了解“计划算法”。这里有一个链接可以帮助您开始
本质上,您需要以最佳方式安排无限多的任务1、2和3。这是在冒险进入更“智能代理”的领域。考虑为你的人工智能设计一个计划数据库。你的施放火球法术计划可能有点燃火焰法术的先决条件,而点燃火焰法术本身可能有成功施放制造气泡法术的先决条件。选择一个计划需要满足所有的先决条件,因此,如果你的AI可以创建一个气泡,但不能点燃气泡,那么计划失败,他们必须做其他事情(可能重试)。可能从某个事件处理程序,你要决定施放什么法术。也许你可以从这个施法者开始:
public class Caster
{
private readonly ICastable[] _spells;
private int _canCastAt;
public Caster(ICastable[] spells)
{
_spells = spells;
_canCastAt = -1;
}
public string GetNextSpellToCast(int currentTime)
{
if (currentTime < _canCastAt)
return null;
for (int i = 0; i < _spells.Length; i++)
{
int durationOfCast = _spells[i].AttemptCast(currentTime);
if (durationOfCast > 0)
{
_canCastAt = currentTime + durationOfCast;
return _spells[i].GetName();
}
}
return null;
}
}
您描述了一种特殊的咒语:
public class ChanneledSpell : ICastable
{
private readonly string _name;
private readonly int _castDuration;
private readonly int _castCooldown;
private int _lastCast;
public ChanneledSpell(string name, int castDuration, int castCooldown)
{
Debug.Assert(castDuration < castCooldown); // a reasonable assumption the tests makes
_name = name;
_castDuration = castDuration;
_castCooldown = castCooldown;
_lastCast = -_castCooldown;
}
public string GetName()
{
return _name;
}
public int AttemptCast(int msCurrentTime)
{
if (msCurrentTime > _lastCast + _castCooldown)
{
_lastCast = msCurrentTime;
return _castDuration;
}
return 0;
}
}
看,这是我见过的最先进的机器人。这是一个大的,存在了几年,许多机器人AI指定的问题都在其中得到了解决。我想,你可以从中得到一些想法。但是OpenKore主要是用Perl编写的。+1用于punnery。我喜欢。如果我告诉你我直到现在才注意到它,你会相信我吗除了一个计划数据库,你需要的是一些简单的条状计划:+1,因为OP说他觉得你的例子很有用,但从来没有给你投票。
public class ChanneledSpell : ICastable
{
private readonly string _name;
private readonly int _castDuration;
private readonly int _castCooldown;
private int _lastCast;
public ChanneledSpell(string name, int castDuration, int castCooldown)
{
Debug.Assert(castDuration < castCooldown); // a reasonable assumption the tests makes
_name = name;
_castDuration = castDuration;
_castCooldown = castCooldown;
_lastCast = -_castCooldown;
}
public string GetName()
{
return _name;
}
public int AttemptCast(int msCurrentTime)
{
if (msCurrentTime > _lastCast + _castCooldown)
{
_lastCast = msCurrentTime;
return _castDuration;
}
return 0;
}
}
[TestFixture]
public class SpellTest
{
[Test]
public void TestCanCastOnStartup()
{
var sut = new ChanneledSpell(Some.String(), Some.PositiveNonzeroInteger(), Some.PositiveNonzeroInteger());
int result = sut.AttemptCast(Some.PositiveNonzeroInteger());
Assert.IsTrue(CastWasMade(result));
}
[Test]
public void TestCantCastUntilCooldown()
{
int firstCast = Some.PositiveNonzeroInteger();
int duration = Some.PositiveNonzeroInteger();
int cooldown = duration + Some.PositiveNonzeroInteger(); // assuming spell duration is less then cooldown
var sut = new ChanneledSpell(Some.String(), duration, cooldown);
int ignored = sut.AttemptCast(firstCast);
int secondCastAttempt = sut.AttemptCast(firstCast + cooldown - 1);
int thirdCastAttempt = sut.AttemptCast(firstCast + cooldown + 1);
Assert.IsFalse(CastWasMade(secondCastAttempt));
Assert.IsTrue(CastWasMade(thirdCastAttempt));
}
[Test]
public void TestReportsTimeOnCast()
{
int duration = Some.PositiveNonzeroInteger();
int firstCastTime = Some.PositiveNonzeroInteger();
var sut = new ChanneledSpell(Some.String(), duration, Some.PositiveNonzeroInteger());
int firstCastAttempt = sut.AttemptCast(firstCastTime);
Assert.AreEqual(duration, firstCastAttempt);
}
private bool CastWasMade(int result)
{
return result > 0;
}
}