2011-06-24 9 views
3

モンスター牧場のゲームに精通している人がいるかどうかはわかりませんが、自分のようなシステムを実装したいと思います。外部ソースのシードを取得する

これは、外部ソースを使用してRNGの種を取得し、モンスターを作成し、その結果に基づいて統計を作成することです。彼らはCDを使用し、新しいdsゲームのサウンドを使用します。

私はプログラミングの意味でこのようなCDの外側の内側からシードをどのように取得するのだろうと思っていました。私の知る限りでは、種子は単なる数字なので、C++を使用すると、コンピュータに接続されたものから数値を得ることができますか?私はUSBポートに接続されているものを使うことができると思っていましたが、面白いでしょうか?

EDIT:ランダムなシードを取得する方法を見ていないので、シードとして使用できる数字を生成するために、そのようなCDをどのように読むことができるかを知りたい。 CDは常に同じシード値を生成し、異なるCDは異なるシード値を生成します。

+1

オン* nixでは、 '/ dev/random'がジョブを行います。 –

+0

@Cicada私はあなたが意味することを理解していません – Skeith

+0

Linuxを使用していますか?はいの場合、私は答えを詳述することができます。 –

答えて

0

ポータブルな方法はありません。ほとんどのUnixシステムでは、/dev/randomまたは/dev/urandomを読むことができます。

Windowsでは、CryptGenRandomを試してください。

(アプリケーションのこの種のために、暗号的に強い疑似乱数が「真」の乱数と同じくらい良いです。私は間違っていることを証明し、世界のどの大学から博士号を取得することができます。)

申し訳ありませんが、あなたはランダムなキャラクターをまっすぐに転がす方法を探していたと思います。毎回同じ番号を使用する場合は、シードをファイルに保存して、古い擬似乱数ジェネレータを使用してください。

3

はい、私はそのゲームを覚えています。シンプルなソリューション。 boost.filesystemのようなものを使って、ドライブ上のファイルのリストを取得します。

次に、これらのファイルに基づいてシードを生成するスキームを決定します。最初のファイルをアルファベット順にとり、ファイルをバイナリで読み込み、最初の4バイトを32ビットワードとして読み込むだけの簡単な方法です。しかし、それはおそらくあなたが望むほどユニークな値を生成しないでしょう。おそらく、いくつかの種類のファイルを含む何らかのハッシュを行うのがよいでしょう。

ここに簡単な例があります。これは、Kドライブの最初のファイルが、sizeof(unsigned int)より大きいサイズを持ち、そこから多くのバイトを取り出し、値に格納します。明らかにそれはあまり洗練されていませんが、それはあなたを始めるはずです。 UNIX上

#include <iostream> 
#include <fstream> 
#include <boost/filesystem.hpp> 

int main() 
{ 
    namespace fs = boost::filesystem; 

    unsigned int seed = 0; 
    fs::recursive_directory_iterator begin("K:/"), end; 
    while (begin != end) 
    { 
     if (fs::is_regular_file(*begin) 
      && fs::file_size(*begin) >= sizeof(seed)) 
     { 
      std::ifstream fin(begin->path().string(), std::ios::binary); 
      fin.read((char*)&seed, sizeof(seed)); 
      break; 
     } 

     ++begin; 
    } 

    std::cout << "Seed = " << seed << '\n'; 
} 
+0

"boost.filesystemのようなもの"このビットは非常に詳細に質問LOLの要点でした。 – Skeith

+0

もう一つの方法は、 'dir/s/b'の出力をつかんでハッシュアルゴリズムを実行することです。 – Brian

+0

@Skeith:私の更新を見てください。それは役に立ちますか? –

0

、コードからバイナリモードでだけ

dd if=/dev/sr0 bs=512 count=32 

又はオープン/ DEV/SR0。 Windowsでは、このスニペット(from this page)を参照してください。これは、Win98のは/ 2Kなどのサンプルを使用してサポートして:,いますが、 を指定することができるとのstd :: cinをを交換し

// All msdos data structures must be packed on a 1 byte boundary 
#pragma pack (1) 
struct 
{ 
    DWORD StartingSector ; 
    WORD NumberOfSectors ; 
    DWORD pBuffer; 
}ControlBlock; 
#pragma pack() 

#pragma pack (1) 
typedef struct _DIOC_REGISTERS 
{ 
    DWORD reg_EBX; 
    DWORD reg_EDX; 
    DWORD reg_ECX; 
    DWORD reg_EAX; 
    DWORD reg_EDI; 
    DWORD reg_ESI; 
    DWORD reg_Flags; 
} DIOC_REGISTERS ; 
#pragma pack() 

char * ReadSectors(int drive, DWORD startinglogicalsector, int numberofsectors) 
{ 

    char* buffer = (char*)malloc (512*numberofsectors); 
    HANDLE hDevice ; 
    DIOC_REGISTERS reg ; 
    BOOL fResult ; 
    DWORD cb ; 

    // Creating handle to vwin32.vxd (win 9x) 
    hDevice = CreateFile ("\\\\.\\vwin32", 
      0, 
      0, 
      NULL, 
      0, 
      FILE_FLAG_DELETE_ON_CLOSE, 
      NULL); 

    if (hDevice == INVALID_HANDLE_VALUE) 
    { 
     // win NT/2K/XP code 
     HANDLE hDevice; 
     DWORD bytesread; 

     char _devicename[] = "\\\\.\\A:"; 
     _devicename[4] += drive; 

     // Creating a handle to disk drive using CreateFile() function .. 
     hDevice = CreateFile(_devicename, 
       GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 
       NULL, OPEN_EXISTING, 0, NULL); 

     if (hDevice == INVALID_HANDLE_VALUE) 
      return NULL; 

     // Setting the pointer to point to the start of the sector we want to read .. 
     SetFilePointer (hDevice, (startinglogicalsector*512), NULL, FILE_BEGIN); 

     if (!ReadFile (hDevice, buffer, 512*numberofsectors, &bytesread, NULL)) 
      return NULL; 
    } 
    else 
    { 
     // code for win 95/98 
     ControlBlock.StartingSector = (DWORD)startinglogicalsector; 
     ControlBlock.NumberOfSectors = (DWORD)numberofsectors ; 
     ControlBlock.pBuffer = (DWORD)buffer ; 

     //----------------------------------------------------------- 
     // SI contains read/write mode flags 
     // SI=0h for read and SI=1h for write 
     // CX must be equal to ffffh for 
     // int 21h's 7305h extention 
     // DS:BX -> base addr of the 
     // control block structure 
     // DL must contain the drive number 
     // (01h=A:, 02h=B: etc) 
     //----------------------------------------------------------- 

     reg.reg_ESI = 0x00 ; 
     reg.reg_ECX = -1 ; 
     reg.reg_EBX = (DWORD)(&ControlBlock); 
     reg.reg_EDX = drive+1; 
     reg.reg_EAX = 0x7305 ; 

     // 6 == VWIN32_DIOC_DOS_DRIVEINFO 
     fResult = DeviceIoControl (hDevice, 
       6, 
       &(reg), 
       sizeof (reg), 
       &(reg), 
       sizeof (reg), 
       &cb, 
       0); 

     if (!fResult || (reg.reg_Flags & 0x0001)) return NULL;  
    } 

    CloseHandle(hDevice); 
    return buffer; 
} 
0
std::string tohash; 
std::cin >> tohash; 
boost::hash<std::string> string_hash; 
std::size_t theRandomNumber = string_hash(tohash); 

"\\\\.\\PhysicalDrive0"または"\\\\.\\PhysicalDrive1"などの生の読み取りのための物理ドライブ...などCDまたはファイルシステムから読み取られたファイル名、ファイルの内容など。

+0

あなたのコードの下にある文章は、私がやるべきことを尋ねています。ちょうどそれは非常に有用な答えではありません行きます。 – Skeith

関連する問題