2009-08-21 4 views
3

В настоящее время я пишу бота для MMORPG. Хотя, в настоящее время я застрял в попытке выяснить, как красиво реализовать это. Проблема дизайна связана с тем, что заклинания персонажа находятся в правильном порядке. Вот простой пример того, что мне нужно для архивирования. Это не связано с их литьем, но делать это в правильном порядке. Я бы знал, как просто произвольно использовать их, проверяя, какое умение еще не было выполнено, но в правильном порядке, как показано в графическом интерфейсе, на самом деле.C++ AI Design Вопрос

примечание: количество умения может отличаться, это не всегда 3, максимум 10.

Charactername < foobar> обладает 3 навыками.

навык 1: Имя (random1) время восстановления (1000 мс) литые длительность (500 мс)

навык 2: Имя (Random2) время восстановления (1500 мс) литые Длительность (700 мс)

Умение 3 : Название (random3) время восстановления (2000 мс) длительность каста (900 мс)

Я действительно не знаю, как я мог бы реализовать это, если у кого-то есть мысли, не стесняйтесь делиться. Я знаю, что большинству людей не нравится идея обмана в играх, мне это тоже не нравится, и я фактически играю в игру, но это интересное поле для меня.

спасибо.

ответ

1

Возможно, вам нужна очередь с запланированными задачами.

3

Это углубляясь в более «интеллектуальный агент» территории. Подумайте о наличии базы данных плана для вашего ИИ. У вашего заклинания пламени заклинаний может быть необходимое условие с заклинанием «огонь-огонь», что само по себе может иметь предпосылку успешного обхода заклинания «создание-газовый пузырь». Выбор плана потребует удовлетворения всех предварительных условий, поэтому, если ваш ИИ может создать газовый пузырь, но не воспламенять пузырь, тогда план сгорит, и они должны сделать что-то еще (возможно, повторить попытку).

+0

+1 для пейннира. Мне нравится это. – Kawa

+0

Вы бы поверили мне, если бы я сказал вам, что не заметил этого до сих пор? : D –

+0

Вместо базы данных плана вам понадобится простая форма планирования STRIPS: http://web.media.mit.edu/~jorkin/goap.html – miquelramirez

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

+1 Поскольку OP сказал, что он нашел ваш пример полезно, но никогда не поддерживал вас. –

0

Посмотрите на OpenKore bot - самый продвинутый бот я видел. Это большой opensource project, существующий несколько лет, и в нем были решены многие проблемы, связанные с ботом-AI.Я думаю, вы можете получить/изучить некоторые идеи из этого. Но OpenKore написан в основном на Perl.