JSFiddle - React, Tailwind, and code Playground
by Sergei Sokolov
HTML
<button>перестрой-ка</button>
<div id="container"></div>
CSS
.box {
width:42px;
height:26px;
padding:16px 0 0;
margin:0;
border:1px solid #CCC;
float: left;
text-align: center;
font-family:Helvetica,Arial,sans-serif;
font-size: 10px;
}
.row {clear: both}
.type0 {background: #AAA}
.type1 {background: #9F0}
.type2 {background: #09F}
.type3 {background: #F09}
JavaScript
// block ids 0..3
// 0 bit: width: 0: 1 sqr, 1: 2 sqr
// 1 bit: height: 0: 1 sqr, 1: 2 sqr
function fill(w, h) {
const M = Array(h).fill(null).map(() => Array(w).fill(0));
let count = 0;
while(count++ < 1000) {
const topRow = M.findIndex(row => !!~row.indexOf(0));
if (-1 === topRow) break;
const row = M[topRow];
// find index and length of longest blank in the row
const max = row.reduce(function(p,c,i,a) {
if (c === 0) {
p.len++;
if (!p.blank) {
p.pos = i;
p.blank = true;
}
} else {
if (p.blank) {
if (p.maxlen < p.len) {
p.maxlen = p.len;
p.maxpos = p.pos;
}
p.len = 0;
p.pos = -1;
p.blank = false;
}
}
return p;
}, {len: 0, pos: -1, maxlen: 0, maxpos: -1, blank: false});
if (max.blank && max.maxlen < max.len) {
max.maxlen = max.len;
max.maxpos = max.pos;
}
let code = 0;
if (max.maxlen > 1) // can fit height 2 ?
code |= Math.random() > 0.5; // bit 0
if (topRow < M.length - 1) // can fit width 2 ?
code |= (Math.random() > 0.5) << 1; // bit 1
// place the block at position max.maxpos
for (let y = 0; y < ((code & 2) ? 2 : 1); y++) {
for (let x = 0; x < ((code & 1) ? 2 : 1); x++) {
M[topRow + y][max.maxpos + x] = '' + code + '_' + count;
}
}
}
return M;
}
function draw(element, M) {
function adddiv(parent, type, text) {
const div = document.createElement('div');
div.classList.add('box', 'type' + type);
div.innerText = text;
parent.appendChild(div);
}
for (let y=0; y<M.length; y++) {
const rowdiv = document.createElement('div');
rowdiv.className = 'row';
const row = M[y];
for (let x=0; x<row.length; x++) {
adddiv(rowdiv, row[x].substr(0,1), row[x].substr(2));
}
element.appendChild(rowdiv);
}
}
const container =...