puzzle

by dp0ch

HTML

<canvas id="canvas"></canvas>

JavaScript

function Array2D(width, height) {
	const arr = [];
  
  function coordsToIndex(x, y) {
  	return y * width + x;
  }
  
  function indexToCoords(index) {
    return {
    	x: index % width,
      y: index / width,
    };
  }
  
  function get2D(x, y) {
  	return arr[coordsToIndex(x, y)];
  }
  
  function set2D(x, y) {
  	return (val) => arr[coordsToIndex(x, y)] = val;
  }
  
  function fill2D(val) {
  	for (let y = 0; y < height; y++) {
    	for (let x = 0; x < width; x++) {
      	set2D(x, y)(val);
      }
    }
  }
  
  function forEach2D(f) {
  	for (let x = 0; x < width; x++) {
    	for (let y = 0; y < height; y++) {
      	const val = get2D(x, y);
        f(val, {x, y}, arr);
      }
    }
  }
  
  function map2D(f) {
  	const newArr = new Array2D(width, height);
    for (let x = 0; x < width; x++) {
    	for (let y = 0; y < height; y++) {
      	const val = get2D(x, y);
        const newVal = f(val, {x, y}, arr);
        set2D(x, y)(newVal);
      }
    }
  }
  
  function log() {
  	const data = [];
    for (let y = 0; y < height; y++) {
    	const row = [];
      data.push(row);
    	for (let x = 0; x < width; x++) {
      	row.push(get2D(x, y));
      }
    }
    console.table(data);
  }
  
  Object.defineProperties(arr, {
  	width: {
    	get: () => width,
    },
    height: {
    	get: () => height,
    },
  })
  
  return Object.assign(arr, {
  		coordsToIndex,
      indexToCoords,
      get2D,
      set2D,
      fill2D,
      map2D,
      forEach2D,
      log,
  });
}

const a = Array2D(10, 15);
a.fill2D('❌');
a.set2D(0, 0)(' ');
a.set2D(1, 0)(' ');
a.set2D(2, 0)(' ');
a.set2D(3, 0)(' ');
a.set2D(4, 0)(' ');
a.set2D(5, 0)(' ');
a.set2D(6, 0)(' ');
a.set2D(7, 0)(' ');
a.set2D(8, 0)(' ');
a.set2D(9, 0)(' ');
a.log();