题
我今天早些时候在想一个关于小游戏的想法,并偶然发现了如何实现它。这个想法是玩家可以做出一系列影响很小的动作,但是如果以特定的顺序完成会产生更大的影响。到目前为止一切都那么好,我知道怎么做。显然,我不得不让它变得更复杂(因为我们喜欢让它变得更复杂),所以我认为序列可能有多条可能的路径会产生更大的影响,尽管不同。此外,一些序列的一部分可能是其他序列的开始,或甚至整个序列可能被其他更大的序列包含。现在我不确定实现这个的最佳方法。不过,我有一些想法。
1)我可以实现循环的n链表。但由于移动列表永远不会结束,我担心它可能导致堆栈溢出™。这个想法是每个节点都有n个孩子,在接到命令后,它可能会引导你到他的一个孩子,或者,如果没有孩子可以接受这样的命令,则引导你回到开始。到达任何孩子后,将执行一些功能,从而产生小的和大的影响。但是,这可能导致树上的许多重复节点处理所有可能的序列,这些序列以不同的效果结束于特定的移动,这可能是一个难以维护但我不确定。我从未在代码上尝试过这种复杂的东西,只是理论上。这个算法是否存在且有名称?这是个好主意吗?
2)我可以实现状态机。然后,我没有在链表中闲逛,而是有一个巨大的嵌套开关,可以调用函数并相应地更新机器状态。看起来似乎更容易实现,但是......好吧......看起来并不好玩......也不好看。巨型开关对我来说似乎总是很难看,但这会更好吗?
3)建议?我很好,但我很缺乏经验。编码领域的好处是无论你的问题多么奇怪,过去有人解决了它,但你必须知道在哪里看。有人可能比我的想法更好,我真的很想听听建议。
解决方案
我并不完全确定我完全理解你所说的内容,但作为一个类似的情况,请说某人在键盘上输入无穷无尽的数字。 '117'是一个神奇的序列,'468'是另一个,'411799'是另一个(包含第一个)。
因此,如果用户输入:
55468411799
你想在* s发射'魔术事件':
55468 * 4117 * 99 *
或类似的东西,对吗?如果这与您正在谈论的问题类似,那么类似于(类似Java的伪代码)的东西:
MagicSequence fireworks = new MagicSequence(new FireworksAction(), 1, 1, 7);
MagicSequence playMusic = new MagicSequence(new MusicAction(), 4, 6, 8);
MagicSequence fixUserADrink = new MagicSequence(new ManhattanAction(), 4, 1, 1, 7, 9, 9);
Collection<MagicSequence> sequences = ... all of the above ...;
while (true) {
int num = readNumberFromUser();
for (MagicSequence seq : sequences) {
seq.handleNumber(num);
}
}
虽然MagicSequence有类似的东西:
Action action = ... populated from constructor ...;
int[] sequence = ... populated from constructor ...;
int position = 0;
public void handleNumber(int num) {
if (num == sequence[position]) {
// They've entered the next number in the sequence
position++;
if (position == sequence.length) {
// They've got it all!
action.fire();
position = 0; // Or disable this Sequence from accepting more numbers if it's a once-off
}
} else {
position = 0; // missed a number, start again!
}
}
其他提示
您可能想要实现状态机,但您不必对状态转换进行硬编码
尝试制作状态图,其中状态A到状态B之间的链接将意味着A可以导致B.
然后,您可以在运行时遍历图形以查找玩家的去向。
编辑:您可以将图形节点定义为:
-state-ID结果
- 其他州的链接列表,
每个链接定义的地方:
-state-ID结果
-precondition,在进入此状态之前必须访问的状态列表
您所描述的内容听起来与现场文明游戏中的技术树非常相似。
我不知道文明作者是如何构建他们的,但是我倾向于使用多图来表示可能的“移动” - 有些人可以从没有'经验'开始,一旦你'在其中,将有多条路径直到最后。
在游戏的每个阶段绘制出你可以拥有的潜在选项,然后从某些选项中划出线条到其他选项。
这应该为您提供实施的开始,因为图表是[相对]容易实现和利用的概念。
听起来像神经网络。您可以创建一个并训练它以识别导致您正在寻找的各种效果的模式。
您所描述的内容听起来有点类似于依赖图或字图。您可以查看这些内容。
@Cowan,@ Javier:好主意,请注意我加入它吗?
让MagicSequence对象监听输入的用户输入流,即通知他们输入(广播)并让每个人将输入添加到内部输入流。当输入不是模式中预期的下一个输入时,该流将被清除,该输入将使MagicSequence触发其动作。模式完成后,立即触发操作并清除内部输入流。
通过仅向等待它的MagicSequences提供输入来优化此功能。这可以通过两种方式完成:
-
您有一个对象,允许所有MagicSequences连接与其模式中的数字对应的事件。 MagicSequence(1,1,7)会将自己添加到got1并获得7,例如:
UserInput.got1 + = MagicSequnece [i] .SendMeInput;
-
您可以对此进行优化,以便在每次输入后,MagicSequences取消注册无效事件并注册有效事件。
醇>
为您想要的每种效果创建一个小型状态机。在每个用户操作中,将其“广播”到所有状态机。大部分时间都不会关心,但有些人会提前,或者可能会倒退。当其中一个达到目标时,产生预期的效果。
保持代码整洁,不要对状态机进行硬编码,而是构建一个编码状态图的简单数据结构:每个状态都是一个带有一系列有趣事件的节点,每个状态都指向下一个状态的节点。每台机器的状态只是对相应状态节点的引用。
编辑:看来Cowan的建议与此相当,但他优化了他的状态机,只表达简单的序列。对于您的具体问题似乎已经足够了,但更复杂的条件可能需要更通用的解决方案。