yojimbos_law icon

TCRS enchantment generating algorithm

yojimbos_law | PRO | 07/03/19 02:56:08 PM UTC | 0 ⭐ | 690 👁️ | Never ⏰ | []
text |

4.75 KB

|

None

|

0 👍

/

0 👎

/* 
int sd;
//this is going to be our sequence of untempered mt_rand() values.
//values 0 through 623 are set by mt_srand(), values after that are generated by mt_reload() in sets of 624.
int[int] s;
int mt_index = 623;
//this will be used to track when we need to call mt_reload().
int random_numbers_left;
 //this is the MT recursion function, maybe?
int twist(int m, int u,int v){
	return ( m ^ ( ( ( u & 2147483648 ) | ( v & 2147483647  ) ) >> 1 )  ^ ( ( 4294967295 * ( u & 1 ) ) & 2567483615 ) ) ;
}
 //this is the tempering function. God only knows what it does.
int temper(int x){
	int s_one;
	s_one = s[x];
	s_one ^= (s_one >> 11);
	s_one ^= (s_one <<  7) & 2636928640;
	s_one ^= (s_one << 15) & 4022730752;
	return ( s_one ^ (s_one >> 18) );
}
  void mt_srand(int seed){
	sd = seed;
	clear(s);
	mt_index = 623;
	random_numbers_left = 0;
 	//this is how mt_srand() converts the seed into a 624 word initial condition.
	s[0] = sd & 2147483647;
 	for j from 1 to 623{
		s[j] = ( ( 1812433253 * ( s[j-1] ^ ( s[j-1] >> 30 ) )) + j ) & 4294967295  ;
	}
}
 void mt_reload(){		
	//this generates the next 624 terms, which are the first 624 outputs of mt_rand() before tempering, probably? and I don't care about more than that, probably?
	//for i from 0 to 623{
	//	s[i+624] = twist(s[i+397],s[i],s[i]);
	for i from mt_index to (mt_index+623){
		s[i+1] = twist(s[i-226],s[i-623],s[i-623]);
	}
	random_numbers_left+= 624;
}
 //this is going to actually spit out random numbers in the specified range, allegedly.
int mt_rand(int min, int max){
	mt_index++;
	if(random_numbers_left == 0){
		mt_reload();
	}
	else{
		random_numbers_left--;
	}
	return (min +  ( max - min + 1 ) * (( temper(mt_index) >> 1 )  / ( 2147483647 + 1.0)))  ;
}
    //returns the [position]-th number that mt_rand([low],[high]) would return in PHP 5.3 when seeded with [seed]
int[int] seeded_mt_rand(int seed,int low, int high, int position){
 	int[int] ret;
	mt_srand(seed);
	for i from 1 to position{
		ret[i] = mt_rand(low,high);
	}
 	return ret;
}
 */
   //glibc rand()
	int next;
	int but = 2**31;
	int bot = 2**16;
	int[int] s;
	int place = 0;
	void srand(int x){
		clear(s);
		//probably wants to be an unsigned int (i.e. in range [0,2**32-1]) based on php-src/ext/standard/rand.c lines 44-52
		s[0] = x;
		for i from 1 to 30{
			s[i] = (s[i-1] * 16807) % (but-1);
		}
		for i from 31 to 33{
			s[i] = s[i-31];
		}
		for i from 34 to (344){
			s[i] = (s[i-3] + s[i-31]) % (2*but);
		}
		place = 344;
	}
 	int rand(int min, int max){
		//LCG stuff:
			//from IBM and C and POSIX
			//next = (1103515245 * next + 12345);
			//next %= but;
			//next &= but-bot;
 			//from some other C thing
			//next = (1103515245 * next + 12345);
			//next %= but*2;
			//next &= but-bot;
 			//from MS Visual C
			//next = (214013 * next + 2531011);
			//next %= 2*but;
			//next &= but-bot;
  		//glibc implementation
		s[place+1] = (s[place-2] + s[place-30]) % (2*but);
		next = s[place+1] >> 1;
		place++;
 		return (min +  ( max - min + 1 ) * ( next   / ( (but -1) + 1.0)))  ;
		//return (next);
	}
 	int seeded_rand(int seed, int low, int high){
		srand(seed);
		return rand(low, high);
	}
            int[int] array_rand(int[int] source, int num_req)
{
    int num_avail = source.count();
    int dest_index = 0;
    int source_index = 0;
    int[int] dest;  // yes, i know this is a map; didn't see an easy way to dynamically allocate arrays
     if((num_req == 0)||(num_req > num_avail))
    {
        abort("Second argument has to be between 1 and the number of elements in the array");
    }
     while(num_req > 0)
    {
        // the PHP source's version divides by (PHP_RAND_MAX + 1.0), which may or may not be required depending on your RNG
        //float randval = mt_rand(0,2147483647).to_float()/(2147483648).to_float();
		float randval = rand(0,2147483647).to_float()/(2147483648).to_float();
        float chance_of_inclusion = num_req.to_float() / num_avail.to_float();
         if(randval < chance_of_inclusion)
        {
            dest[dest_index]=source_index;
            dest_index += 1;
            num_req -= 1;
        }
        num_avail -= 1;
        source_index += 1;
    }
     return dest;    // still a map instead of an array; hopefully that won't cause any problems
}
        int[int] to_randomize;
 for i from 0 to 169{
	to_randomize[i]=i;
}
 //mt_srand(426695+10);
srand(426695+10);
int[int] randomized = array_rand(to_randomize,4);
 foreach i in randomized{
print(i+": "+(randomized[i]+1));
}
/*we want to see 
123
79
115
133
somewhere here because those are the 4 enchantments on the item corresponding to seed 426695+10.
*/

Comments