C# 随机化值而不超过某个值?
我有一些时间思考以下问题,我想做一个按钮来随机分配一些技能的整体值。问题是,我有10分可以在4种技能之间分配,这个想法是在不超过10分的情况下选择随机数 我曾想过这一点C# 随机化值而不超过某个值?,c#,unity3d,random,C#,Unity3d,Random,我有一些时间思考以下问题,我想做一个按钮来随机分配一些技能的整体值。问题是,我有10分可以在4种技能之间分配,这个想法是在不超过10分的情况下选择随机数 我曾想过这一点 public int startPts = 10, usedPts = 0; public int skill1 = 0, skill2 = 0, skill3 = 0, skill4 = 0; public void ButtonRandom(){ startPts = 10; usedPts = 0;
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个值而保留点
谢谢大家。如果我理解正确:
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]++;
}
int[]skills=newint[4];
int pointstodistribution=10;
var rnd=新的随机变量();
对于(int i=0;i
测试:这对我有用。
每一行都有一个解释,但简而言之,它使用一个数组来存储随机生成的数字
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的新实例,这意味着
Random random = new Random();
可以删除如果您希望每个可能的分布都具有相同的可能性,那么到目前为止提供的解决方案都不起作用。迄今为止提出的解决方案选择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));
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
公共课程
{
//将n划分为m和
静态IEnumerable分区(int n,int m)
{
//对于除零以外的任何n值,都不存在将n划分为零和的情况。
//否则,给出以0、1、2、…n开头的分区。
如果(m==0)
{
如果(n==0)
产生返回可枚举的.Empty();
}
其他的
{
对于(int nn=0;nn使用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]++;
}
int[]skills=newint[4];
int pointstodistribution=10;
对于(int i=0;i
伙计们@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];
}
public int startPts=10,usedPts=0;
public int skill1=0,skill2=0,skill3=0,skill4=0;
公共无效按钮随机(){
startPts=10;
usedPts=0;
int[]技能=新int[4];
对于(int i=0;i<4;i++){
技能[i]=1;
}
对于(int i=0;i<(startPts-skills.Length);i++){
int tempRandom=Random.Range(0,4);
技能[随机]+;
}
对于(int i=0;i<4;i++){
使用的DPTS+=技能[i];
}
startPts=startPts-使用的DPTS;
skill1=技能[0];
技能2=技能[1];
技能3=技能[2];
技能4=技能[3];
}
您的上一次作业需要分配剩余的点,而不是尝试猜测一个随机点。“skill4=startPts-usedPts”您确定您实际上不想使用random.Range(1,startPts-usedPts)
?目前,您生成的数字根本没有考虑剩余的可用点数。我认为您当前的方法不正确,您基本上有十分之一的机会将10分分配给您的第一项技能。您几乎没有机会将10分分配给您的最后一项技能。我将随机分配一个数字1对于所有技能中的10项,然后根据它们占总数的百分比,你可以应用一个适当的数字。Derrick Moeller是正确的;此算法不会产生技能的统一分布。你是否希望有一个特定的分布?例如,是否应该表示四项加起来等于10项的所有可能组合?第你想要的算法是:给每个技能一个起点。然后六次,选择一个随机技能并增加一。这保证了(1)总数将增加到十,(2)每个技能至少有一个,和(3)没有特别喜欢的技能。但是,这并不能保证所有可能的十点分布分成四部分,每个技能至少有一个点。我认为每个技能都应该从一开始,然后循环将只转到pointsToDistribute-skills.Length
。这是问题的一个要求。@dcg:我给了他一个想法,他可以很容易地适应他的要求。但你当然是对的。嘿@apocapse我想使用.Next()方法,但在Unity中,它似乎不能使用,或者我认为是这样。但这是期望的结果,谢谢你,现在我不知道如何用Unity植入它。
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];
}