0

我正在尝试使用 RNG 类从列表中选择 2 个随机项目。问题是偶尔我会得到相同的 2 个数字,我希望它们是唯一的。我尝试使用 while 循环来获取另一个数字,如果它与最后一个数字相同,但即使添加一个简单的 while 循环也会导致“超过预付费用”错误。我不明白什么?

//simplified for posting question
var lengthOfList = 10
var numItemsWanted = 2
//Get more rng numbers than I need incase of duplicates
const rng = new RNG<u32>(lenghtOfList, lengthOfList)

for(let i = 0; i < numItemsWanted; i++) {
    var r = rng.next()
    while (r == rng.last()) {
        r = rng.next()
    }
    newList.push(oldList[r])
}

在职的:

//simplified for posting question
var lengthOfList = 10
var numItemsWanted = 2
//Get more rng numbers than I need incase of duplicates
const rng = new RNG<u32>(lenghtOfList, lengthOfList)
let r = rng.next()
let last = r + 1
for(let i = 0; i < numItemsWanted; i++) {
    newList.push(oldList[r])
    last = r
    r = rng.next()
    while (r == last) {
        r = rng.next()
    }
}

4

2 回答 2

1

如果您从oldList一次拾取的项目中删除该项目,则无法再次拾取它。

另一种方法是洗牌oldList,然后选择前两项。

于 2022-01-25T17:34:43.987 回答
1

这是关于near-sdk-asNEAR 平台上的 AssemblyScript 智能合约开发工具包

您可以查看此示例中如何使用 RNG https://github.com/Learn-NEAR/NCD.L1.sample--lottery/blob/ff6cddaa8cac4d8fe29dd1a19b38a6e3c7045363/src/lottery/assembly/lottery.ts#L12-L13

class Lottery {
  private chance: f64 = 0.20

  play(): bool {
    const rng = new RNG<u32>(1, u32.MAX_VALUE);
    const roll = rng.next();
    logging.log("roll: " + roll.toString());
    return roll <= <u32>(<f64>u32.MAX_VALUE * this.chance);
  }
}

以及如何在此处实现构造函数: https ://github.com/near/near-sdk-as/blob/f3707a1672d6da6f6d6a75cd645f8cbdacdaf495/sdk-core/assembly/math.ts#L152

第一个参数是保存从种子生成的随机数的缓冲区的长度。您可以使用该next()方法在每次调用时从此缓冲区中获取更多数字

export class RNG<T> {
  constructor(len: u32, public max: u32 = 10_000) {
    let real_len = len * sizeof<T>();
    this.buffer = math.randomBuffer(real_len);
    this._last = this.get(0);
  }

  next(): T {}
}
于 2022-01-25T18:33:37.910 回答