获取外部来源的种子
Obtain a seed for an outside source
我不确定是否有人熟悉怪物牧场主游戏,但我想实现一个像他们这样的系统。
它的工作方式是,他们使用外部来源为RNG获得种子,然后创建一个怪物,并根据结果进行统计。他们使用CD,一款新的ds游戏使用声音。
我在想,从编程的意义上讲,我该如何从外部媒体获得种子,比如cd。就我所见,种子只是一个数字,所以使用C++,我如何从电脑上的东西中获得数字?我在想我可以使用插入USB端口的东西,会有点有趣吗?
编辑:我不是在研究如何获得一个随机的种子,我想知道如何读取类似的CD,以产生一个可以用作种子的数字。CD将始终产生相同的种子值,而不同的CD将产生不同的种子值。
然后根据这些文件决定一些生成种子的方案。它可以很简单,按照字母顺序读取第一个文件,然后以二进制读取文件,只将前四个字节作为32位单词。但这可能不会产生像你希望的那样独特的价值。更好的方法可能是对几个文件进行某种散列。
这里有一个简单的例子。它在K驱动器上查找大小大于sizeof(unsigned int)
的第一个文件,从中检索这么多字节,并将其存储在值中。显然,这不是很复杂,但它应该让你开始。
#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';
}
没有可移植的方法。在大多数Unix系统上,您可以读取/dev/random
或/dev/urandom
。
在Windows上,尝试CryptGenRandom
。
(对于这种应用,加密强伪随机数和"真"随机数一样好。证明我错了,你可以从世界上任何一所大学获得博士学位。)
[编辑]
对不起,我以为你在寻找一个不错的方式来滚动一个随机的角色。如果你每次都试图使用相同的数字,只需将种子存储在一个文件中,并使用任何旧的伪随机数生成器。
在unix上,只有
dd if=/dev/sr0 bs=512 count=32
或者从代码中以二进制模式打开/dev/sr0。在Windows上,请参阅此片段(来自本页)。它支持Win98/2k等。示例使用A:,但您也可以指定用于原始读取的物理驱动器为CCD_ 5或CCD_。。。etc
// 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;
}
std::string tohash;
std::cin >> tohash;
boost::hash<std::string> string_hash;
std::size_t theRandomNumber = string_hash(tohash);
将std::cin替换为从cd或文件系统读取的文件名、文件的内容等等。
- 在函数内部的声明中初始化数组,并在外部使用它
- 使外部项目可用于find_package CMake
- C++:Application.cpp中抛出了未解析的外部符号(解决方案在问题的末尾,供未来的读者参考)
- 使用外部SDK工具链文件在VisualStudio上生成项目编译错误
- C++:来自外部文件的Trivia
- 从函数角度看ID到文件路径的内部与外部映射
- C++:将外部库链接到dll库
- spdlog标头仅与外部fmt一起使用.spdlog错误:'内部':不是'fmt'
- 节俭并发:未解决的外部问题
- 如何在c++中从git建立外部库
- 未解析的外部符号_MsiLocateComponentW@12.
- 如何使用对C函数和类对象的外部调用来处理C++头文件
- 具有外部"c"和程序集的未定义函数
- 为什么导入Mixed native/CLR lib.dll的本机C++应用程序没有在Mixed lib.dll中的外部变
- 在C++中使用 gRPC 时未解析的外部符号
- 在类函数中初始化外部作用域变量
- 如果全局变量默认是外部变量,为什么要添加"extern"关键字?
- 调用外部函数,无法指定类型 C++/MVS
- 同时具有"外部"和"内联"说明符的变量
- 获取外部来源的种子