1.SRand( 123456 ) を呼んだ後、GetRand( 1000000 ) を 10000000回実行して、その戻り値を保存する
2.1をもう一度行って、2つの GetRand 10000000回の結果を比較して一致しているか確認する
↑
こちらのようなテストを行うのが以下のプログラムなのですが
#include "DxLib.h"
#define TEST_NUM 10000000
int RandResult1[ TEST_NUM ] ;
int RandResult2[ TEST_NUM ] ;
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
int i ;
// ウインドウモードで起動
ChangeWindowMode( TRUE ) ;
// DXライブラリの初期化
if( DxLib_Init() < 0 ) return -1 ;
// 乱数を初期化
SRand( 123456 ) ;
// 乱数を取得
for( i = 0; i < TEST_NUM; i++ )
{
RandResult1[ i ] = GetRand( 1000000 ) ;
}
// 乱数を初期化
SRand( 123456 ) ;
// 乱数を取得
for( i = 0; i < TEST_NUM; i++ )
{
RandResult2[ i ] = GetRand( 1000000 ) ;
}
// 2つの乱数列が一致しているかチェック
for( i = 0; i < TEST_NUM; i++ )
{
if( RandResult1[ i ] != RandResult2[ i ] )
{
break ;
}
}
// 結果を表示
DrawFormatString( 0, 0, GetColor( 255,255,255 ), "%d回の2つの乱数は一致%s", TEST_NUM, i == TEST_NUM ? "しています" : "していません" ) ;
// キー入力待ち
WaitKey() ;
// DXライブラリの後始末
DxLib_End() ;
// ソフトの終了
return 0 ;
}
結果は『10000000回の2つの乱数は一致しています』となりました
なので、本来であれば SRand を事前に行う
> リプレイ記録:「初期化・ロード(初回)・SRand(固定値)宣言」→「ゲーム(リプレイデータ記録)」→リプレイデータ書き出し
> リプレイ再生:「初期化・ロード(初回)・SRand(固定値)宣言」→「ゲーム(リプレイデータ再生)」→「デリート」→「初期化・ロード(2週目)SRand(固定値)宣言」→「ゲーム(リプレイデータ再生)(2週目)」
↑こちらの処理であれば正常にリプレイを再現できるはずです
なので、リプレイ処理に関わらない意図しない箇所で GetRand を使用してしまっていないか確認してみてください
また、リファレンスには載っていませんがプログラム全体で乱数の情報を共有してしまう
SRand, GetRand ではなく、独立した乱数取得を行うための以下の関数がありますので
// 乱数ハンドルを作成する( 戻り値 0以外:乱数ハンドル 0:エラー )
DWORD_PTR CreateRandHandle( int Seed = -1 ) ;
// 乱数ハンドルを削除する
int DeleteRandHandle( DWORD_PTR RandHandle ) ;
// 乱数ハンドルの初期値を再設定する
int SRandHandle( DWORD_PTR RandHandle, int Seed ) ;
// 乱数ハンドルを使用して乱数を取得する( RandMax : 返って来る値の最大値 )
int GetRandHandle( DWORD_PTR RandHandle, int RandMax ) ;
リプレイに関わる乱数については上記の関数を使用して取得したほうが確実かと思います
使い方の例
グローバル変数の定義箇所
DWORD_PTR GameRandHandle;
ゲーム開始の初期化処理
// 乱数ハンドルを作成
GameRandHandle = CreateRandHandle( 固定値 );
ゲーム中のリプレイ処理に関わる乱数の取得箇所
// GetRandHandle で乱数を取得
int RandNum = GetRandHandle( GameRandHandle, 乱数最大値 );
ゲーム終了( ゲームオーバー後など )
// 乱数ハンドルを削除
DeleteRandHandle( GameRandHandle );
リプレイ開始前の初期化処理
// 乱数ハンドルを作成
GameRandHandle = CreateRandHandle( 固定値 );
リプレイ中の乱数の取得箇所
// GetRandHandle で乱数を取得
int RandNum = GetRandHandle( GameRandHandle, 乱数最大値 );
リプレイ終了
// 乱数ハンドルを削除
DeleteRandHandle( GameRandHandle );
よろしければお試しください m(_ _)m