enter image description hereI got an exercise , where i have to create a rectangle-canvas using p5.js , but that canvas will consist small rects ,so i do it , but there is also 1 point in the exrecise . How can i get those small rects in 2 different colors , but 50% of those colores must be green and the other red , using matrix .
Here is the code .
var matrix = [
];
var ab = 36;
for (var y = 0; y < ab; y++) {
matrix.push([])
for (var x = 0; x < 36; x++) {
matrix[y][x] = Math.floor(Math.random() * 2)
}
}
console.log(matrix)
var side = 16;
function setup() {
createCanvas(matrix[0].length * side, matrix.length * side);
background('#acacac');
frameRate()
}
function draw() {
for (var y = 0; y < matrix.length; y++) {
for (var x = 0; x < matrix[y].length; x++) {
if (matrix[y][x] == 0) {
fill(0, 255, 0)
rect(y * side, x * side, side, side)
}
else if (matrix[y][x] == 1) {
fill("red")
rect(y * side, x * side, side, side)
}
function Shuffle (arguments) {
for(var k = 0; k < arguments.length; k++){
var i = arguments[k].length;
if ( i == 0 ) return false;
else{
while ( --i ) {
var j = Math.floor( Math.random() * ( i + 1 ) );
var tempi = arguments[k][i];
var tempj = arguments[k][j];
arguments[k][i] = tempj;
arguments[k][j] = tempi;
}
return arguments;
}
}
}
so as discussed in comments , the problem reduces to filling exactly half the matrix with one color and other half with other.
your matrix is in two dimension i will give a solution in one dimension, which should be quite easy to extend to 2-d
var count = 0;
var arr = [];
for( var i = 0 ;i < ab;i++){
arr[i] = 0;
}
while(true) {
var i = floor(random(ab));
if(arr[i] !==1) {
arr[i] = 1;
count++;
}
if(count === ab/2) break; // assume ab is even
}
there is one more way
fill half the array with 1 and half with 0 and then shuffle the array
you can very easily google algorithms for shuffling,
one pseudocode i could find
// after filling half elements with 1 and half with zero
// To shuffle an array a of n elements (indices 0..n-1):
for i from n - 1 downto 1 do
j = random integer with 0 <= j <= i
exchange a[j] and a[i]
source: https://www.geeksforgeeks.org/shuffle-a-given-array/
There it is my problem
var matrix = [
];
var ab = 36;
for (var y = 0; y < ab; y++) {
matrix.push([])
for(var x = 0 ; x<ab;x++){
matrix[y][x] = Math.floor(Math.random()*1)
}
for(var x = 0 ; x<ab/2;x++){
matrix[y][x] = 1
}
}
var count = 0;
var arr = [];
for( var i = 0 ;i < ab;i++){
arr[i] = 0;
}
while(true) {
var i = Math.floor(Random(ab));
if(arr[i] !==1) {
arr[i] = 1;
count++;
}
if(count === ab/2) break; // assume ab is even
}
console.log(arr)
var side = 16;
function setup() {
createCanvas(arr[0].length * side, arr.length * side);
background('#acacac');
frameRate()
}
function draw() {
for (var y = 0; y < arr.length; y++) {
for (var x = 0; x < arr[y].length; x++) {
if (matrix[y][x] == 0) {
fill(0, 255, 0)
rect(y * side, x * side, side, side)
}
else if (matrix[y][x] == 1) {
fill("red")
rect(y * side, x * side, side, side)
}
else if (matrix[y][x] == 2) {
fill(255, 255, 0)
rect(y * side, x * side, side, side)
}
else if (matrix[y][x] == 3) {
fill(255, 0, 0)
rect(y * side, x * side, side, side)
}
}
}
}
Related
I'm coding Conways game of life in P5JS, but I got a wierd bug. It seems to "work" but it looks all wrong. I'm not sure if it has t do with finding the neighbors, because when I call the function manually, it works. I even copied a second neighbor-counting function of the internet in there, and it works, too.
Maybe it's a visual glitch, but I'm not sure of that either, because the code looks fine.
/// <reference path="../TSDef/p5.global-mode.d.ts" />
let gridSize = 10;
let arrCurrent = create2dArray(gridSize);
let arrNext = create2dArray(gridSize);
function setup() {
createCanvas(800, 800, WEBGL);
background(0);
stroke(0, 255, 0);
noFill();
initGame();
}
function draw() {
displayCells();
calcNextGen();
}
//Returns a 2D Array
function create2dArray(size) {
let newArray = new Array(size);
for (let i = 0; i < newArray.length; i++) {
newArray[i] = new Array(1);
}
return newArray;
}
//Fills initial array with random values
function initGame() {
for (let x = 0; x < arrCurrent.length; x++) {
for (let y = 0; y < arrCurrent.length; y++) {
arrCurrent[x][y] = Math.round((Math.random()));
}
}
}
//Calculates next generation
function calcNextGen() {
for (let x = 0; x < gridSize; x++) {
for (let y = 0; y < gridSize; y++) {
let neighbors = countNeighbors1(arrCurrent, x, y);
let state = arrCurrent[x][y];
//If cell is dead and has exactly 3 neighbors, it starts living
if (state === 0 && neighbors === 3) {
arrNext[x][y] = 1;
}
//If cell lives and has too few or too many neighbors, it dies
else if (state === 1 && (neighbors < 2 || neighbors > 3)) {
arrNext[x][y] = 0;
}
else {
arrNext[x][y] = state;
}
}
}
arrCurrent = arrNext.slice();
}
//Count neighbors
function countNeighbors(x, y) {
return arrCurrent[(x + 1) % gridSize][y] +
arrCurrent[x][(y + 1) % gridSize] +
arrCurrent[(x + gridSize - 1) % gridSize][y] +
arrCurrent[x][(y + gridSize - 1) % gridSize] +
arrCurrent[(x + 1) % gridSize][(y + 1) % gridSize] +
arrCurrent[(x + gridSize - 1) % gridSize][(y + 1) % gridSize] +
arrCurrent[(x + gridSize - 1) % gridSize][(y + gridSize - 1) % gridSize] +
arrCurrent[(x + 1) % gridSize][(y + gridSize - 1) % gridSize];
}
function countNeighbors1(grid, x, y) {
let sum = 0;
for (let i = -1; i < 2; i++) {
for (let j = -1; j < 2; j++) {
let col = (x + i + gridSize) % gridSize;
let row = (y + j + gridSize) % gridSize;
sum += grid[col][row];
}
}
sum -= grid[x][y];
return sum;
}
function displayCells() {
background(0);
translate(-300, -300, 0);
for (let x = 0; x < arrCurrent.length; x++) {
for (let y = 0; y < arrCurrent.length; y++) {
push();
translate(x * 50, y * 50, 0);
if (arrCurrent[x][y] === 1) box(50);
pop();
}
}
}
function logGrid() {
console.log(arrCurrent[0]);
console.log(arrCurrent[1]);
console.log(arrCurrent[2]);
console.log(arrCurrent[3]);
console.log(arrCurrent[4]);
console.log(arrCurrent[5]);
console.log(arrCurrent[6]);
console.log(arrCurrent[7]);
console.log(arrCurrent[8]);
console.log(arrCurrent[9]);
}
I know I'm very close, but I'm banging my head against this one since 2 hours.
Here's a little P5JS Web Editor, you can copy the code over and visually see the problem.
Any help is appreciated - thank you!
arrCurrent = arrNext.slice(); doesn't create a deep copy of the grid, it just creates a shallow copy of the first dimension.
It creates a grid, where columns of arrCurrent refers to the rows of arrNext.
You've to create a completely new grid:
arrCurrent = []
for (let x = 0; x < gridSize; x++)
arrCurrent.push(arrNext[x].slice());
let gridSize = 10;
let arrCurrent = create2dArray(gridSize);
let arrNext = create2dArray(gridSize);
function setup() {
createCanvas(800, 800, WEBGL);
background(0);
stroke(0, 255, 0);
noFill();
initGame();
frameRate(10)
}
function draw() {
displayCells();
calcNextGen();
}
//Returns a 2D Array
function create2dArray(size) {
let newArray = new Array(size);
for (let i = 0; i < newArray.length; i++) {
newArray[i] = new Array(1);
}
return newArray;
}
//Fills initial array with random values
function initGame() {
for (let x = 0; x < arrCurrent.length; x++) {
for (let y = 0; y < arrCurrent.length; y++) {
arrCurrent[x][y] = Math.round((Math.random()));
}
}
}
//Calculates next generation
// - A live cell dies if it has fewer than two live neighbors.
// - A live cell with two or three live neighbors lives on to the next generation.
// - A live cell with more than three live neighbors dies.
// - A dead cell will be brought back to live if it has exactly three live neighbors.
function calcNextGen() {
for (let x = 0; x < gridSize; x++) {
for (let y = 0; y < gridSize; y++) {
let neighbors = countNeighbors1(arrCurrent, x, y);
let state = arrCurrent[x][y];
//If cell is dead and has exactly 3 neighbors, it starts living
if (state === 0 && neighbors === 3) {
arrNext[x][y] = 1;
}
//If cell lives and has too few or too many neighbors, it dies
else if (state === 1 && (neighbors < 2 || neighbors > 3)) {
arrNext[x][y] = 0;
}
else {
arrNext[x][y] = state;
}
}
}
arrCurrent = []
for (let x = 0; x < gridSize; x++)
arrCurrent.push(arrNext[x].slice());
}
function countNeighbors1(grid, x, y) {
let sum = 0;
for (let i = -1; i < 2; i++) {
for (let j = -1; j < 2; j++) {
let col = (x + i + gridSize) % gridSize;
let row = (y + j + gridSize) % gridSize;
sum += grid[col][row];
}
}
sum -= grid[x][y];
return sum;
}
function displayCells() {
background(0);
translate(-75, -75, 0);
stroke(128);
box(50*gridSize, 50*gridSize, 50);
translate(-225, -225, 0);
stroke(0, 255, 0);
for (let x = 0; x < arrCurrent.length; x++) {
for (let y = 0; y < arrCurrent.length; y++) {
push();
translate(x * 50, y * 50, 0);
if (arrCurrent[x][y] === 1) box(50);
pop();
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.9.0/p5.js"></script>
I'm quite new to Javascript, and I've been working on a graphic-based genetic algorithm. However, I think I'm getting some tunnel vision after working on it a while and I can't seem to catch what's going wrong?
I'm using Javascript with p5.js.
Problem described below.
Premise
Create a bunch of red dots with probability-based movement. Fitness determined by how many randomly placed green dots they eat. Evolve to eat more.
Errors
When I run it, a green dot always appears in the upper left even though they should be randomly placed.
(RESOLVED) The breeding function doesn't seem to work properly. It should:
Create an array for the next generation (this works)
Draw random parents from mating pool (this works)
Randomly cross their chromosome arrays to form a new individual (not sure)
Apply mutation chance for each new individual (not sure)
Store offspring in the new generation (this works)
Replace a random offspring with fittest member of last generation (not sure)
Replace current generation array with new generation array (not sure)
Code
var settings = {
populationSize : 25,
geneLength : 8,
mutationProbability : 0.01,
forestSize : 1500,
rows : 124,
cols : 249,
year : 250,
end : 20,
};
function onCanvas(position){
return position*4+2;
}
function randombetween(min, max){
return Math.random()*max;
}
//set up sheep
var population = new Population(settings.populationSize, settings.geneLength);
function Sheep(g, dna){
this.genLen = g;
this.state = 0;
this.fitness=0;
this.xpos = Math.floor(Math.random()*settings.cols);
this.ypos = Math.floor(Math.random()*settings.rows);
this.chromosome = new Array(this.genLen);
if (dna != null){
this.chromosome = dna;
} else{
for(var x=0; x<this.genLen; x+=4){
this.chromosome[x] = Math.random();
this.chromosome[x+1] = randombetween(0, 1-this.chromosome[x]);
this.chromosome[x+2] = randombetween(0, 1-this.chromosome[x]-this.chromosome[x+1]);
this.chromosome[x+3] = 1-this.chromosome[x]-this.chromosome[x+1]-this.chromosome[x+2];
}
}
}
function Population(p, g){
this.popSize = p;
this.sheep = [];
this.matingPool = [];
this.maxFit;
this.maxFitIndex;
for (var x = 0; x < this.popSize; x++) {
this.sheep[x] = new Sheep(g, null);
}
this.evaluate = function() {
//find maximum fitness in generation
this.maxFit = 0;
this.maxFitIndex = 0;
for (var x = 0; x < this.popSize; x++) {
//this.sheep[x].calcFitness();
if (this.sheep[x].fitness > this.maxFit){
this.maxFitIndex = x;
this.maxFit = this.sheep[x].fitness;
}
}
//document.write("Maximum fitness: " + this.maxFit);
//normalize fitness
for (var i = 0; i < this.popSize; i++) {
this.sheep[i].fitness /= this.maxFit;
}
//reset mating pool every generation
this.matingPool = [];
//higher fitness means more representation in the pool
for (var i = 0; i < this.popSize; i++) {
var n = this.sheep[i].fitness *10;
for (var j = 0; j < n; j++) {
this.matingPool.push(this.sheep[i]);
}
}
}
//create children sheep
this.breed = function (){
var newsheep = [];
for (var i = 0; i < this.popSize; i++){
//pick random parents from the mating pool
let parentA = this.matingPool[Math.floor(Math.random()*this.matingPool.length)];
let parentB = this.matingPool[Math.floor(Math.random()*this.matingPool.length)];
//parent genes are randomly crossed
var newchromosome = [];
var midpoint = Math.floor(Math.random()*g);
for (var j = 0; j < g; j++){
if (j > midpoint){
newchromosome[j] = parentA.chromosome[j];
} else{
newchromosome[j] = parentB.chromosome[j];
}
}
//offspring may be mutated
if(Math.random()<=settings.mutationProbability){
newchromosome[Math.floor(Math.random()*g)]=Math.floor(Math.random()*10+1);
}
newsheep[i] = new Eater(g, newchromosome);
}
//elite offspring survive into next generation, replacing a random offspring
var random = Math.floor(Math.random()*this.popSize);
if(Math.random()<=settings.mutationProbability){
this.sheep[this.maxFitIndex].chromosome[Math.floor(Math.random()*g)]=Math.floor(Math.random()*10+1);
}
for(var x = 0; x < g; x++){
newsheep[random].chromosome[x] = this.sheep[this.maxFitIndex].chromosome[x];
}
//update array of sheep
for(var x=0; x<this.popSize; x++){
this.sheep[x] = newsheep[x];
}
}
}
//set up trees
var forest = new Forest(settings.forestSize);
function radialTreePopulation(x,y,r,count){
let trees = [];
for(let i = 0;i < count; i++){
trees.push({
posx : (x + Math.floor((Math.random()* r) * (Math.random() < 0.5 ? -1 : 1))),
posy : (y + Math.floor((Math.random()* r) * (Math.random() < 0.5 ? -1 : 1)))
});
}
return trees;
}
function Forest(f){
this.forSize = f/ 75;
this.trees = [];
for (var x = 0; x < this.forSize ; x++) {
this.trees.push(...radialTreePopulation(
(Math.floor(Math.random()*(settings.cols-20)+10))| 0,
(Math.floor(Math.random()*(settings.rows-20)+10))| 0,
11,
75)
);
}
}
//evaluate how to move
function moveHungry(x, move){
if(move<population.sheep[x].chromosome[0]){
return 0;
}
else if(move-population.sheep[x].chromosome[0]<population.sheep[x].chromosome[1]){
return 1;
}
else if(move-population.sheep[x].chromosome[0]-population.sheep[x].chromosome[1]<population.sheep[x].chromosome[2]){
return 2;
}
else{
return 3;
}
}
function moveEaten(x,move){
if(move<population.sheep[x].chromosome[4]){
return 0;
}
else if(move-population.sheep[x].chromosome[4]<population.sheep[x].chromosome[5]){
return 1;
}
else if(move-population.sheep[x].chromosome[4]-population.sheep[x].chromosome[5]<population.sheep[x].chromosome[6]){
return 2;
}
else{
return 3;
}
}
//count generations and days
var generation=0;
var counter = 0;
//create world
function createWorld(){
background("lightblue");
fill(0,255,0);
for(var x=0; x<settings.forestSize; x++){
rect(onCanvas(forest.trees[x].posx), onCanvas(forest.trees[x].posy), 4, 4);
}
fill(255,0,0);
for(var x=0; x<settings.populationSize; x++){
population.sheep[x].state=0;
rect(onCanvas(population.sheep[x].xpos), onCanvas(population.sheep[x].ypos), 4, 4);
}
//remove eaten trees
for(var x=0; x<settings.populationSize; x++){
for(var y=0; y<settings.forestSize; y++){
if(population.sheep[x].xpos==forest.trees[y].posx && population.sheep[x].ypos==forest.trees[y].posy){
forest.trees[y].posx=null;
forest.trees[y].posy=null;
population.sheep[x].state=1;
population.sheep[x].fitness++;
}
}
}
//move sheep based on chromosome
for(var x=0; x<settings.populationSize; x++){
var move = Math.random();
if(population.sheep[x].state==0){
switch(moveHungry(x, move)){
case 0: //up
if(population.sheep[x].ypos>0)
population.sheep[x].ypos-=1;
break;
case 1: //down
if(population.sheep[x].ypos<settings.rows-1)
population.sheep[x].ypos+=1;
break;
case 2: //right
if(population.sheep[x].xpos<settings.cols-1)
population.sheep[x].xpos+=1;
break;
case 3: //left
if(population.sheep[x].xpos>0)
population.sheep[x].xpos-=1;
}
}
else {
switch(moveEaten(x, move)){
case 0: //up
if(population.sheep[x].ypos>0)
population.sheep[x].ypos-=1;
break;
case 1: //down
if(population.sheep[x].ypos<settings.rows-1)
population.sheep[x].ypos+=1;
break;
case 2: //right
if(population.sheep[x].xpos<settings.cols-1)
population.sheep[x].xpos+=1;
break;
case 3: //left
if(population.sheep[x].xpos>0)
population.sheep[x].xpos-=1;
}
}
}
counter++;
}
function reset(){
counter=0;
//regrow forest
forest = new Forest(settings.forestSize);
//reset locations and fitness values
for(var x=0; x<settings.populationSize; x++){
population.sheep[x].xpos = Math.floor(Math.random()*settings.cols);
population.sheep[x].ypos = Math.floor(Math.random()*settings.rows);
population.sheep[x].fitness=0;
}
}
function setup() {
createCanvas(1000, 500);
}
function draw() {
createWorld();
if(counter>=settings.year){
population.evaluate();
population.breed();
reset();
generation++;
if(generation>=settings.end){
noLoop();
}
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.3/p5.min.js"></script>
I've made a multidimensional array with Array constructor and Array.fill method.
I cannot figure out where the problem is, but this code doesn't work as I want.
function loadChunk(){
for(var x = 0; x< 3; x++){
for(var y= 0; y < 3; y++){
console.log(x+","+y);
console.log((world[x][y]).loaded);
if(!(world[x][y]).loaded){
world[x][y].loaded=true;
}
}
}
}
function createWorld(w, d){
var worldz = new Array(d * 2 + 1);
var world = new Array(w * 2 + 1);
world.fill(worldz);
for(var x = 0; x< w * 2+ 1; x++){
for(var z = 0; z < d * 2 + 1; z++){
world[x][z]= { loaded: false };
}
}
return world;
}
var world = createWorld(1, 1);
Start();
function Start(){
loadChunk();
}
You can see what is happening with console.
With my view, no true should be written on console.
The problem is, if I edit world[0][n],then world[1 or more][n] changes too.
Replace your createWorld function with this:
function createWorld(w, d){
var world = new Array(w * 2 + 1);
for(var x = 0; x< w * 2+ 1; x++){
// each item of the array requires a new instance
// you should not use fill method in this situation
world[x]=new Array(d * 2 + 1);
for(var z = 0; z < d * 2 + 1; z++){
world[x][z]= { loaded: false };
}
}
return world;
}
function loadChunk() {
for (var x = 0; x < 3; x++) {
for (var y = 0; y < 3; y++) {
console.log(x + "," + y, (world[x][y]).loaded);
if (!(world[x][y]).loaded) {
world[x][y].loaded = true;
}
}
}
}
function createWorld(w, d) {
var world = [];
for (var x = 0; x < w * 2 + 1; x++) {
world[x] = [];
for (var z = 0; z < d * 2 + 1; z++) {
world[x][z] = {loaded: false};
}
}
return world;
}
var world = createWorld(1, 1);
Start();
function Start() {
loadChunk();
}
The problem that you expirience is that you fill "rows" of world with the same array, so world[0] === world[1] && world[1] === world[2] because array variable worldz is holding a reference
The best way to learn your problem is doing next thing:
function createWorld(w, d){
var worldz = new Array(d * 2 + 1);
var world = new Array(w * 2 + 1);
world.fill(worldz);
for(var x = 0; x< w * 2+ 1; x++){
for(var z = 0; z < d * 2 + 1; z++){
world[x][z]= { loaded: false };
debugger;
}
}
return world;
}
And inspecting in chrome debugger what happens with world variable on a first step
The reason why a change of world[0][0] also changes world[1][0] and world[2][0] (same for other indecees of worldz) is that world.fill(worldz) makes all elements of world the same identical object (Array) worldz.
To avoid this every element of world should be a new Array like eg:
for(n=0,max=world.length;n<max;n++) {world[n] = new Array(d * 2 + 1);}
I'm experiencing a bug in my code that doubles the display and ends up drawing it twice, besides itself in a weird resolution. After changing a global variable (total_sand) to a different integer, and changing it back, the display has actually tripled.
The intended result is for it to display just once in full resolution (in this case, 301x301 pixels). This bug didn't happen immediately and seemed to happen randomly upon changing the code one day.
total_sand = 100000;
sandpiles = [];
var next_sandpiles;
function setup() {
createCanvas(301, 301);
for (var x = 0; x < width; x++) {
sandpiles[x] = [];
for (var y = 0; y < height; y++) {
sandpiles[x][y] = 0;
}
}
next_sandpiles = sandpiles;
//STARTING CONDITIONS
if (width % 2 == 0) {
sandpiles[width/2][height/2] = total_sand;
} else {
sandpiles[(width-1)/2][(height-1)/2] = total_sand;
}
}
function topple() {
for (var x = 0; x < width; x++) {
for (var y = 0; y < height; y++) {
if (sandpiles[x][y] > 3) {
toppling = true;
next_sandpiles[x][y] = next_sandpiles[x][y] - 4;
if (x > 0) {
next_sandpiles[x-1][y]++;
}
if (x < width - 1) {
next_sandpiles[x+1][y]++;
}
if (y > 0) {
next_sandpiles[x][y-1]++;
}
if (y < height - 1) {
next_sandpiles[x][y+1]++;
}
}
}
}
sandpiles = next_sandpiles;
}
function update() {
loadPixels();
var r;
var g;
var b;
for (var x = 0; x < width; x++) {
for (var y = 0; y < height; y++) {
if (sandpiles[x][y] == int(0)) {
r = 255;
g = 255;
b = 0;
} else if(sandpiles[x][y] == 1) {
r = 0;
g = 185;
b = 63;
} else if(sandpiles[x][y] == 2) {
r = 0;
g = 104;
b = 255;
} else if(sandpiles[x][y] == 3) {
r = 122;
g = 0;
b = 229;
} else {
r = 255;
g = 0;
b = 0;
}
var index = (x + y * width)*4;
pixels[index] = r;
pixels[index+1] = g;
pixels[index+2] = b;
pixels[index+3] = 255; // alpha
}
}
updatePixels();
}
function draw() {
background(0);
topple();
update();
}
I have an array (2d matrix of ones and zeros) like below and like to change it's size and so I've developed a function you can also find below.
'011111' '001111111111'
'000000' '001111111111'
'000011' ---> '000000000000'
'000001' '000000001111'
'000000001111'
'000000000011'
'011111' '001111111111'
'000000' '001111111111'
'000011' <--- '000000000000'
'000001' '000000001111'
'000000001111'
'000000000011'
So the example task above is working fine with the code below. But scaling down a big matrix (2000*1000) to (40*20) takes a LONG time. Also in the other direction (40*20) to (2000*1000)
So does anybody has an idea how to edit my code to make it working way faster?
So I would be very thankful if somebody shares some working code matching my problem, however.. Thanks a million in advance,
Nina.
var matrix=[
'011111000000000000000000001111000000000000000000000000000000000000000011111110000000000000001011',
'001111000000000000000000011110000000000000000011111000000000000000000001111111000000000000011101',
'001111100000000000000000111110000000000000111111111111100000000000000000011111100000000000010100',
'011111000000000000000000111100000000000111111111111111111000000000000000000111110000000000111000',
'000000000000000000000001111100000000001111111111111111111110000000000000000001100000000000111000',
'000000000000000000000001111000000000111111111111111111111111000000000000000000000000000001110000',
'000000000000000000000011110000000001111111111111111111111111100000000000000000000000000001110000',
'000000000000000000000111110000000011111111111111111111111111111000000000000000000000000011100000',
'000000000000000000000111100000000111111111111111111111111111111000000000000000000000000111000000',
'000000000000000000001111100000001111111111111111111111111111111100000000000000000000000111000001',
'000000000000000000011111000000011111111111111111111111111111111110000000000000000000001110000001',
'000000000000000000011110000000011111111111111111111111111111111111000000000000000000001110000000',
'000000000000000000111110000000111111111111111111111111111111111111110000000000000000000111000000',
'000000000000000000111100000001111111111111111111111111111111111111100000000000000000011000000001',
'000000000000000001111100000001111111111111111111111111111111111111111000000000000000001110000000',
'000000000000000011111000000001111111111111111111111111111111111111111000000000000000011100000000',
'000000000000000011111000000011111111111111111111111111111111111111111110000000000000001111000001',
'000000000000000111110000000011111111111111111111111111111111111111111110000000000000011100000001',
'000000000000001111100000000011111111111111111111111111111111111111111100000000000001110000000001',
'000000000000001111100000000011111111111111111111111111111111111111111110000000000000011100000001',
'000000000000011111000000000111111111111111111111111111111111111111111110000000000001110000000001',
'000000000000011111000000000111111111111111111111111111111111111111111110000000000111000000000001',
'000000000000111110000000000111111111111111111111111111111111111111111110000000000011000000000001',
'000000000000111100000000000111111111111111111111111111111111111111111110000000000011000000000001',
'000000000000111100000000000111111111111111111111111111111111111111111110000000111000000000000001',
'000000000001111000000000000111111111111111111111111111111111111111111110000000010100000000000001',
'000000000001111000000000000111111111111111111111111111111111111111111100011100000000000000000001',
'000000000111110000000000000111111111111111111111111111111111111111111000001111000000000000000001',
'000000000111100000000000000011111111111111111111111111111111111111111000000011100000000000000001',
'000000000111100000000000000011111111111111111111111111111111111111110000001111000000000000000001',
'000000000111100000000000000011111111111111111111111111111111111111100000000111000000000000000001',
'000000101111110000000000000001111111111111111111111111111111111111100000000110000000000000000001',
'000000001111111000000000000001111111111111111111111111111111111111000000111000000000000000000001',
'000000000111111110000000000000111111111111111111111111111111111110000000011110000000000000000001',
'000000000011111111100000000000111111111111111111111111111111111100000000011100000000000000000001',
'000000000001111111110000000000011111111111111111111111111111111100000000111000000000000000000001',
'000000000000011111111000000000001111111111111111111111111111111000000001111000000000000000000001',
'000000000000001111111100000000001111111111111111111111111111110000000001110000000000000000000001',
'000000000000000011111111000000000011111111111111111111111111100000000001110000000000000000000001',
'000000000000000001111111110000000001111111111111111111111111000000000010000000000000000000000001',
'000000000000000000111111111000000000111111111111111111111100000000000111100000000000000000000001',
'000000000000000000001111111110000000001111111111111111111000000000000111000000000000000000000001',
'000000000000000000000011111111100000000011111111111111000000000000001111000000000000000000000001',
'000000000000000000000001111111111000000000001111111000000000000000001110000000000000000000000001',
'000000000000000000000000011110111100000000000000000000000000000000011100000000000000000000000001'
]
Array.prototype.scale_matrix = function(scale_factor) {
var matrix = this;
var scale = 1 / scale_factor;
var array = duplicate_matrix(Math.round(this.length * scale_factor), Math.round(this[0].length * scale_factor), '0').map(str => Array.from(str, String))
if (scale_factor < 1) {
for (var y = 0; y < array.length; y++) {
for (var x = 0; x < array[0].length; x++) {
_y = Math.round(y / scale_factor);
_x = Math.round(x / scale_factor);
var old_values = []
for (var oldx = _x; oldx < _x + scale; oldx++) {
for (var oldy = _y; oldy < _y + scale; oldy++) {
try {
old_values.push(matrix[oldy][oldx]);
}
catch (e) {}
}
}
var new_value = old_values.sort((a, b) => old_values.filter(v => v === a).length - old_values.filter(v => v === b).length).pop();
array[y][x] = matrix[_y][_x];
}
}
}
else {
for (var y = 0; y < matrix.length; y++) {
for (var x = 0; x < matrix[0].length; x++) {
_y = Math.round(y * scale_factor);
_x = Math.round(x * scale_factor);
for (var newx = _x; newx < _x + scale_factor; newx++) {
for (var newy = _y; newy < _y + scale_factor; newy++) {
try {
array[newy][newx] = matrix[y][x];
}
catch (e) {}
}
}
}
}
}
return array.map(a => [a.join('')]).concat.apply([], array.map(a => [a.join('')]));
}
function duplicate_matrix(rows, cols, value) {
var arr = [];
for (var i = 0; i < rows; i++) {
arr.push([]);
arr[i].push(new Array(cols));
for (var j = 0; j < cols; j++) arr[i][j] = value;
};
return arr;
}
console.log(matrix.scale_matrix(0.3).join('\n'));
console.log('\n\n>------<\n\n');
console.log(matrix.scale_matrix(1.3).join('\n'));
.as-console-wrapper { max-height: 100% !important; top: 0; }