Advertisement
yojimbos_law

TCRS enchantment generating algorithm

Jul 3rd, 2019
241
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.75 KB | None | 0 0
  1. /*
  2. int sd;
  3. //this is going to be our sequence of untempered mt_rand() values.
  4. //values 0 through 623 are set by mt_srand(), values after that are generated by mt_reload() in sets of 624.
  5. int[int] s;
  6. int mt_index = 623;
  7. //this will be used to track when we need to call mt_reload().
  8. int random_numbers_left;
  9.  
  10. //this is the MT recursion function, maybe?
  11. int twist(int m, int u,int v){
  12. return ( m ^ ( ( ( u & 2147483648 ) | ( v & 2147483647 ) ) >> 1 ) ^ ( ( 4294967295 * ( u & 1 ) ) & 2567483615 ) ) ;
  13. }
  14.  
  15. //this is the tempering function. God only knows what it does.
  16. int temper(int x){
  17. int s_one;
  18. s_one = s[x];
  19. s_one ^= (s_one >> 11);
  20. s_one ^= (s_one << 7) & 2636928640;
  21. s_one ^= (s_one << 15) & 4022730752;
  22. return ( s_one ^ (s_one >> 18) );
  23. }
  24.  
  25.  
  26. void mt_srand(int seed){
  27. sd = seed;
  28. clear(s);
  29. mt_index = 623;
  30. random_numbers_left = 0;
  31.  
  32. //this is how mt_srand() converts the seed into a 624 word initial condition.
  33. s[0] = sd & 2147483647;
  34.  
  35. for j from 1 to 623{
  36. s[j] = ( ( 1812433253 * ( s[j-1] ^ ( s[j-1] >> 30 ) )) + j ) & 4294967295 ;
  37. }
  38. }
  39.  
  40. void mt_reload(){
  41. //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?
  42. //for i from 0 to 623{
  43. // s[i+624] = twist(s[i+397],s[i],s[i]);
  44. for i from mt_index to (mt_index+623){
  45. s[i+1] = twist(s[i-226],s[i-623],s[i-623]);
  46. }
  47. random_numbers_left+= 624;
  48. }
  49.  
  50. //this is going to actually spit out random numbers in the specified range, allegedly.
  51. int mt_rand(int min, int max){
  52. mt_index++;
  53. if(random_numbers_left == 0){
  54. mt_reload();
  55. }
  56. else{
  57. random_numbers_left--;
  58. }
  59. return (min + ( max - min + 1 ) * (( temper(mt_index) >> 1 ) / ( 2147483647 + 1.0))) ;
  60. }
  61.  
  62.  
  63.  
  64.  
  65. //returns the [position]-th number that mt_rand([low],[high]) would return in PHP 5.3 when seeded with [seed]
  66. int[int] seeded_mt_rand(int seed,int low, int high, int position){
  67.  
  68. int[int] ret;
  69. mt_srand(seed);
  70. for i from 1 to position{
  71. ret[i] = mt_rand(low,high);
  72. }
  73.  
  74. return ret;
  75. }
  76.  
  77. */
  78.  
  79.  
  80.  
  81. //glibc rand()
  82. int next;
  83. int but = 2**31;
  84. int bot = 2**16;
  85. int[int] s;
  86. int place = 0;
  87. void srand(int x){
  88. clear(s);
  89. //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
  90. s[0] = x;
  91. for i from 1 to 30{
  92. s[i] = (s[i-1] * 16807) % (but-1);
  93. }
  94. for i from 31 to 33{
  95. s[i] = s[i-31];
  96. }
  97. for i from 34 to (344){
  98. s[i] = (s[i-3] + s[i-31]) % (2*but);
  99. }
  100. place = 344;
  101. }
  102.  
  103. int rand(int min, int max){
  104. //LCG stuff:
  105. //from IBM and C and POSIX
  106. //next = (1103515245 * next + 12345);
  107. //next %= but;
  108. //next &= but-bot;
  109.  
  110. //from some other C thing
  111. //next = (1103515245 * next + 12345);
  112. //next %= but*2;
  113. //next &= but-bot;
  114.  
  115. //from MS Visual C
  116. //next = (214013 * next + 2531011);
  117. //next %= 2*but;
  118. //next &= but-bot;
  119.  
  120.  
  121. //glibc implementation
  122. s[place+1] = (s[place-2] + s[place-30]) % (2*but);
  123. next = s[place+1] >> 1;
  124. place++;
  125.  
  126. return (min + ( max - min + 1 ) * ( next / ( (but -1) + 1.0))) ;
  127. //return (next);
  128. }
  129.  
  130. int seeded_rand(int seed, int low, int high){
  131. srand(seed);
  132. return rand(low, high);
  133. }
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140.  
  141.  
  142.  
  143.  
  144.  
  145.  
  146. int[int] array_rand(int[int] source, int num_req)
  147. {
  148. int num_avail = source.count();
  149. int dest_index = 0;
  150. int source_index = 0;
  151. int[int] dest; // yes, i know this is a map; didn't see an easy way to dynamically allocate arrays
  152.  
  153. if((num_req == 0)||(num_req > num_avail))
  154. {
  155. abort("Second argument has to be between 1 and the number of elements in the array");
  156. }
  157.  
  158. while(num_req > 0)
  159. {
  160. // the PHP source's version divides by (PHP_RAND_MAX + 1.0), which may or may not be required depending on your RNG
  161. //float randval = mt_rand(0,2147483647).to_float()/(2147483648).to_float();
  162. float randval = rand(0,2147483647).to_float()/(2147483648).to_float();
  163. float chance_of_inclusion = num_req.to_float() / num_avail.to_float();
  164.  
  165. if(randval < chance_of_inclusion)
  166. {
  167. dest[dest_index]=source_index;
  168. dest_index += 1;
  169. num_req -= 1;
  170. }
  171. num_avail -= 1;
  172. source_index += 1;
  173. }
  174.  
  175. return dest; // still a map instead of an array; hopefully that won't cause any problems
  176. }
  177.  
  178.  
  179.  
  180.  
  181.  
  182.  
  183.  
  184.  
  185. int[int] to_randomize;
  186.  
  187. for i from 0 to 169{
  188. to_randomize[i]=i;
  189. }
  190.  
  191. //mt_srand(426695+10);
  192. srand(426695+10);
  193. int[int] randomized = array_rand(to_randomize,4);
  194.  
  195. foreach i in randomized{
  196. print(i+": "+(randomized[i]+1));
  197. }
  198. /*we want to see
  199. 123
  200. 79
  201. 115
  202. 133
  203. somewhere here because those are the 4 enchantments on the item corresponding to seed 426695+10.
  204. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement