kaktwoos-amd.cl 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. int nextInt(ulong* seed, short bound);
  2. int next(ulong* seed, short bits);
  3. int nextIntUnknown(ulong* seed, short bound);
  4. #define WANTED_CACTUS_HEIGHT 22
  5. kernel void crack(global int *data, global ulong* answer)
  6. {
  7. int id = get_global_id(0);
  8. ulong originalSeed = (((ulong)data[0] * (ulong)data[1] + (ulong)id) << 4) | data[8];
  9. ulong seed = originalSeed;
  10. short position = -1;
  11. short posMap;
  12. short posX, posY, posZ;
  13. short initialPosX, initialPosY, initialPosZ;
  14. uchar top = data[7] + FLOOR_LEVEL;
  15. uchar heightMap[1024];
  16. for (short i = 0; i < 1024; i++) {
  17. heightMap[i] = FLOOR_LEVEL;
  18. }
  19. for (short i = 0; i < 10; i++) {
  20. if (WANTED_CACTUS_HEIGHT - top > 9 * (10 - i) + FLOOR_LEVEL)
  21. return;
  22. initialPosX = next(&seed, 4) + 8;
  23. initialPosZ = next(&seed, 4) + 8;
  24. short terrainHeight = heightMap[initialPosX + initialPosZ * 32] * 2 + 2;
  25. initialPosY = nextIntUnknown(&seed, terrainHeight);
  26. if (initialPosY + 3 <= FLOOR_LEVEL && initialPosY - 3 >= 0) {
  27. seed = (seed * 256682821044977UL + 233843537749372UL) & ((1UL << 48) - 1);
  28. continue;
  29. }
  30. if (initialPosY - 3 > top + 1) {
  31. for (int j = 0; j < 10; j++) {
  32. seed = (seed * 76790647859193UL + 25707281917278UL) & ((1UL << 48) - 1);
  33. nextIntUnknown(&seed, nextInt(&seed, 3) + 1);
  34. }
  35. continue;
  36. }
  37. #pragma unroll (2)
  38. for (short a = 0; a < 10; a++) {
  39. posX = initialPosX + next(&seed, 3) - next(&seed, 3);
  40. posY = initialPosY + next(&seed, 2) - next(&seed, 2);
  41. posZ = initialPosZ + next(&seed, 3) - next(&seed, 3);
  42. posMap = posX + posZ * 32;
  43. if (position == -1 && posY > FLOOR_LEVEL && posY <= FLOOR_LEVEL + data[7] + 1) {
  44. if (posMap == data[3]) {
  45. position = 0;
  46. } else if (posMap == data[4]) {
  47. position = 1;
  48. } else if (posMap == data[5]) {
  49. position = 2;
  50. }
  51. if (position != -1) {
  52. int bit = (int)((originalSeed >> 4) & 1);
  53. if ((data[6] == position) ^ (bit == data[9]))
  54. return;
  55. heightMap[posMap] += data[7];
  56. }
  57. }
  58. if (posY <= heightMap[posMap])
  59. continue;
  60. short offset = 1 + nextIntUnknown(&seed, nextInt(&seed, 3) + 1);
  61. #pragma unroll (4)
  62. for (uchar j = posY; j < posY + offset; j++) {
  63. if (posY < 0 ||
  64. j > heightMap[posMap] + 1 ||
  65. j <= heightMap[posMap + 1 ] ||
  66. j <= heightMap[posMap - 1 ] ||
  67. j <= heightMap[posMap + 32] ||
  68. j <= heightMap[posMap - 32])
  69. continue;
  70. heightMap[posMap]++;
  71. }
  72. top = max(top, heightMap[posMap]);
  73. }
  74. }
  75. if (top - FLOOR_LEVEL >= WANTED_CACTUS_HEIGHT) {
  76. answer[atomic_add(&data[2], 1)] =
  77. ((ulong)top - FLOOR_LEVEL) << 58UL |
  78. (((ulong)data[position + 3]) << 48UL) |
  79. originalSeed;
  80. }
  81. }
  82. int next(ulong* seed, short bits)
  83. {
  84. *seed = (*seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1);
  85. return *seed >> (48 - bits);
  86. }
  87. int nextInt(ulong* seed, short bound)
  88. {
  89. int bits, value;
  90. do {
  91. *seed = (*seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1);
  92. bits = *seed >> 17;
  93. value = bits % bound;
  94. } while(bits - value + (bound - 1) < 0);
  95. return value;
  96. }
  97. int nextIntUnknown(ulong* seed, short bound)
  98. {
  99. if((bound & -bound) == bound) {
  100. *seed = (*seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1);
  101. return (int)((bound * (*seed >> 17)) >> 31);
  102. }
  103. int bits, value;
  104. do {
  105. *seed = (*seed * 0x5DEECE66DL + 0xBL) & ((1L << 48) - 1);
  106. bits = *seed >> 17;
  107. value = bits % bound;
  108. } while(bits - value + (bound - 1) < 0);
  109. return value;
  110. }