我有一些时间思考以下内容,我想制作一个按钮来随机化一些技能的全部价值。问题是我有4点分配4种技能,想法是选择不超过10分的randoms数字。
我曾想过这个
public int startPts = 10, usedPts = 0;
public int skill1 = 0, skill2 = 0, skill3 = 0, skill4 = 0;
public void ButtonRandom(){
startPts = 10;
usedPts = 0;
skill1 = Random.Range( 1, 10 );
usedPts += skill1;
skill2 = Random.Range( 1, usedPts );
usedPts += skill2;
skill3 = Random.Range( 1, usedPts );
usedPts += skill3;
skill4 = startPts - usedPts;
usedPts += skill4;
startPts = startPts - usedPts;
}
我也尝试了几种条件和重复方法,但我没有得到理想的结果。因为有时它会超过10个点,所以在我放置条件时不使用或只更改前2个值就会留下点数。
谢谢你们,伙计们。
答案 0 :(得分:8)
如果你想要的是每个可能的发行版同样可能,那么到目前为止所提供的解决方案都不起作用。到目前为止提供的解决方案比3, 3, 2, 2
更频繁地选择7, 1, 1, 1
。你知道为什么吗?
如果您所需的分布在可能性上是均匀的,则此算法为您提供:
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
// Partition n into m summands
static IEnumerable<IEnumerable<int>> Partitions(int n, int m)
{
// There is no partition of n into zero summands for any value of n other than zero.
// Otherwise, give the partitions that begin with 0, 1, 2, ... n.
if (m == 0)
{
if (n == 0)
yield return Enumerable.Empty<int>();
}
else
{
for (int nn = 0; nn <= n; ++nn)
foreach(var p in Partitions(n - nn, m - 1))
yield return (new[] { nn }).Concat(p);
}
}
public static void Main()
{
// Divide up six points into four buckets:
var partitions = Partitions(6, 4).ToArray();
// Now choose a random member of partitions, and
// add one to each element of that sequence. Now
// you have ten points total, and every possibility is
// equally likely.
// Let's visualize the partitions:
foreach(var p in partitions)
Console.WriteLine(string.Join(",", p));
}
}
答案 1 :(得分:4)
如果我理解正确的话:
int[] skills = new int[4];
int pointsToDistribute = 10;
var rnd = new Random ();
for (int i = 0; i < pointsToDistribute; i++)
{
int whichSkill = rnd.Next (0, 4);
skills[whichSkill]++;
}
答案 2 :(得分:2)
使用 Unity API,这将是这样的,基于@apocalypse的解决方案
int[] skills = new int[4];
int pointsToDistribute = 10;
for (int i = 0; i < pointsToDistribute; i++) {
int whichSkill = Random.Range (0, 4);
skills [whichSkill]++;
}
答案 3 :(得分:1)
这对我有用。
每行都有一个解释,但简而言之,它使用一个数组来存储随机生成的数字。
public void RandomButton()
{
int toDistribute = 10; // 10 points to distribute
int[] skills = new int[4]; // Array that contains 4 skills
Random random = new Random(); // New instance of Random
for (int i = 0; i < 4; i++) // For loop that loops four times
{
if (toDistribute > 0) // Do this IF there are points to distribute
{
int points = random.Next(0, toDistribute + 1); // Assign points a value between 0 and the remaining amount of points
// Random.Next(lowerBoundary,upperBoundary-1) e.g. Random.Next(0,100) gives values from 0 to 99
skills[i] = points; // The current skill is given the value of points
toDistribute -= points; // Total number of points remaining is reduced by the number of points assigned this iteration
} else break; // If there are no points, end the loop
}
}
如果您不了解Random.Next的工作原理,请阅读here
编辑/统一更新:
研究让我相信Random.Next()在Unity中并不容易获得,而是使用Random.Range。在这种情况下,请使用以下内容:
int point = Random.Range(0,toDistribute);
另外,据我所知,你不需要创建一个新的Random实例,这意味着
Random random = new Random();
可以删除
答案 4 :(得分:0)
Guys @apocalypse击中目标,我正在研究他们的每一个算法和解决方案,非常感谢你们。这是我的代码的结果,以防有人有同样的怀疑。
public int startPts = 10, usedPts = 0;
public int skill1 = 0, skill2 = 0, skill3 = 0, skill4 = 0;
public void ButtonRandom(){
startPts = 10;
usedPts = 0;
int[] skills = new int[4];
for (int i = 0; i < 4; i++){
skills[i] = 1;
}
for (int i = 0; i < (startPts - skills.Length); i++) {
int tempRandom = Random.Range (0, 4);
skills [tempRandom]++;
}
for (int i = 0; i < 4; i++){
usedPts += skills[i];
}
startPts = startPts - usedPts;
skill1 = skills[0];
skill2 = skills[1];
skill3 = skills[2];
skill4 = skills[3];
}