随机化值而不超过值?

时间:2017-02-28 19:04:36

标签: c# unity3d random

我有一些时间思考以下内容,我想制作一个按钮来随机化一些技能的全部价值。问题是我有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个值就会留下点数。

谢谢你们,伙计们。

5 个答案:

答案 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]++;
}

测试:https://dotnetfiddle.net/891OlN

答案 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];

}