C++游戲教程基本技巧之隨機化詳解
0. 引言
小游戲中時常要用到隨機數(shù),今天就來談?wù)勥@個所謂的“隨機”。
1. 隨機數(shù) rand()
我們要使用隨機數(shù)(嚴(yán)格意義上是偽隨機)的話,C++ 中就有 rand() 來提供了這一操作。
rand()返回值是整數(shù)。在不同系統(tǒng)的編譯器下,返回值的范圍不同,我們姑且認(rèn)為足夠我們使用。
設(shè)我們要獲取數(shù)x,逐步推導(dǎo):
當(dāng)x∈[0,100] 時,可以寫成 rand()%101;
當(dāng) x∈[1,100] 時,可以轉(zhuǎn)化為x′+1(x′∈[0,99]),寫成 rand()%100+1;
當(dāng)x∈[l,r] 時,可以轉(zhuǎn)化為x′+l(x′∈[0,r−l]),寫成 rand()%(r-l+1)+l。
可現(xiàn)實總是不盡如人意:

為什么每次隨機出來的序列都是一樣的呢?這里我們就要講到下面的東西了
2. 設(shè)置隨機種子 srand()
畢竟是偽隨機,所以每次生成的隨機序列需要有一個初始的隨機種子(無符號整數(shù)),srand() 提供了這一操作。
比如設(shè)置隨機種子為114514,可以寫成 srand(114514);。
然而

這意味著種子要隨機。
3. 時間 time()
time() 返回從 1970.1.1 1970.1.1 1970.1.1 至今的秒數(shù),參數(shù)直接填 NULL 或 0 0 0(也就是空指針)即可。
設(shè)置為種子,也就是 srand(time(0));。
效果顯著:

4. 隨機排列 random_shuffle()
如果有一個數(shù)組 a a a,如何讓其進(jìn)行隨機排列呢?
C++ 有函數(shù) random_shuffle()。
參數(shù)和用法與 sort() 類似,直接調(diào)用即可。
示例代碼:
#include<bits/stdc++.h>
using namespace std;
int main()
{
srand(time(0));
int n,a[105];
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
random_shuffle(a+1,a+n+1);
for(int i=1;i<=n;i++)
{
cout<<a[i]<<' ';
}
return 0;
}
效果:

5. 隨機基本案例
5-1. 隨機 01 矩陣
給定邊長n,要求生成一個隨機 01 矩陣。
示例代碼:
#include<bits/stdc++.h>
using namespace std;
int main()
{
srand(time(0));
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
cout<<rand()%2;
}
cout<<endl;
}
return 0;
}
效果:

5-2. 隨機區(qū)間
給定n,要求生成n個區(qū)間[l,r](l≤r),并且這些區(qū)間是[1,n]的子區(qū)間。
每次分別對于l,r隨機,然后調(diào)整l,r大小位置。
示例代碼:
#include<bits/stdc++.h>
using namespace std;
int main()
{
srand(time(0));
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
int l=rand()%n+1,r=rand()%n+1;
if(l>r) swap(l,r);//防止 l>r
cout<<l<<' '<<r<<endl;
}
return 0;
}
效果:

5-3. 隨機浮點數(shù)
給定n和k,要求生成n個[0,n] 的k位浮點數(shù)(不可以有后綴0)。
分成整數(shù)部分和小數(shù)部分考慮。
整數(shù)部分生成[0,n] 的整數(shù),小數(shù)部分生成k位 [0,9] 的數(shù)(在位數(shù)允許時,可以生成一個[0,10k−1] 的整數(shù)代替小數(shù))。
當(dāng)然,要特判整數(shù)為n的情況。若小數(shù)部分>0,就不在[0,n]內(nèi)了。
處理后綴0時,只要把其存進(jìn)字符串處理即可。
示例代碼:
#include<bits/stdc++.h>
using namespace std;
int main()
{
srand(time(0));
int n,k;
cin>>n>>k;
for(int i=1;i<=n;i++)
{
int d=rand()%(n+1);
cout<<d;
if(d==n)
{
cout<<endl;
continue;
}
string s=".";
for(int j=1;j<=k;j++)
{
s+=(char)(rand()%10+48);
}
while(s[s.size()-1]=='0'&&s.size()>2) s.erase(s.size()-1);//防止后綴 0
cout<<s<<endl;
}
return 0;
}
效果:

5-4. 隨機整數(shù)
給定n,l,r(l,r∈Z,l≤r),要求生成n個整數(shù)x(x∈[l,r])。
可能含有負(fù)數(shù),該怎么辦呢?
分三類討論:
1.當(dāng)l≤r≤0 時,先輸出 -,然后生成[∣r∣,∣l∣] 范圍的整數(shù)。
2.當(dāng)l≤0≤r 時,先隨機t=0或1來確定符號。
- 當(dāng)t=0時,輸出
-,生成[0,∣l∣] 的整數(shù)。 - 當(dāng)t=1時,生成[0,r]的整數(shù)。
3.當(dāng)0≤l≤r時,直接生成[l,r] 的整數(shù)。
注意以上操作中輸出 -0 的情況要處理一下。
示例代碼:
#include<bits/stdc++.h>
using namespace std;
int main()
{
srand(time(0));
int n,l,r;
cin>>n>>l>>r;
while(n--)
{
if(l<=r&&r<=0)
{
int d=rand()%(abs(l)-abs(r)+1)+abs(r);
if(d) cout<<'-';//防止 -0
cout<<d;
}
else if(l<=0&&0<=r)
{
int f=rand()%2;
if(f) cout<<rand()%(r+1);
else
{
int d=rand()%(abs(l)+1);
if(d) cout<<'-';//防止 -0
cout<<d;
}
}
else cout<<rand()%(r-l+1)+l;
puts("");
}
return 0;
}
效果:

以上就是C++游戲教程基本技巧之隨機化詳解的詳細(xì)內(nèi)容,更多關(guān)于C++隨機的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
c語言網(wǎng)絡(luò)編程-標(biāo)準(zhǔn)步驟(改進(jìn)版)
這篇文章主要介紹了c語言網(wǎng)絡(luò)編程-標(biāo)準(zhǔn)步驟的改進(jìn)說明,需要的朋友可以參考下2014-01-01
詳解C++中二進(jìn)制求補運算符與下標(biāo)運算符的用法
這篇文章主要介紹了C++中二進(jìn)制求補運算符與下標(biāo)運算符的用法,是C++入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下2016-01-01
C++ Custom Control控件向父窗體發(fā)送對應(yīng)的消息
這篇文章主要介紹了C++ Custom Control控件向父窗體發(fā)送對應(yīng)的消息的相關(guān)資料,需要的朋友可以參考下2015-06-06
MoveWindow() SetWindowPos()的區(qū)別于聯(lián)系
這篇文章主要介紹了VC++中MoveWindow() SetWindowPos()的區(qū)別于聯(lián)系,需要的朋友可以參考下2015-01-01
C++11中value category(值類別)及move semantics(移動語義)的介紹
這篇文章主要給大家介紹了C++11中value category(值類別)及move semantics(移動語義)的介紹,文中介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-05-05
C++實現(xiàn)Matlab的zp2tf函數(shù)的示例代碼
matlab?的?zp2tf?函數(shù)的作用是將極點形式的?H(s)?函數(shù)的分母展開,本文主要為大家介紹了C++實現(xiàn)Matlab的zp2tf函數(shù)示例代碼,需要的可以參考一下2023-04-04
C中的open(),?write(),?close(),?fopen()詳解
本文主要介紹了C語言中的open(),?write(),?close(),?fopen()等文件操作函數(shù),open()函數(shù)用于打開文件,write()函數(shù)用于寫入數(shù)據(jù),close()函數(shù)用于關(guān)閉已打開的文件描述符2024-10-10

