class BooleanArray {
constructor(height, width) {
this.height = height;
this.width = width;
this.byteWidth = (width >> 3) + ((width & 0b111) > 0 ? 1 : 0);
this.dataArray = new Uint8Array(height * this.byteWidth);
}
getAt(x, y) {
const xBytes = x >>> 3;
const bitMask = 1 << (x & 0b111);
return !!(this.dataArray[y * this.byteWidth + xBytes] & bitMask)|0
}
setAt(x, y, value) {
const xBytes = x >>> 3;
const xBits = x & 0b111;
const i = y * this.byteWidth + xBytes;
if (value) {
this.dataArray[i] |= 1 << xBits;
} else {
this.dataArray[i] &= ~(1 << xBits);
}
}
randomise() {
const size = 2**16
const chunks = (this.dataArray.length/size);
for (let i = 0; i < chunks; ++i) {
crypto.getRandomValues(this.dataArray.subarray(i*size,(i+1)*size))
}
}
toString() {
let result = "";
for (let y = 0; y < this.height; y++) {
result += "\n";
for (let x = 0; x < this.width; x++) {
result += this.getAt(x, y) ? "1" : "0";
}
}
return result;
}
to2D() {
let result = [];
for (let y = 0; y < this.height; y++) {
result[y] = new Uint8Array(this.width)
for (let x = 0; x < this.width; x++) {
result[y][x] = this.getAt(x, y)
}
}
return result;
}
to1D() {
let result = new Uint8Array(this.height * this.byteWidth)
for (let y = 0; y < this.height; y++) {
for (let x = 0; x < this.width; x++) {
const xBytes = x >>> 3;
const xBits = x & 0b111;
result[ y * this.byteWidth + xBytes] = this.getAt(x, y)
}
}
return result;
}
}