2013-06-04 27 views
0

我试图产生一个随机怪物遭遇。基本上,当按下“查找战斗!”时按钮,我想返回一个随机怪物供玩家战斗。但事情是,我想让一些怪物有更多机会出现,而有些则非常罕见。编码随机遇到

我一直在想的去做,到目前为止,我想到了3种方式的最佳途径。

  1. 给予每个怪物一个“重量”,并将它们的重量除以列表中每个怪物的总重量,给出一定百分比的机会被选中。优点:易于制作。缺点:如果我加入怪物,一些怪物可能变得对我想要的怪物太稀有。

  2. 让每一个怪物%的机会遇到,然后把他们全部名单内随机顺序。然后从列表中的第一个怪物开始,使用%遇到的机会掷骰子。如果是,则选择怪物。如果为false,则转到列表中的下一个怪物。至少有一个怪物有100%的遭遇机会来确保遇到相遇。优点:似乎很随机。缺点:与#1相同,对于它的价值可能有点太复杂。

  3. 给予每个怪物怪物类型(IE:正常,强,罕见),然后给每一个类型的一个%的几率来选择。然后掷骰子,看看在遭遇时会选择哪种类型,然后选择一种随机的怪物。优点:容易做到,会让罕见的怪物保持我希望他们成为的机会。缺点:不能让所有怪物都有自己的%机会。

我的问题:最好的方法是什么?我说的方式之一还是有更好的方法来做到这一点?

它是一个网站,我用asp.net,C#和SQL Server的工作。 Javascript和jquery都很好。如果您需要更多信息,我很乐意分享。

编辑:我认为第四办法做到这一点。这将是1和3的混合。对每个怪物使用“重量”(1到1000之间)。然后掷一个1000的骰子。然后对每个生成骰子下的重量的怪物生成一个随机数,将它们放在一个列表中,并在列表中选择一个随机怪物。

+1

尽管我们非常感谢您的热情,但这不是问这样的开放式问题的最佳选择。 –

+0

真的取决于你希望游戏如何工作,所有的方法都很好。如果你的怪物适合少数几个类别,并且你不想为个别怪物进行微调,那么我会去#3 – bengoesboom

+0

你已经提出了3个解决方案,并且你对于利弊有了很好的把握。做出选择。你比我们有更好的选择装备。 –

回答

1

随机数发生器1之间 - 100

如果1 - 25 1怪物

如果25 - 35怪物2

等。

+0

是的,但每次你添加/更新/删除一个怪物,你都必须重新编写你的算法。 –

+0

就像Brad M说的那样。我正在寻找一种方法来做到这一点,我不必为每个怪物重新更新每个怪物,以保持良好的机会。 – snaplemouton

+1

不会为你写一个算法,你问简单的想法 –

1

细分怪物遭遇表,使得它看起来是这样的:

  • 80%:怪物转储:从不断增长的列表抢一个怪物。
  • 20%:具有相对“固定”相遇概率的特殊怪物表。概率不受添加到其他表中的怪物的影响。
+0

所以1和3的混合?给我的怪物一个类型。 (IE:正常,半稀有,稀有)然后给予每种类型百分之一的机会被选中。 (IE:80%,15%,5%)然后掷骰子来选择一种类型。然后用重量随机选择一个怪物。这种方式罕见的怪物发生。这看起来是一个很好的方法。认为它限制了怪物的罕见程度,我限制了多少种类型。 – snaplemouton

+0

如果你想要一致的稀有性的遭遇,那么你应该考虑使用混合结果(而不是随机)来决定怪物类别(即正常,稀有等),并使用一个“实际”随机数字该类怪物。从预先洗好的数组中挑选数字会给你更多可预测的结果(不会太多也不会太少)。 – jongo45

0

通常我不会为某些东西输入代码,但我找不出一种描述我所想的方法的好方法,所以我只是在JavaScript中一起举例。我会留给你把它翻译成C#。基本的想法是为每个可能的怪物建立一个加权条目列表。然后生成一个随机数,从1到总重量(在我的示例中为maxKey),然后通过在列表中执行二进制搜索来计算出它对应的怪物。我认为这是相当动态的,并且仍然给你你正在寻找的灵活性,但也不需要太多的内存数据结构。

<!-- language-all: lang-js --> 
/** key-val pair constructor */ 
function KV(k,v) { return { 'key': k, 'val': v } } 

/** 
* Modified binary search 
* Finds value for closest key >= k 
*/ 
function findMatch(k, kvList) { 
    var h = 0 
    var i = Math.floor(kvList.length/2) 
    var j = kvList.length-1 
    while (j - h > 1) { 
    if (kvList[i].key == k) break 
    if (kvList[i].key < k) h = i 
    else j = i 
    i = Math.floor((h+j)/2) 
    } 
    if (kvList[i].key < k) i += 1 
    return kvList[i].val 
} 

// findMatch example: 
xs=[KV(1,1),KV(2,2),KV(4,4),KV(8,8),KV(16,16)] 
findMatch(5,xs) // => 8 

monsters = [ 
    { 'name': 'Rat', 'freq': 100 }, 
    { 'name': 'Bear', 'freq': 10 }, 
    { 'name': 'Qilin', 'freq': 1 } 
] 

maxKey = 0 
encounterList = new Array(monsters.length) 
for (i=0; i<monsters.length; i++) { 
    maxKey += monsters[i].freq 
    encounterList[i] = KV(maxKey, monsters[i].name) 
} 

function randomEncounterMonster() { 
    r = Math.floor(Math.random()*maxKey+1) 
    return findMatch(r, encounterList) 
} 

// test 
counts = { 'Rat': 0, 'Bear': 0, 'Qilin': 0} 
for (i=0; i<1000; i++) counts[randomEncounterMonster()]++ 
// print counts to see results