3

我目前正在为 MMORPG 编写一个机器人。虽然,目前我一直在试图弄清楚如何很好地实现这一点。设计问题与以正确的顺序施放角色咒语有关。这是我需要归档的一个简单示例。这与铸造它们无关,而是以正确的顺序进行。我会知道如何简单地随机施放它们,通过检查尚未施放的技能,但在 GUI 中显示的正确顺序,不是真的。

注意:技能数量可能会有所不同,并不总是3,但最多10。

Charactername < foobar > 有 3 个技能。

技能 1:名称(随机 1)冷却时间(1000 毫秒)施法时间(500 毫秒)

技能 2:名称 (random2) 冷却时间 (1500 毫秒) 施法时间 (700 毫秒)

技能 3:名称 (random3) 冷却时间 (2000 毫秒) 施法时间 (900 毫秒)

我真的不知道如何实现这一点,如果有人有一些想法,请随时分享。我知道大多数人不喜欢在游戏中作弊的想法,我也不喜欢它,我实际上也不是在玩游戏,但它对我来说是一个有趣的领域。

谢谢你。

4

5 回答 5

3

这是冒险进入更“智能代理”的领域。考虑为您的 AI 建立一个计划数据库。你的 cast-fireball-spell 计划可能有 ignite-fire 法术的先决条件,它本身可能有成功执行 create-gas-bubble 法术的先决条件。选择一个计划需要满足所有先决条件,所以如果你的 AI 可以制造一个气泡但不能点燃气泡,那么计划就会失败,他们必须做其他事情(也许重试)。

于 2009-08-25T06:10:01.607 回答
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;
    }
}
于 2009-08-25T07:14:01.370 回答
1

也许您想要一个带有计划任务的队列。

于 2009-08-21T02:33:12.787 回答
1

您将要研究“调度算法”。这是一个帮助您入门的链接。

http://www.ctl.ua.edu/math103/scheduling/scheduling_algorithms.htm

本质上,您需要以最佳方式调度无限数量的任务 1、2 和 3。

于 2009-08-21T02:34:46.980 回答
0

看看OpenKore机器人——我见过的最先进的机器人。这是一个大型的开源项目,存在数年,其中解决了许多 bot-AI-specificing 问题。我认为,您可以从中获得/学习一些想法。但是OpenKore主要是用 Perl 编写的。

于 2009-09-18T07:23:01.437 回答