/// Created by Haoyi on 2021/9/14

// PseudoRandom类实现了一个伪随机数生成器，可生成整数、布尔值和对列表进行洗牌操作。
class PseudoRandom {
  // 伪随机数生成器的最大值和初始值
  static const _RAND_MAX = 0x7FFFFFFF;
  static const _RAND_INIT = 123459876;

  // 用于计算下一个随机数的内部状态变量
  int _next = 1;

  // 伪随机数生成器的种子值
  final int seed;

  // 构造函数，接受可选的种子值，如果没有提供，则使用默认的初始值
  PseudoRandom([int? seed])
      : seed = seed ?? _RAND_INIT,
        _next = seed ?? _RAND_INIT;

  // 根据当前状态计算下一个随机整数，返回一个伪随机数
  int _rand() {
    if (_next == 0) {
      _next = _RAND_INIT;
    }
    final int quotient = _next ~/ 127773;
    final int remainder = _next % 127773;
    int t = 16807 * remainder - 2836 * quotient;
    if (t <= 0) {
      t += _RAND_MAX;
    }
    _next = t % (_RAND_MAX + 1);
    return _next;
  }

  // 生成一个伪随机整数，可以指定最大值max（可选参数），如果未提供，则使用默认的最大值
  int nextInt([int? max]) {
    return _rand() % (max ?? _RAND_MAX);
  }

  // 生成一个伪随机布尔值，返回true或false
  bool nextBool() {
    return _rand() & 0x01 == 1;
  }

  // 使用Fisher-Yates洗牌算法随机打乱列表中的元素
  void shuffle(List list) {
    var i = list.length;
    while (i > 1) {
      int pos = nextInt(i);
      i -= 1;
      var tmp = list[i];
      list[i] = list[pos];
      list[pos] = tmp;
    }
  }
}
