Advertisement
Guest User

Untitled

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