游戏中伪随机数的产生

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

对于一般的作法:
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;
}
值得一提的是这种方法产生的随机数是可逆的,举个例子:拼图游戏中如果图片打乱的过于随机,以致玩者根本不可能完成游戏任务,但用这种方法是绝对没有问题的。
posted @ 2014-03-14 21:54  jadeshu  阅读(179)  评论(0编辑  收藏  举报