Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class SandPile {
- constructor(str, width) {
- if (typeof str === 'number' && typeof width === 'number') {
- this.height = str;
- this.width = width;
- this.grid = new Array(height).fill(0).map((e, i) => new Array(width).fill(0));
- } else {
- let shouldTopple = false;
- /* takes a string like:
- * 0 1 2
- * 3 0 1
- * 2 3 0
- * and converts it into a 2 dimensional array
- */
- this.grid = str.split(/(\r|\n)+/g).map(row => row.trim()).filter(row => row).map(row => {
- return row.split(/\s+/g).map(num => num.trim()).filter(num => num).map(num => {
- const value = parseInt(num);
- if (value > 3) {
- shouldTopple = true;
- }
- return value;
- });
- });
- this.height = this.grid.length;
- this.width = this.grid[0].length;
- if (shouldTopple) {
- this.stablilze();
- }
- }
- }
- topple() {
- let shouldTopple = false;
- const newGrid = new Array(this.grid.length).fill(0).map((e,i) => new Array(this.grid[i].length).fill(0));
- for (let i = 0; i < this.grid.length; i++) {
- for (let j = 0; j < this.grid[i].length; j++) {
- if (this.grid[i][j] <= 3) {
- newGrid[i][j] += this.grid[i][j];
- if (newGrid[i][j] > 3) {
- shouldTopple = true;
- }
- } else {
- newGrid[i][j] += this.grid[i][j] - 4;
- if (newGrid[i][j] > 3) {
- shouldTopple = true;
- }
- [{x: 0, y: 1}, {x: 0, y: -1}, {y:0, x: 1}, {y: 0, x: -1}].forEach(coords => {
- let {x: xOffset, y: yOffset} = coords;
- if (this.grid[i + yOffset] !== undefined && this.grid[i + yOffset][j + xOffset] !== undefined) {
- newGrid[i + yOffset][j + xOffset] += 1;
- if (newGrid[i + yOffset][j + xOffset] > 3) {
- shouldTopple = true;
- }
- }
- });
- }
- }
- }
- this.grid = newGrid;
- return shouldTopple;
- }
- add(s) {
- if (typeof s === 'string') {
- return this.add(new SandPile(s));
- }
- if (!(s instanceof SandPile)) {
- throw new TypeError('Right operand must be a SandPile');
- }
- const newSandpile = new SandPile(this.height, this.width);
- if (this.grid.length !== s.grid.length) {
- throw new TypeError('SandPiles must have the same dimensions');
- }
- let shouldTopple = false;
- for (let i = 0; i < this.grid.length; i++) {
- if (this.grid[i].length !== s.grid[i].length) {
- throw new TypeError('SandPiles must have the same dimensions');
- }
- for (let j = 0; j < this.grid[i].length; j++) {
- const newValue = this.grid[i][j] + s.grid[i][j];
- newSandpile.grid[i][j] = newValue;
- if (newValue > 3) {
- shouldTopple = true;
- }
- }
- }
- if (shouldTopple) {
- this.stablilze();
- }
- return newSandpile;
- }
- stablilize() {
- while(this.topple()){}
- }
- toString() {
- return this.grid.map(row => row.join(' ')).join('\r\n');
- }
- render(cellSize) {
- if (typeof cellSize !== 'number') {
- cellSize = 2;
- }
- let existingElement = document.getElementById('sandpile');
- let existingStyle = document.getElementById('sandpile-style');
- if (existingElement) {
- document.body.removeChild(existingElement);
- }
- if (existingStyle) {
- document.body.removeChild(existingStyle);
- }
- const style = document.createElement('style');
- style.id = 'sandpile-style';
- style.innerHTML = `
- #sandpile {
- width: ${cellSize * this.width}px;
- height: ${cellSize * this.height}px;
- }
- #sandpile .sandpile-row {
- margin: 0;
- padding: 0;
- list-style-type: none;
- width: ${cellSize * this.width}px;
- height: ${cellSize}px;
- float: left;
- }
- #sandpile .sandpile-cell {
- width: ${cellSize}px;
- height: ${cellSize}px;
- float: left;
- display: block;
- }
- #sandpile .sandpile-cell.val-0 {
- background-color: #fff;
- }
- #sandpile .sandpile-cell.val-1 {
- background-color: rgba(0,0,0,.33);
- }
- #sandpile .sandpile-cell.val-2 {
- background-color: rgba(0,0,0,.67);
- }
- #sandpile .sandpile-cell.val-3 {
- background-color: rgba(0,0,0,1);
- }
- `;
- document.body.appendChild(style);
- const div = document.createElement('div');
- div.id = 'sandpile';
- this.grid.forEach(row => {
- const ul = document.createElement('ul');
- ul.className = 'sandpile-row';
- row.forEach(cell => {
- const li = document.createElement('li');
- li.className = 'val-' + cell + ' sandpile-cell';
- ul.appendChild(li);
- });
- div.appendChild(ul);
- });
- document.body.appendChild(div);
- }
- }
- const sandpile = new SandPile(201,201);
- sandpile.grid[100][100] = 60000;
- sandpile.stablilize();
- sandpile.render();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement