# Spiral Matrix

{% tabs %}
{% tab title="demo" %}
{% embed url="https://codesandbox.io/embed/spiral-matrix-ll143?fontsize=14&hidenavigation=1&theme=dark" %}
spiral matrix
{% endembed %}
{% endtab %}

{% tab title="JS" %}
````javascript
import { matrix, matrixToString } from '../ext/Array.js';
import { Point } from './Point.js';
import { Turtle } from './Turtle.js';

// SpiralMatrix
/**
 * SpiralMatrix
 * ------------
 * a matrix (2D array) filled with integers circulating as a spiral.
   ```
   let m = new SpiralMatrix(4);
   console.log(`${m}`);
   ```
 * ### Methods
 * - matrix.toString()
 */
export class SpiralMatrix {

  // init
  constructor(n) {
    // ⭐️ is-blocked function (passed to this.turtle)
    function isBlockedAt(x, y) {
      if (!(0 <= x && x < n && 0 <= y && y < n)) return true;
      return this.footprint[x][y] > 0; // ⭐️ .bind(this)❗️
    }

    // map matrix size
    this.size = n;

    // n x n matrix (filled with 0)
    this.footprint = matrix(n, n);

    // this.turtle
    this.turtle = new Turtle(
      new Point(0, 0), // position
      new Point(0, 1), // direction
      isBlockedAt.bind(this), // ⭐️ .bind(this)❗️
    );

    // run the turtle
    this._index = 1;
    this._run();
  }

  // mark the map
  _markMap() {
    const { x, y } = this.turtle.position;
    this.footprint[x][y] = this._index;
    this._index += 1;
  }

  // run the turtle
  _run() {
    while (!this.turtle.isInDeadEnd) {
      this._markMap();
      this.turtle.forward();
    }
  }

  // this.toString()
  toString() {
    return matrixToString(this.footprint, '0');
  }
}
````
{% endtab %}

{% tab title="⬆️ 需要" %}
* [point](../../../appendix/custom/class/point "mention")
* [turtle](../../../appendix/custom/class/turtle "mention")
* [matrix-methods](../../val/builtin/arr/matrix-methods "mention") functions
{% endtab %}

{% tab title="💾 程式" %}
* replit - [Spiral Matrix 1.2](https://replit.com/@pegasusroe/SpiralMatrix-12#main.js)
{% endtab %}
{% endtabs %}
