【问题标题】:使用 math.random 生成随机数,但不重复
【发布时间】:2021-03-22 09:42:21
【问题描述】:

对于我参与的组织的年度圣诞节活动,我们通常会举行抽奖活动,人们只需参加并在门口获得号码票,就有机会赢取免费奖品。我们使用 Flash 编写的程序(使用 ActionScript 2.0),利用 math.random 选择一个随机数,并附加一些参数,如下所示:

//maxNr = 999999999999999;


initRandom = function(){
    var nr = Math.ceil(Math.ceil(Math.random()*(maxNr));
    var nrString = "";
    for( var j=0; j<(maxNr.toString().length-nr.toString().length); j++){
        nrString += "0";
    }
    nrString += nr.toString();
    var holder = this.createEmptyMovieClip("holder",1);
    for( i=0; i<maxNr.toString().length; i++ ){
        var mc = holder.attachMovie("number","n"+i,i+10);
        mc._x = i*350;
        mc.anim_mc.gotoAndPlay( Math.floor(Math.random()*9) + 1 );
        this["iv"+i] = setInterval( this, "revealNumber", 2000 + (500*i), nrString.substr(i,1), i );
    }
    // scale (if needed) and center
    if( holder._width > Stage.width ){
        holder._width = Stage.width;
        holder._yscale = holder._xscale;
    }
    holder._x = Stage.width/2 - holder._width/2;
    holder._y = 100;
    // buttons
    back_btn.onRelease = function(){
        for(item in holder){
            holder[item].removeMovieClip();
        }
        gotoAndStop("intro");
    }
}

revealNumber = function( digit, i ){
    clearInterval( this["iv"+i] );
    holder["n"+i].gotoAndStop("done");
    holder["n"+i]["number_txt"].text = digit;
}

initRandom();

stop();

返回一个介于 1 到 1000 之间的随机数,定义如下:

go_btn.onRelease = function(){
    maxNr = Math.max( 1000 , 1 );
    gotoAndStop("random");
}

stop();

它是由我们组织的一位成员编写的,他不幸在这一年去世了,我几乎没有编程知识,但我学得很快,实际上已经修改了一些代码以达到目前的水平.但是,我正在尝试添加一个参数,该参数将禁止该函数重复一个数字,即不包括重新选择已生成的数字。 我已经花了几天时间搜索所有可能的资源,但都遇到了死胡同。

使用目前采用的方法,是否可以将此参数添加到现有代码中,我该如何做?

非常感谢任何帮助、建议或回复!

【问题讨论】:

  • 简单地说,您需要 var nr = Math.ceil(Math.ceil(Math.random()*(maxNr)); 才能产生独特的结果?
  • 是的,我相信这应该是简单的表达方式;我希望只有独特的结果,这样它就不会给我以前生成的数字

标签: arrays flash random actionscript actionscript-2


【解决方案1】:

我的 AS2 有点生疏了,但我认为下面的脚本解释了总体思路。您需要一些注册表来记录生成的数字,以便下次生成数字时可以跳过它们。我使用了 _global 对象,因此这个逻辑甚至超越了以下脚本的多个实例。

// Create an Array to record generated numbers.
// The _global object is always present and can be accessed from anywhere.
if (_global.uniqueNr == undefined)
{
    _global.uniqueNr = [];
}

function initRandom()
{
    var nr;

    do
    {
        nr = Math.ceil(Math.ceil(Math.random()*(maxNr));
    }
    while (_global.uniqueNr[nr] == true);
    
    // Record the newly generated number so it would never drop again.
    _global.uniqueNr[nr] = true;
    
    // At this point you can be sure that "nr" contains a unique value.

【讨论】:

  • 非常感谢,让我试试看。我应该在代码的什么地方插入这个?
  • @Bolu 这应该替换脚本的前两行有意义行(函数声明和数字生成)。
【解决方案2】:
package 
{
    public class RandomGenerator
    {
        private var _st:Number;
        private var _en:Number;
        private var _len:Number;
        private var _pos:Number;
        private var _numPos:Number;
        private var _myNums:Array;
        private var _randNums:Array;
            
        public function RandomGenerator(en:Number, st:Number = 0) 
        {
            _st = st;
            _en = en;
            
            // just in case if params order mixup:
            if(en < st){
                _st = en;
                _en = st;
            }
            
            _len = _en - _st + 1;
            shuffle();
        }
        
        public function getNum():Number
        {
            // if passed last item:
            if(_numPos == _len)shuffle();
            
            var myResult:Number = _randNums[_numPos];
            _numPos++;
            return myResult;
        }
        
        private function shuffle():void
        {
            _numPos = 0;
            _randNums = [];
            _myNums = [];
            
            // Creating Numbers Array:
            var i:Number;
            for(i = 0; i<_len; i++){ _myNums[i] = _st + i; }
            
            // Creating shuffled Numbers Array:
            i = 0;
            while(_myNums.length > 0){
                _pos = Math.round(Math.random()*(_myNums.length-1));
                _randNums[i] = _myNums[_pos];
                i++;
                _myNums.splice(_pos,1);
            }
        }
        
        public function get len():Number
        {
            return _len;
        }

    }
    
}

从这个类中创建一个对象,例如cardGenerator:RandomGenerator = new RandomGenerator(51, 0),最后你可以得到随机数而不用重复这个代码:

for (var i:int = 0; i < cardGenerator.len; i++) {
     trace(cardGenerator.getNum());               
}

【讨论】:

    猜你喜欢
    • 2015-10-16
    • 2019-07-27
    • 2014-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-06
    • 2011-07-13
    • 1970-01-01
    相关资源
    最近更新 更多