对于在线游戏(MMORPG),我想创建具有随机强度值的角色(玩家)。字符越强,这种情况就越少。
示例:
实际上,我需要从1.1到9.9的浮动渐进强度值,但是对于这个例子,用整数强度来解释它更容易。
你知道如何用PHP编写代码吗?当然,我需要mt_rand()来生成随机数。但是我怎样才能实现这种金字塔结构呢?
它有什么功能?根函数,指数函数,幂函数或对数函数?
提前致谢!
它应该如下图所示:
Pyramid graph http://img7.imageshack.us/img7/107/pyramidy.jpg
答案 0 :(得分:5)
您可以使用对数函数模拟分布,例如您描述的分布。以下将返回1.1和9.9之间的随机强度值:
function getRandomStrength()
{
$rand = mt_rand() / mt_getrandmax();
return round(pow(M_E, ($rand - 1.033) / -0.45), 1);
}
分布超过1000次(其中S
是强度值):
S | Count
--+------
1 - 290
2 - 174
3 - 141
4 - 101
5 - 84
6 - 67
7 - 55
8 - 50
9 - 38
此答案已更新为包含强度值1.1(由于四舍五入而未包括在内)并修复了mt_getrandmax()
函数的名称
答案 1 :(得分:3)
最简单的方法是为随机数提供“带”。在你的例子中,你有15个玩家,所以你可以拥有:
rand < 1/15, highest strength
1/15 < rand < 3/15, second highest
3/15 < rand < 6/15, third highest
6/15 < rand < 10/15, fourth highest
10/15 < rand < 15/15, lowest strength
您还可以使用您允许的每个波段的“最大”数量来对这样的函数进行参数化,并且当波段被填充时,它将被包含到下一个最低的现有波段中(除了底部波段,它将被包含到下一个最高的)确保只有一定数量的随机分布。
编辑从我的评论中添加:
要获得浮动范围金字塔结构,最佳函数很可能是对数。公式:
11 - log10(rand)
可以工作(log10是基数为10的对数),因为它可以得到如下范围:
1 < rand < 10 = 9 < strength < 10
10 < rand < 100 = 8 < strength < 9
100 < rand < 1000 = 7 < strength < 8
etc.
但是rand需要的范围是1到10 ^ 10,这需要很多随机性(比大多数随机生成器可以管理的多)。要获得这种范围内的随机数,您可以将它们相乘。 3个随机数可以管理它:
11 - log10(rand1 * rand2 * rand3)
rand1的范围是1-10000,rand2和rand3的范围是1-1000。这会使分布稍微偏离适当的金字塔(我认为更可能在中心有数字)所以它可能不合适。
答案 2 :(得分:2)
workmad3有一个开始,但有一个问题 - 你需要跟踪你的水桶大小以及它们是否已满。随机数生成器不保证这一点。你需要分配你的桶值(强度)和大小(人数),并让你的随机生成器告诉你哪个桶放弃了玩家 - 如果那个桶已满,'溢出'到下一个低点。 / p>
至于为给定的强度值分配铲斗尺寸,这是一个棘手的问题(我认为你真正在做什么)。您所需分布的特征至关重要。如果你想要一个线性下降(金字塔形状提示),那么表格的一行
strength = max_strength - m(number_characters)
会奏效。改变m的值会改变线路下降的速度,并且基本上会限制你的最大总字符数。如果你正在寻找一种更复杂的强度值下降的方法,你可以使用抛物线或双曲线 - 这些曲线有点复杂,但会给你非常不同的特性。
答案 3 :(得分:0)
类似这样的事情
<?php
$rand = rand(1,10);
switch ($rand) {
case 1:
echo "band 1";
break;
case 2:
case 3:
echo "band 2";
break;
case 4:
case 5:
case 6:
echo "band 3";
break;
default:
echo "band 4";
break;
}
?>
乐队1是最强的,乐队4是最弱的。
当然这是基本的,你会想要重构这个以使用循环而不是硬编码开关,但你明白了这一点:)
答案 4 :(得分:-1)
生成0到40000之间的随机数,如果它在0到12000之间,则指定强度1,在12000和22500之间指定2等。
编辑:对于0到10之间的渐进值,使用0到100之间的随机数的平方根,然后从10减去
对于1.1和9.9之间的结果,公式将为伪代码
强度= 10 - sqrt(兰特(1..79))
答案 5 :(得分:-1)
在这种情况下使用百分比可能最容易。
从您的示例中可以看出(稍后将转换为数组以便于使用):
$strength[1] = .3; // start with a key of 1
$strength[2] = .26;
$strength[3] = .21;
$strength[4] = .15;
$strength[5] = .08;
这样,您可以使用mt_rand()
生成一个随机数,并除以最大可能值,得到0到1之间的数字:
$rand = mt_rand() / mt_getrandmax(); // rand is some random value between 0 and 1
然后,您可以使用foreach
语句来隔离每个案例:
$comparisonPercentage = 1;
$selectedLevel = count($strength); // covers the case where mt_rand() returns 0
foreach($strength as $level => $currentPercentage)
{
$comparisonPercentage -= $currentPercentage;
if ($rand > $comparisonPercentage)
{
$selectedLevel = $level;
break;
}
}
// $selectedLevel contains the level you need...
如果你这样做,你只需要改变$strength
数组,如果你需要调整百分比。