Advertisement
Guest User

Untitled

a guest
Jan 20th, 2017
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. class SandPile {
  2.     constructor(str, width) {
  3.         let height;
  4.         if (typeof str === 'number' && typeof width === 'number') {
  5.             height = str;
  6.             this.height = height;
  7.             this.width = width;
  8.             this.grid = new Array(height).fill(0).map((e, i) => new Array(width).fill(0));
  9.         } else {
  10.             let shouldTopple = false;
  11.  
  12.             /* takes a string like:
  13.             *     0 1 2
  14.             *     3 0 1
  15.             *     2 3 0
  16.             * and converts it into a 2 dimensional array
  17.             */
  18.             this.grid = str.split(/(\r|\n)+/g).map(row => row.trim()).filter(row => row).map(row => {
  19.                 return row.split(/\s+/g).map(num => num.trim()).filter(num => num).map(num => {
  20.                     const value = parseInt(num);
  21.                     if (value > 3) {
  22.                         shouldTopple = true;
  23.                     }
  24.                     return value;
  25.                 });
  26.             });
  27.  
  28.             this.height = this.grid.length;
  29.             this.width = this.grid[0].height;
  30.  
  31.             if (shouldTopple) {
  32.                 this.stablilze();
  33.             }
  34.         }
  35.        
  36.     }
  37.  
  38.     topple() {
  39.         let shouldTopple = false;
  40.         const newGrid = new Array(this.grid.length).fill(0).map((e,i) => new Array(this.grid[i].length).fill(0));
  41.         for (let i = 0; i < this.grid.length; i++) {
  42.             for (let j = 0; j < this.grid[i].length; j++) {
  43.                 if (this.grid[i][j] <= 3) {
  44.                     newGrid[i][j] += this.grid[i][j];
  45.                     if (newGrid[i][j] > 3) {
  46.                         shouldTopple = true;
  47.                     }
  48.                 } else {
  49.                     newGrid[i][j] += this.grid[i][j] - 4;
  50.  
  51.                     if (newGrid[i][j] > 3) {
  52.                         shouldTopple = true;
  53.                     }
  54.  
  55.                     [{x: 0, y: 1}, {x: 0, y: -1}, {y:0, x: 1}, {y: 0, x: -1}].forEach(coords => {
  56.                         let {x: xOffset, y: yOffset} = coords;
  57.                         if (this.grid[i + yOffset] !== undefined && this.grid[i + yOffset][j + xOffset] !== undefined) {
  58.                             newGrid[i + yOffset][j + xOffset] += 1;
  59.                             if (newGrid[i + yOffset][j + xOffset] > 3) {
  60.                                 shouldTopple = true;
  61.                             }
  62.                         }
  63.                     });
  64.                 }
  65.             }
  66.         }
  67.         this.grid = newGrid;
  68.         return shouldTopple;
  69.     }
  70.  
  71.     add(s) {
  72.         if (typeof s === 'string') {
  73.             return this.add(new SandPile(s));
  74.         }
  75.  
  76.         if (!(s instanceof SandPile)) {
  77.             throw new TypeError('Right operand must be a SandPile');
  78.         }
  79.  
  80.         const newSandpile = new SandPile(this.height, this.width);
  81.         if (this.grid.length !== s.grid.length) {
  82.             throw new TypeError('SandPiles must have the same dimensions');
  83.         }
  84.  
  85.         let shouldTopple = false;
  86.         for (let i = 0; i < this.grid.length; i++) {
  87.             if (this.grid[i].length !== s.grid[i].length) {
  88.                 throw new TypeError('SandPiles must have the same dimensions');
  89.             }
  90.             for (let j = 0; j < this.grid[i].length; j++) {
  91.                 const newValue = this.grid[i][j] + s.grid[i][j];
  92.                 newSandpile.grid[i][j] = newValue;
  93.                 if (newValue > 3) {
  94.                     shouldTopple = true;
  95.                 }
  96.             }
  97.         }
  98.  
  99.         if (shouldTopple) {
  100.             this.stablilze();
  101.         }
  102.  
  103.         return newSandpile;
  104.     }
  105.  
  106.     stablilize() {
  107.         while(this.topple()){}
  108.     }
  109.  
  110.     toString() {
  111.         return this.grid.map(row => row.join(' ')).join('\r\n');
  112.     }
  113.  
  114.     render(cellSize) {
  115.         if (typeof cellSize !== 'number') {
  116.             cellSize = 2;
  117.         }
  118.  
  119.         let existingElement = document.getElementById('sandpile');
  120.         let existingStyle = document.getElementById('sandpile-style');
  121.         if (existingElement) {
  122.            document.body.removeChild(existingElement);
  123.         }
  124.         if (existingStyle) {
  125.             document.body.removeChild(existingStyle);
  126.         }
  127.      
  128.        const style = document.createElement('style');
  129.        style.id = 'sandpile-style';
  130.        style.innerHTML = `
  131.           #sandpile {
  132.              width: ${cellSize * this.width}px;
  133.              height: ${cellSize * this.height}px;
  134.           }
  135.           #sandpile .sandpile-row {
  136.               margin: 0;
  137.               padding: 0;
  138.               list-style-type: none;
  139.               width: ${cellSize * this.width}px;
  140.               height: ${cellSize}px;
  141.               float: left;
  142.           }
  143.  
  144.           #sandpile .sandpile-cell {
  145.               width: ${cellSize}px;
  146.               height: ${cellSize}px;
  147.               float: left;
  148.               display: block;
  149.           }
  150.  
  151.           #sandpile .sandpile-cell.val-0 {
  152.               background-color: #fff;
  153.           }
  154.  
  155.           #sandpile .sandpile-cell.val-1 {
  156.               background-color: rgba(0,0,0,.33);
  157.            }
  158.  
  159.           #sandpile .sandpile-cell.val-2 {
  160.               background-color: rgba(0,0,0,.67);
  161.           }
  162.  
  163.           #sandpile .sandpile-cell.val-3 {
  164.               background-color: rgba(0,0,0,1);
  165.            }
  166.         `;
  167.         document.body.appendChild(style);
  168.    
  169.  
  170.         const div = document.createElement('div');
  171.  
  172.         div.id = 'sandpile';
  173.         this.grid.forEach(row => {
  174.             const ul = document.createElement('ul');
  175.             ul.className = 'sandpile-row';
  176.             row.forEach(cell => {
  177.                 const li = document.createElement('li');
  178.                 li.className = 'val-' + cell + ' sandpile-cell';
  179.                 ul.appendChild(li);
  180.             });
  181.             div.appendChild(ul);
  182.         });
  183.         document.body.appendChild(div);
  184.        
  185.     }
  186. }
  187.  const sandpile = new SandPile(201,201);
  188.  sandpile.grid[100][100] = 60000;
  189.  sandpile.stablilize();
  190.  sandpile.render();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement