游戏中伪随机数的产生

在游戏编程,随机数的应用无所不在,例如扑克类游戏中的随机发牌,俄罗斯方块的随机生成,拼图游戏中单元图片的散化,道具的摆放等等,我们希望所产生的数字随机,而且在我们预先设计的范围之内,同时又不希望有重复的两个数字出现,

对于一般的作法:

srand( (unsigned)time( NULL ) );    // 使用时间产生随机数.
int number=rand()%mRange; 

很有可能会产生相同的数字,以致让游戏失去的随机性,趣味性。下面给出通过随机交换产生随机数的程序:

#include  < stdio.H >
#include 
< stdlib.H >
#include 
< time.H >

//  随机数产生类
class  clRandom
{
protected:
    
int    mRange;        // 随机数的值域
    int    mIndex;        // 取出索引
    int    *mTable;    // 随机数表
    bool    mAutoGenerate;    // 是否自动产生随机数

public:
    
// 建构
    clRandom( unsigned int Range, bool AutoGen = false ) : mRange(Range), 
        mTable(NULL), 
        mIndex(
0),
        mAutoGenerate(AutoGen)

    
{
        srand( (unsigned)time( NULL ) );    
// 使用时间产生随机数.
        mRange = Range;
        mTable 
= new int [ mRange ];
        Generate();                
// 产生随机数.
    }


    
// 析构
    virtual ~clRandom()
    
{
        
if ( mTable != NULL ){
            delete [] mTable;
            mTable 
= NULL;
        }

        mRange 
= 0;
    }


    
// 取出随机数
    int    GetNumber    ( void )
    
{
        
int    Number = -1;

        
if ( mRange > 0 )
        
{
            Number 
= mTable[ mIndex ];    // 取出随机数.
            ++mIndex;            // 偏移取出随机数的指针.
            if ( mIndex >= mRange ){
                mIndex 
= 0;
                
if ( mAutoGenerate ){    // 是否重新产生随机数?
                    Generate();    // 产生随机数.
                }

            }

        }

        
return Number;
    }


    
// 随机数重整
    void    Generate    ( void )
    
{
        
int loop, Offset;
        
// 建立连续数字.
        for ( loop=0 ; loop<mRange ; loop++ )
        
{
            mTable[ loop ] 
= loop;
        }

        
// 依照随机数变更数字的位置.
        for ( loop=0 ; loop<mRange ; loop++ )
        
{
            
int    Temp;
            
// 使用随机数选择要变换的数字.
            Offset = (rand()%mRange)+loop;
            
if ( Offset >= mRange ){
                Offset 
-= mRange;
            }


            
// 将数字对调.
            Temp = mTable[ loop ];
            mTable[ loop ] 
= mTable[ Offset ];
            mTable[ Offset ] 
= Temp;
        }


        mIndex 
= 0;
    }

}
;

 

// 测试程序:
int  main()
{
    Random 
*RandomMaker;
    
int loop, range = 20;
    RandomMaker 
= new Random(range);
    
for(int time = 0; time < range; time++)
    
{
        std::cout 
<< "" << time << "组. ";
        
for(loop = 0; loop < range; loop++)
        
{
            std::cout 
<< " " << RandomMaker->GetNumber();
        }

        std::cout 
<< std::endl << std::endl;
        RandomMaker
->Generate();
    }
    
    
return 0;
}

值得一提的是这种方法产生的随机数是可逆的,举个例子:拼图游戏中如果图片打乱的过于随机,以致玩者根本不可能完成游戏任务,但用这种方法是绝对没有问题的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值