Advertisement
Guest User

Untitled

a guest
Dec 14th, 2019
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.31 KB | None | 0 0
  1. // use node.js
  2. const fs = require("fs");
  3. const zlib = require("zlib");
  4.  
  5. const MapSize = 1024;
  6. const BlockSize = 64;
  7. const BlockBytes = BlockSize * BlockSize * 3;
  8.  
  9. let MapBlocks = Array(20);
  10. for(let z=0; z<20; z++){
  11. MapBlocks[z] = {};
  12. }
  13. function GetBlockIndex(x, y){
  14. return (~~(y / BlockSize) * MapSize) + ~~(x / BlockSize);
  15. }
  16. function GetTileIndex(x, y){
  17. return ((y % BlockSize) * BlockSize) + (x % BlockSize);
  18. }
  19.  
  20. // Reading map data
  21. let FileBuffer = fs.readFileSync("minimap.map");
  22. let FileSignature = FileBuffer.readUInt32LE(0);
  23. if(FileSignature == 0x4D4D544F){
  24. let Start = FileBuffer.readUInt16LE(4);
  25. let Version = FileBuffer.readUInt16LE(6);
  26. let Flags = FileBuffer.readUInt32LE(8);
  27.  
  28. if(Version == 1){
  29. let FilePosition = Start;
  30.  
  31. while(true){
  32. let x = FileBuffer.readUInt16LE(FilePosition + 0);
  33. let y = FileBuffer.readUInt16LE(FilePosition + 2);
  34. let z = FileBuffer.readUInt8(FilePosition + 4);
  35.  
  36. if(x == 65535 && y == 65535 && z == 255){
  37. FilePosition = FilePosition + 5;
  38. break;
  39. }
  40.  
  41. let BlockLength = FileBuffer.readUInt16LE(FilePosition + 5);
  42. let BlockBuffer = FileBuffer.subarray(FilePosition + 7, FilePosition + 7 + BlockLength);
  43. let BlockUncompressedBuffer = zlib.unzipSync(BlockBuffer);
  44. if(BlockUncompressedBuffer.length != BlockBytes){
  45. return;
  46. }
  47.  
  48. let BlockTiles = [];
  49. for(let b=0; b<(BlockSize*BlockSize); b++){
  50. let BlockPosition = b * 3;
  51. let flags = BlockUncompressedBuffer.readUInt8(BlockPosition + 0);
  52. let color = BlockUncompressedBuffer.readUInt8(BlockPosition + 1);
  53. let speed = BlockUncompressedBuffer.readUInt8(BlockPosition + 2);
  54. BlockTiles.push({"flags": flags, "color": color, "speed": speed});
  55. }
  56. MapBlocks[z][GetBlockIndex(x, y)] = BlockTiles;
  57.  
  58. FilePosition = FilePosition + 7 + BlockLength;
  59. }
  60. }
  61. }
  62.  
  63. // Trying to find map matches that are similar to mask from the book:
  64. // I generate vectors of colors within patch separately for 1s in mask and 0s in mask and compare using https://en.wikipedia.org/wiki/Cosine_similarity Probably there are better ways to do this.
  65. let Book_Mask = `00001000
  66. 01011001
  67. 00101100
  68. 01001100
  69. 00011010
  70. 01010101`;
  71. Book_Mask = Book_Mask.replace(/\r?\n|\r/g, "");
  72. Book_Mask = Book_Mask.split("").map(c => parseInt(c));
  73. let Book_Mask_w = 8;
  74. let Book_Mask_h = 6;
  75.  
  76. function GetTileRel(x, y, Block, BlockR, BlockB, BlockRB){
  77. let FromBlock = Block;
  78. if(x >= BlockSize && y >= BlockSize){
  79. FromBlock = BlockRB;
  80. }else if(x >= BlockSize){
  81. FromBlock = BlockR;
  82. }else if(y >= BlockSize){
  83. FromBlock = BlockB;
  84. }
  85. if(FromBlock){
  86. return FromBlock[GetTileIndex(x, y)];
  87. }
  88. return null;
  89. }
  90.  
  91. let MinCosineSimilarity = Infinity;
  92. let MaxCosineSimilarity = -Infinity;
  93. let Candidates = [];
  94.  
  95. for(let z=0; z<16; z++){
  96. console.log("Floor z =", z);
  97.  
  98. for(let i in MapBlocks[z]){
  99. i = parseInt(i);
  100. let Bx = (i % MapSize) * BlockSize;
  101. let By = (~~(i / MapSize)) * BlockSize;
  102.  
  103. let Block = MapBlocks[z][i];
  104. let BlockR = MapBlocks[z][GetBlockIndex(Bx + BlockSize, By)];
  105. let BlockB = MapBlocks[z][GetBlockIndex(Bx, By + BlockSize)];
  106. let BlockRB = MapBlocks[z][GetBlockIndex(Bx + BlockSize, By + BlockSize)];
  107.  
  108. for(let y=0; y<BlockSize; y++){
  109. for(let x=0; x<BlockSize; x++){
  110. let CanCompare = true;
  111. let ColorsMap = [];
  112. for(let my=0; my<Book_Mask_h; my++){
  113. for(let mx=0; mx<Book_Mask_w; mx++){
  114. let Tile = GetTileRel(x + mx, y + my, Block, BlockR, BlockB, BlockRB);
  115. if(Tile){
  116. ColorsMap.push(Tile.color);
  117. }else{
  118. CanCompare = false;
  119. break;
  120. }
  121. }
  122. if(!CanCompare){
  123. break;
  124. }
  125. }
  126. if(CanCompare){
  127. let CountsOne = Array(256).fill(0);
  128. let CountsZero = Array(256).fill(0);
  129. for(let m=0; m<Book_Mask.length; m++){
  130. let k = ColorsMap[m];
  131. if(Book_Mask[m]){
  132. CountsOne[k]++;
  133. }else{
  134. CountsZero[k]++;
  135. }
  136. }
  137.  
  138. let HadamardProduct = 0;
  139. let CountsOneSumSquared = 0;
  140. let CountsZeroSumSquared = 0;
  141. for(let v=0; v<256; v++){
  142. HadamardProduct += CountsOne[v] * CountsZero[v];
  143. CountsOneSumSquared += (CountsOne[v] * CountsOne[v]);
  144. CountsZeroSumSquared += (CountsZero[v] * CountsZero[v]);
  145. }
  146. let CosineSimilarity = HadamardProduct / Math.sqrt(CountsOneSumSquared) / Math.sqrt(CountsZeroSumSquared);
  147. MinCosineSimilarity = Math.min(MinCosineSimilarity, CosineSimilarity);
  148. MaxCosineSimilarity = Math.max(MaxCosineSimilarity, CosineSimilarity);
  149.  
  150. // Calculated from the center of the rectangle
  151. let Delta = ((Bx + x + 3.5) + (By + y + 2.5) + z) - 65175;
  152.  
  153. let IsCandidate = false;
  154. if(CosineSimilarity <= 0.5){
  155. IsCandidate = true;
  156. }
  157. if(CosineSimilarity <= 0.7){
  158. if(Math.abs(Delta) <= 10){
  159. IsCandidate = true;
  160. }
  161. }
  162. if(IsCandidate){
  163. let Candidate = {"x": (Bx + x), "y": (By + y), "z": z, "CosineSimilarity": CosineSimilarity, "Delta": Delta};
  164. Candidates.push(Candidate);
  165. console.log(Candidate);
  166. }
  167. }
  168. }
  169. }
  170. }
  171. }
  172.  
  173.  
  174. console.log("MinCosineSimilarity", MinCosineSimilarity);
  175. console.log("MaxCosineSimilarity", MaxCosineSimilarity);
  176.  
  177. Candidates.sort(function(a, b){
  178. return a.CosineSimilarity - b.CosineSimilarity;
  179. });
  180.  
  181. let Output = JSON.stringify(Candidates);
  182. fs.writeFile("output.txt", Output, "utf8", function(err){
  183. if(err){
  184. console.log(err);
  185. }
  186. });
  187.  
  188.  
  189.  
  190. // Get all map points matching formula from the book:
  191. let MatchingPoints = [];
  192. for(let z=0; z<16; z++){
  193. for(let i in MapBlocks[z]){
  194. i = parseInt(i);
  195. let Bx = (i % MapSize) * BlockSize;
  196. let By = (~~(i / MapSize)) * BlockSize;
  197. for(let y=0; y<BlockSize; y++){
  198. for(let x=0; x<BlockSize; x++){
  199. if((Bx + x + By + y + z) == 65175){
  200. let Block = MapBlocks[z][i];
  201. let Tile = Block[GetTileIndex(Bx + x, By + y)];
  202.  
  203. let color = Tile.color;
  204. let r = ~~(color / 36) % 6 * 51;
  205. let g = ~~(color / 6) % 6 * 51;
  206. let b = color % 6 * 51;
  207. MatchingPoints.push({"x": (Bx + x), "y": (By + y), "z": z, "color": [r, g, b]});
  208. }
  209. }
  210. }
  211. }
  212. }
  213.  
  214. console.log("MatchingPoints", MatchingPoints.length);
  215.  
  216. let OutputPoints = JSON.stringify(MatchingPoints);
  217. fs.writeFile("points.txt", OutputPoints, "utf8", function(err){
  218. if(err){
  219. console.log(err);
  220. }
  221. });
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement