C++人工智能设计问题

3
我正在为一个MMORPG编写机器人,但现在我卡在了如何很好地实现这一点上。设计问题与按正确顺序施放角色法术有关。以下是我需要实现的简单示例,虽然它与施放它们无关,但是要按正确顺序进行操作。我可以通过检查哪个技能尚未被施放来随机地简单施放它们,但并非真正按照GUI中显示的正确顺序进行。
注意:技能数量可能不同,不总是3个,最多10个。
角色名称<foobar>拥有3个技能。
技能1:名称(random1)冷却时间(1000毫秒)施法时间(500毫秒)
技能2:名称(random2)冷却时间(1500毫秒)施法时间(700毫秒)
技能3:名称(random3)冷却时间(2000毫秒)施法时间(900毫秒)
我真的不知道如何实现这一点,如果有任何想法,请随便分享。我知道大多数人不喜欢在游戏中作弊的想法,我也不喜欢,我实际上也没有玩这个游戏,但对我来说这是一个有趣的领域。
谢谢。
5个回答

3

这涉及到更多的“智能代理”领域。考虑为您的AI建立一个计划数据库。您的投掷火球咒语计划可能需要先使用点燃火咒语,而这个咒语本身可能需要成功施法创建气泡咒语。选择一个计划需要满足所有先决条件,因此如果您的AI可以创建气泡但无法点燃气泡,则计划会失败,他们必须做其他事情(也许是重试)。


+1 对于双关语我很喜欢。 - Kawa
你会相信我直到现在我才注意到它吗?:D - Shaggy Frog
你需要的不是一个常规的数据库,而是一些简单形式的STRIPS规划:http://web.media.mit.edu/~jorkin/goap.html - Miquel Ramirez

2
也许在某些事件处理程序中,您想决定施放哪个咒语。也许您可以从这个咒语施放器开始:
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 interface ICastable
{
    string GetName();
    int AttemptCast(int msCurrentTime);
}

您描述了一种特定类型的咒语:
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;
    }
}

我看到这篇文章被标记为C++,但我的答案是用C#编写的,虽然我只使用了C++中可用的语言结构,因此应该是一个简单的翻译。但我无法轻松地翻译一些测试内容。

[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;
    }
}

+1 因为楼主说他觉得你的例子有帮助,但是从未给你点赞。 - ire_and_curses

1
也许你需要一个带有预定任务的队列。

1

0
看看OpenKore bot - 这是我见过的最先进的bot。这是一个大型开源项目,已经存在了几年,许多bot-AI-specific问题在其中得到了解决。我认为,你可以从中得到/学习一些想法。但是OpenKore主要用Perl编写。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接