如何设计依赖列表并存储它

How to design a dependency list and store it

我正在开发一款包含一系列任务的游戏。用户随时可以进行许多任务,但是某些任务取决于其他任务在可用之前先完成。您可以从 WoW 中寻找可能的最佳实现方式。当您完成各种任务时,游戏状态会更新以反映用户可用的新选项。

我很好奇如何有效地构建它。例如:

Quest A: no dependency
Quest B: no dependency
Quest C: dependent on B complete
Quest D: dependent on C and A both complete

本质上,这变成了一个图,其中节点 C 具有 B 作为 parent,节点 D 具有节点 C 和 A 作为 parents。当我们完成任务时,应用程序将查看 children 已全部完成 parent 的任务可供用户使用。

我确定这是一个常见问题。理论上我可以理解它,但是我正在努力实现它。

我正在使用 C#/sqlite。我想将 Quest 数据存储在我的数据库中。我正在考虑一个名为 Quest(不是部落)的 table 来获取任务细节,但我正在为依赖信息的最佳实现而苦苦挣扎。特别是,以易于维护的方式构建它。

有什么想法吗?

这是一个多对多的关系,所以显而易见的解决方案是 junction table:

CREATE TABLE Quest (
    ID,
    [...]
);
CREATE TABLE QuestDependency (
    Child  REFERENCES Quest(ID),
    Parent REFERENCES Quest(ID)
);

我认为您可以在代码中设置依赖项,因为它们不会经常更改(如果有的话)。要实现您想要的,您需要创建 Quest class 并包含一系列相关任务。

public class Quest
{
    private List<Quest> quests = new List<Quest>();

    // you need a validation in setter.
    public bool Complete { get; set; }

    public bool CanStart()
    {
        return quests.All(o => o.Complete);
    }

    public void Add(Quest quest)
    {
        this.quests.Add(quest);
    }

    public void Remove(Quest quest)
    {
        this.quests.Remove(quest);
    }
}

您可以通过将依赖项 Quest 添加到集合来配置 Quest 依赖项。例如,要设置 4 个具有依赖性的任务,就像您在问题中想要的那样。

[TestMethod]
public void SetupABCDQuestTest()
{
    var questA = new Quest();
    Assert.IsTrue(questA.CanStart());

    var questB = new Quest();
    Assert.IsTrue(questB.CanStart());

    var questC = new Quest();
    questC.Add(questB);
    Assert.IsFalse(questC.CanStart());

    questB.Complete = true;
    Assert.IsTrue(questC.CanStart());

    var questD = new Quest();
    questD.Add(questA);
    questD.Add(questC);
    Assert.IsFalse(questD.CanStart());

    questA.Complete = true;
    questC.Complete = true;

    Assert.IsTrue(questD.CanStart());
}

使用 Decorator Pattern,您可以按照自己的方式设置依赖关系,复杂或简单都可以!