{
  "schemaVersion": 1,
  "slug": "minecraft-circle-generator",
  "category": "gaming",
  "kind": "implementation",
  "independentValidation": false,
  "implementationHash": "e22390dbe3b45757fa21d0bc0f0827149b9501c434b72f17e27111d0c246f766",
  "provenance": "Generated from the calculation contract used by the published page. Publication is not external validation.",
  "sourceFiles": [
    "data/calculators/minecraft-circle-generator.json",
    "src/engine.js"
  ],
  "runtimeSource": "/sources/engine.txt",
  "runtimeHash": "5c888d8898afbdee36267bb9977829e1e2ac568f6677c8ee87469c139864645c",
  "scope": "The compute function records implemented equations, constants, lookup tables and custom rules. Inputs record defaults and allowed values; outputs record precision and units. Defaults are examples, not recommendations. General background references are not evidence for this specific algorithm.",
  "publishedFormula": {
    "formula": "on(x, y): r − 0.9 ≤ √((x − r)² + (y − r)²) ≤ r + 0.5",
    "vars": [
      [
        "on",
        "block placed"
      ],
      [
        "r",
        "circle radius, (d−1) ÷ 2"
      ],
      [
        "d",
        "odd diameter"
      ],
      [
        "x,y",
        "cell coordinates 0…d−1"
      ]
    ],
    "note": "Generates one flat, symmetric pixel-art disk pattern; it does not calculate a dome or vertical layers."
  },
  "externalEvidence": {
    "reviewedAt": "2026-10-12",
    "sources": [
      {
        "name": "MDN — Integer grid rounding",
        "url": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round"
      }
    ],
    "referenceRole": "definition",
    "implementationHash": "e22390dbe3b45757fa21d0bc0f0827149b9501c434b72f17e27111d0c246f766",
    "basis": "on(x, y): r − 0.9 ≤ √((x − r)² + (y − r)²) ≤ r + 0.5",
    "limitations": "The references explain definitions and methods; any extra preset must be checked against the assumptions on this page."
  },
  "contract": {
    "compute": "const d=Math.max(3,Math.round(diameter)%2===0?Math.round(diameter)+1:Math.round(diameter)),r=(d-1)/2,rows=[];let count=0;for(let y=0;y<d;y++){let row='';for(let x=0;x<d;x++){const dx=x-r,dy=y-r,dist=Math.sqrt(dx*dx+dy*dy),on=fill==='filled'?dist<=r+.5:dist<=r+.5&&dist>=r-.9;row+=on?'#':'.';if(on)count++}rows.push(row)}return{pattern:rows.join('\\n'),width:d,height:d,blocksNeeded:count}",
    "inputs": [
      {
        "name": "diameter",
        "type": "number",
        "default": 15,
        "min": 3,
        "max": 41,
        "step": 2,
        "requiredValue": true
      },
      {
        "name": "fill",
        "type": "select",
        "default": "hollow",
        "options": [
          {
            "value": "hollow"
          },
          {
            "value": "filled"
          }
        ]
      }
    ],
    "outputs": [
      {
        "name": "pattern",
        "precision": 0,
        "unit": "",
        "type": "text",
        "display": "code"
      },
      {
        "name": "width",
        "precision": 0,
        "unit": "",
        "trimTrailingZeros": true
      },
      {
        "name": "height",
        "precision": 0,
        "unit": "",
        "trimTrailingZeros": true
      },
      {
        "name": "blocksNeeded",
        "precision": 0,
        "unit": "",
        "trimTrailingZeros": true
      }
    ],
    "interpret": null
  }
}
