Merge branch 'countermeasures' into alex-and-isaac
This commit is contained in:
@@ -120,6 +120,7 @@ NEARDATA boolean mrg_to_wielded = FALSE;
|
||||
/* weapon picked is merged with wielded one */
|
||||
|
||||
NEARDATA boolean in_steed_dismounting = FALSE;
|
||||
NEARDATA boolean has_strong_rngseed = FALSE;
|
||||
|
||||
NEARDATA coord bhitpos = DUMMY;
|
||||
NEARDATA coord doors[DOORMAX] = { DUMMY };
|
||||
|
||||
1
src/do.c
1
src/do.c
@@ -1420,6 +1420,7 @@ boolean at_stairs, falling, portal;
|
||||
/* we'll reach here if running in wizard mode */
|
||||
error("Cannot continue this game.");
|
||||
}
|
||||
reseed_random();
|
||||
minit(); /* ZEROCOMP */
|
||||
getlev(fd, hackpid, new_ledger, FALSE);
|
||||
(void) nhclose(fd);
|
||||
|
||||
@@ -51,6 +51,8 @@
|
||||
boolean fuzzymatch (const char *, const char *,
|
||||
const char *, boolean)
|
||||
void setrandom (void)
|
||||
void init_random (void)
|
||||
void reseed_random (void)
|
||||
time_t getnow (void)
|
||||
int getyear (void)
|
||||
char * yymmdd (time_t)
|
||||
@@ -848,44 +850,59 @@ extern struct tm *FDECL(localtime, (time_t *));
|
||||
#endif
|
||||
STATIC_DCL struct tm *NDECL(getlt);
|
||||
|
||||
void
|
||||
setrandom()
|
||||
/* Sets the seed for the random number generator */
|
||||
static void
|
||||
set_random(unsigned long seed)
|
||||
{
|
||||
unsigned long seed = (unsigned long) getnow(); /* time((TIME_type) 0) */
|
||||
|
||||
#if defined(UNIX) || defined(VMS)
|
||||
{
|
||||
unsigned long pid = (unsigned long) getpid();
|
||||
|
||||
/* Quick dirty band-aid to prevent PRNG prediction */
|
||||
if (pid) {
|
||||
if (!(pid & 3L))
|
||||
pid -= 1L;
|
||||
seed *= pid;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_ISAAC64
|
||||
init_isaac64(seed);
|
||||
#else
|
||||
/* the types are different enough here that sweeping the different
|
||||
* routine names into one via #defines is even more confusing
|
||||
*/
|
||||
#ifdef RANDOM /* srandom() from sys/share/random.c */
|
||||
# ifdef RANDOM /* srandom() from sys/share/random.c */
|
||||
srandom((unsigned int) seed);
|
||||
#else
|
||||
#if defined(__APPLE__) || defined(BSD) || defined(LINUX) || defined(ULTRIX) \
|
||||
# else
|
||||
# if defined(__APPLE__) || defined(BSD) || defined(LINUX) || defined(ULTRIX) \
|
||||
|| defined(CYGWIN32) /* system srandom() */
|
||||
#if defined(BSD) && !defined(POSIX_TYPES) && defined(SUNOS4)
|
||||
# if defined(BSD) && !defined(POSIX_TYPES) && defined(SUNOS4)
|
||||
(void)
|
||||
#endif
|
||||
# endif
|
||||
srandom((int) seed);
|
||||
#else
|
||||
#ifdef UNIX /* system srand48() */
|
||||
# else
|
||||
# ifdef UNIX /* system srand48() */
|
||||
srand48((long) seed);
|
||||
#else /* poor quality system routine */
|
||||
# else /* poor quality system routine */
|
||||
srand((int) seed);
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/* An appropriate version of this must always be provided in
|
||||
port-specific code somewhere. It returns a number suitable
|
||||
as seed for the random number generator */
|
||||
extern unsigned long NDECL(sys_random_seed);
|
||||
|
||||
/*
|
||||
* Initializes the random number generator.
|
||||
* Only call once.
|
||||
*/
|
||||
void
|
||||
init_random()
|
||||
{
|
||||
set_random(sys_random_seed());
|
||||
}
|
||||
|
||||
/* Reshuffles the random number generator. */
|
||||
void
|
||||
reseed_random()
|
||||
{
|
||||
/* only reseed if we are certain that the seed generation is unguessable
|
||||
* by the players. */
|
||||
if (has_strong_rngseed)
|
||||
init_random();
|
||||
}
|
||||
|
||||
time_t
|
||||
|
||||
161
src/isaac64.c
Normal file
161
src/isaac64.c
Normal file
@@ -0,0 +1,161 @@
|
||||
/*Written by Timothy B. Terriberry (tterribe@xiph.org) 1999-2009
|
||||
CC0 (Public domain) - see http://creativecommons.org/publicdomain/zero/1.0/ for details
|
||||
Based on the public domain ISAAC implementation by Robert J. Jenkins Jr.*/
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include "isaac64.h"
|
||||
|
||||
#define ISAAC64_MASK ((uint64_t)0xFFFFFFFFFFFFFFFFULL)
|
||||
|
||||
#if (defined(__STDC__) && __STDC_VERSION__ >= 199901L)
|
||||
#define HAS_INLINE
|
||||
#endif
|
||||
|
||||
/* Extract ISAAC64_SZ_LOG bits (starting at bit 3). */
|
||||
#ifdef HAS_INLINE
|
||||
static inline uint32_t lower_bits(uint64_t x)
|
||||
#else
|
||||
static uint32_t lower_bits(uint64_t x)
|
||||
#endif
|
||||
{
|
||||
return (x & ((ISAAC64_SZ-1) << 3)) >>3;
|
||||
}
|
||||
|
||||
/* Extract next ISAAC64_SZ_LOG bits (starting at bit ISAAC64_SZ_LOG+2). */
|
||||
#ifdef HAS_INLINE
|
||||
static inline uint32_t upper_bits(uint64_t y)
|
||||
#else
|
||||
static uint32_t upper_bits(uint64_t y)
|
||||
#endif
|
||||
{
|
||||
return (y >> (ISAAC64_SZ_LOG+3)) & (ISAAC64_SZ-1);
|
||||
}
|
||||
|
||||
static void isaac64_update(isaac64_ctx *_ctx){
|
||||
uint64_t *m;
|
||||
uint64_t *r;
|
||||
uint64_t a;
|
||||
uint64_t b;
|
||||
uint64_t x;
|
||||
uint64_t y;
|
||||
int i;
|
||||
m=_ctx->m;
|
||||
r=_ctx->r;
|
||||
a=_ctx->a;
|
||||
b=_ctx->b+(++_ctx->c);
|
||||
for(i=0;i<ISAAC64_SZ/2;i++){
|
||||
x=m[i];
|
||||
a=~(a^a<<21)+m[i+ISAAC64_SZ/2];
|
||||
m[i]=y=m[lower_bits(x)]+a+b;
|
||||
r[i]=b=m[upper_bits(y)]+x;
|
||||
x=m[++i];
|
||||
a=(a^a>>5)+m[i+ISAAC64_SZ/2];
|
||||
m[i]=y=m[lower_bits(x)]+a+b;
|
||||
r[i]=b=m[upper_bits(y)]+x;
|
||||
x=m[++i];
|
||||
a=(a^a<<12)+m[i+ISAAC64_SZ/2];
|
||||
m[i]=y=m[lower_bits(x)]+a+b;
|
||||
r[i]=b=m[upper_bits(y)]+x;
|
||||
x=m[++i];
|
||||
a=(a^a>>33)+m[i+ISAAC64_SZ/2];
|
||||
m[i]=y=m[lower_bits(x)]+a+b;
|
||||
r[i]=b=m[upper_bits(y)]+x;
|
||||
}
|
||||
for(i=ISAAC64_SZ/2;i<ISAAC64_SZ;i++){
|
||||
x=m[i];
|
||||
a=~(a^a<<21)+m[i-ISAAC64_SZ/2];
|
||||
m[i]=y=m[lower_bits(x)]+a+b;
|
||||
r[i]=b=m[upper_bits(y)]+x;
|
||||
x=m[++i];
|
||||
a=(a^a>>5)+m[i-ISAAC64_SZ/2];
|
||||
m[i]=y=m[lower_bits(x)]+a+b;
|
||||
r[i]=b=m[upper_bits(y)]+x;
|
||||
x=m[++i];
|
||||
a=(a^a<<12)+m[i-ISAAC64_SZ/2];
|
||||
m[i]=y=m[lower_bits(x)]+a+b;
|
||||
r[i]=b=m[upper_bits(y)]+x;
|
||||
x=m[++i];
|
||||
a=(a^a>>33)+m[i-ISAAC64_SZ/2];
|
||||
m[i]=y=m[lower_bits(x)]+a+b;
|
||||
r[i]=b=m[upper_bits(y)]+x;
|
||||
}
|
||||
_ctx->b=b;
|
||||
_ctx->a=a;
|
||||
_ctx->n=ISAAC64_SZ;
|
||||
}
|
||||
|
||||
static void isaac64_mix(uint64_t _x[8]){
|
||||
static const unsigned char SHIFT[8]={9,9,23,15,14,20,17,14};
|
||||
int i;
|
||||
for(i=0;i<8;i++){
|
||||
_x[i]-=_x[(i+4)&7];
|
||||
_x[(i+5)&7]^=_x[(i+7)&7]>>SHIFT[i];
|
||||
_x[(i+7)&7]+=_x[i];
|
||||
i++;
|
||||
_x[i]-=_x[(i+4)&7];
|
||||
_x[(i+5)&7]^=_x[(i+7)&7]<<SHIFT[i];
|
||||
_x[(i+7)&7]+=_x[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void isaac64_init(isaac64_ctx *_ctx,const unsigned char *_seed,int _nseed){
|
||||
_ctx->a=_ctx->b=_ctx->c=0;
|
||||
memset(_ctx->r,0,sizeof(_ctx->r));
|
||||
isaac64_reseed(_ctx,_seed,_nseed);
|
||||
}
|
||||
|
||||
void isaac64_reseed(isaac64_ctx *_ctx,const unsigned char *_seed,int _nseed){
|
||||
uint64_t *m;
|
||||
uint64_t *r;
|
||||
uint64_t x[8];
|
||||
int i;
|
||||
int j;
|
||||
m=_ctx->m;
|
||||
r=_ctx->r;
|
||||
if(_nseed>ISAAC64_SEED_SZ_MAX)_nseed=ISAAC64_SEED_SZ_MAX;
|
||||
for(i=0;i<_nseed>>3;i++){
|
||||
r[i]^=(uint64_t)_seed[i<<3|7]<<56|(uint64_t)_seed[i<<3|6]<<48|
|
||||
(uint64_t)_seed[i<<3|5]<<40|(uint64_t)_seed[i<<3|4]<<32|
|
||||
(uint64_t)_seed[i<<3|3]<<24|(uint64_t)_seed[i<<3|2]<<16|
|
||||
(uint64_t)_seed[i<<3|1]<<8|_seed[i<<3];
|
||||
}
|
||||
_nseed-=i<<3;
|
||||
if(_nseed>0){
|
||||
uint64_t ri;
|
||||
ri=_seed[i<<3];
|
||||
for(j=1;j<_nseed;j++)ri|=(uint64_t)_seed[i<<3|j]<<(j<<3);
|
||||
r[i++]^=ri;
|
||||
}
|
||||
x[0]=x[1]=x[2]=x[3]=x[4]=x[5]=x[6]=x[7]=(uint64_t)0x9E3779B97F4A7C13ULL;
|
||||
for(i=0;i<4;i++)isaac64_mix(x);
|
||||
for(i=0;i<ISAAC64_SZ;i+=8){
|
||||
for(j=0;j<8;j++)x[j]+=r[i+j];
|
||||
isaac64_mix(x);
|
||||
memcpy(m+i,x,sizeof(x));
|
||||
}
|
||||
for(i=0;i<ISAAC64_SZ;i+=8){
|
||||
for(j=0;j<8;j++)x[j]+=m[i+j];
|
||||
isaac64_mix(x);
|
||||
memcpy(m+i,x,sizeof(x));
|
||||
}
|
||||
isaac64_update(_ctx);
|
||||
}
|
||||
|
||||
uint64_t isaac64_next_uint64(isaac64_ctx *_ctx){
|
||||
if(!_ctx->n)isaac64_update(_ctx);
|
||||
return _ctx->r[--_ctx->n];
|
||||
}
|
||||
|
||||
uint64_t isaac64_next_uint(isaac64_ctx *_ctx,uint64_t _n){
|
||||
uint64_t r;
|
||||
uint64_t v;
|
||||
uint64_t d;
|
||||
do{
|
||||
r=isaac64_next_uint64(_ctx);
|
||||
v=r%_n;
|
||||
d=r-v;
|
||||
}
|
||||
while(((d+_n-1)&ISAAC64_MASK)<d);
|
||||
return v;
|
||||
}
|
||||
@@ -982,6 +982,8 @@ mklev()
|
||||
struct mkroom *croom;
|
||||
int ridx;
|
||||
|
||||
reseed_random();
|
||||
|
||||
init_mapseen(&u.uz);
|
||||
if (getbones())
|
||||
return;
|
||||
@@ -1009,6 +1011,8 @@ mklev()
|
||||
entered; rooms[].orig_rtype always retains original rtype value */
|
||||
for (ridx = 0; ridx < SIZE(rooms); ridx++)
|
||||
rooms[ridx].orig_rtype = rooms[ridx].rtype;
|
||||
|
||||
reseed_random();
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -692,7 +692,7 @@ initoptions_init()
|
||||
reset_commands(TRUE); /* init */
|
||||
|
||||
/* initialize the random number generator */
|
||||
setrandom();
|
||||
init_random();
|
||||
|
||||
/* for detection of configfile options specified multiple times */
|
||||
iflags.opt_booldup = iflags.opt_compdup = (int *) 0;
|
||||
|
||||
26
src/rnd.c
26
src/rnd.c
@@ -4,6 +4,31 @@
|
||||
|
||||
#include "hack.h"
|
||||
|
||||
#ifdef USE_ISAAC64
|
||||
#include "isaac64.h"
|
||||
|
||||
static isaac64_ctx rng_state;
|
||||
|
||||
void
|
||||
init_isaac64(unsigned long seed)
|
||||
{
|
||||
unsigned char new_rng_state[sizeof(seed)];
|
||||
int i;
|
||||
for (i=0; i<sizeof(seed); i++) {
|
||||
new_rng_state[i]= (unsigned char)(seed & 0xFF);
|
||||
seed >>= 8;
|
||||
}
|
||||
|
||||
isaac64_init(&rng_state, new_rng_state, sizeof(seed));
|
||||
}
|
||||
|
||||
static int
|
||||
RND(int x)
|
||||
{
|
||||
return (isaac64_next_uint64(&rng_state) % x);
|
||||
}
|
||||
|
||||
#else
|
||||
/* "Rand()"s definition is determined by [OS]conf.h */
|
||||
#if defined(LINT) && defined(UNIX) /* rand() is long... */
|
||||
extern int NDECL(rand);
|
||||
@@ -16,6 +41,7 @@ extern int NDECL(rand);
|
||||
#define RND(x) ((int) ((Rand() >> 3) % (x)))
|
||||
#endif
|
||||
#endif /* LINT */
|
||||
#endif
|
||||
|
||||
/* 0 <= rn2(x) < x */
|
||||
int
|
||||
|
||||
@@ -125,12 +125,12 @@ boolean exclude_cookie;
|
||||
case 2: /*(might let a bogus input arg sneak thru)*/
|
||||
case 1:
|
||||
beginning = (long) true_rumor_start;
|
||||
tidbit = Rand() % true_rumor_size;
|
||||
tidbit = rn2(true_rumor_size);
|
||||
break;
|
||||
case 0: /* once here, 0 => false rather than "either"*/
|
||||
case -1:
|
||||
beginning = (long) false_rumor_start;
|
||||
tidbit = Rand() % false_rumor_size;
|
||||
tidbit = rn2(false_rumor_size);
|
||||
break;
|
||||
default:
|
||||
impossible("strange truth value for rumor");
|
||||
|
||||
Reference in New Issue
Block a user