C ++ AI Design Question

I am currently writing a bot for MMORPG. Although, at present I am stuck in an attempt to figure out how beautifully to implement this. The design problem is that character spells are in the correct order. Here is a simple example of what I need for archiving. This is not related to casting, but it does so in the correct order. I would know how easy it is to arbitrarily use them, checking which skill has not yet been completed, but in the correct order, as shown in the graphical interface, in fact.

Note: the number of skills may vary, this is not always 3, maximum 10, though.

Charactername <foobar> has 3 skills.

Skill 1: Recovery time of the spell "Name" (random1) (1000 ms) (500 ms)

Skill 2: Recovery time of the spell "Name" (random2) (1500 ms) (700 ms)

Skill 3: Recovery time of the spell "Name" (random3) (2000 ms) (900 ms)

I do not know how to implement this, if someone has thoughts, do not hesitate to share them. I know that most people donโ€™t like the idea of โ€‹โ€‹cheating in games, I donโ€™t like this either, and I actually play this game, but this is an interesting field for me.

Thanks.

+3
source share
5 answers

" ". . "-", "- ". , , , , , - (, ).

+3

, - , . , - :

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

, ++, - #, , ++, . , , - ,

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

, .

+1

Check out the OpenKore bot , the most advanced bot I've seen. This is a large open source project that has existed for several years, and it solved many problems related to the AI โ€‹โ€‹bot. I think you can get / learn some ideas from this. But OpenKore is written primarily in Perl.

0
source

Source: https://habr.com/ru/post/1715675/


All Articles