You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Javascript开发不同尺寸幻方报错排查及通用生成校验算法求助

问题原因与修复方案

1. 类型错误问题修复

报错来自两个核心问题:

  • 你的HTML代码中没有定义id="time"、id="select"、id="attempting"的元素,页面加载后定时器直接给不存在的元素设置textContent,直接触发未定义错误
  • 你仅在页面初始化时查询了一次.box元素,后续调用creategrid动态生成的新格子没有同步更新到window.boxes变量中,赋值时也会触发未定义错误
    修复方式:补充缺失的DOM元素,每次生成网格后重新查询.box集合,定时器放在DOM加载完成后再启动。

2. 通用幻方校验函数实现

n阶幻方的固定求和公式为 n * (n² + 1) / 2,不需要为每个尺寸写死校验逻辑,通用校验逻辑如下:

// 入参:扁平的幻方数组,阶数n
function checkMagicSquare(arr, n) {
  const targetSum = n * (n * n + 1) / 2
  // 校验每行
  for (let i = 0; i < n; i++) {
    let rowSum = 0
    for (let j = 0; j < n; j++) {
      rowSum += arr[i * n + j]
    }
    if (rowSum !== targetSum) return false
  }
  // 校验每列
  for (let j = 0; j < n; j++) {
    let colSum = 0
    for (let i = 0; i < n; i++) {
      colSum += arr[i * n + j]
    }
    if (colSum !== targetSum) return false
  }
  // 校验两条对角线
  let diagonal1 = 0, diagonal2 = 0
  for (let i = 0; i < n; i++) {
    diagonal1 += arr[i * n + i]
    diagonal2 += arr[i * n + (n - 1 - i)]
  }
  if (diagonal1 !== targetSum || diagonal2 !== targetSum) return false
  return true
}

3. 多尺寸网格生成修复

你之前用charAt(0)取尺寸,只能适配个位数的阶数,而且没有处理参数类型转换,修改后的网格生成函数:

function creategrid(n) {
  boxparent.innerHTML = ''
  for (let i = 0; i < n; i++) {
    const rows = document.createElement('div');
    rows.className = 'row';
    for (let j = 0; j < n; j++) {
      const boxs = document.createElement('div');
      boxs.className = 'box';
      rows.appendChild(boxs);
    }
    boxparent.appendChild(rows);
  }
  // 生成完重新获取box集合
  window.boxes = document.querySelectorAll(".box")
}

额外优化提示:你现在用随机打乱数组暴力枚举的方式生成幻方,4阶以上的枚举量会暴涨,性能会非常差,建议替换成对应的幻方构造算法:奇数阶用罗伯法,双偶阶用对称交换法,单偶阶用斯特雷奇法,生成效率会提升几个数量级。


优化后完整可运行代码

HTML

<div>尝试次数:<span id="attempting">0</span></div>
<div>耗时:<span id="time">0</span>ms</div>
<div id="boxParent"></div>
<form>
    <label>Choose a Size:</label>
    <select id="select" onchange='change()'>
        <option value="3">3 X 3</option>
        <option value="4">4 X 4</option>
        <option value="5">5 X 5</option>
        <option value="6">6 X 6</option>
        <option value="7">7 X 7</option>
        <option value="8">8 X 8</option>
        <option value="9">9 X 9</option>
    </select>
</form>

CSS

.box {
   border: black 1px solid;
   background: white;
   opacity: 0.7;
   /* 适配大尺寸网格自动缩小格子 */
   width: 40px;
   height: 40px;
   display: inline-flex;
   align-items: center;
   justify-content: center;
}
.row {
   display: block;
   width: 100%;
}

JS

var numsarray = [];
let timeDom = document.getElementById('time')
let selectDom = document.getElementById('select')
let attemptingDom = document.getElementById('attempting')
var attempting = 0;
var output = {};
var attempt = 0;
let boxparent = document.getElementById('boxParent')
let done = false;
var interval = null;

// 初始化生成3阶网格
creategrid(3)
startTimer()
generateMagic(3)

function startTimer() {
  interval = setInterval(function() {
    attemptingDom.textContent = attempt;
    timeDom.textContent = parseFloat(timeDom.textContent)+1
  },1)
}

function createnums (size) {
  const arrays = []
  for( let i=1 ; i <= Math.pow(size,2) ; i++ ) {
    arrays.push(i);
  }
  return arrays;
}

let getnums = (size) => {
  const arrays = createnums(size);
  numsarray = [];
  var len = arrays.length;
  while( len > 0 ) {
    attempt+=1
    var rans = Math.floor(Math.random() * len);
    numsarray.push(arrays[rans]);
    arrays.splice(rans, 1);
    len = len - 1;
  }
  return numsarray;
}

function creategrid(n) {
  boxparent.innerHTML = ''
  for (let i = 0; i < n; i++) {
    const rows = document.createElement('div');
    rows.className = 'row';
    for (let j = 0; j < n; j++) {
      const boxs = document.createElement('div');
      boxs.className = 'box';
      rows.appendChild(boxs);
    }
    boxparent.appendChild(rows);
  }
  window.boxes = document.querySelectorAll(".box")
}

function checkMagicSquare(arr, n) {
  const targetSum = n * (n * n + 1) / 2
  // 校验行
  for (let i = 0; i < n; i++) {
    let rowSum = 0
    for (let j = 0; j < n; j++) {
      rowSum += arr[i * n + j]
    }
    if (rowSum !== targetSum) return false
  }
  // 校验列
  for (let j = 0; j < n; j++) {
    let colSum = 0
    for (let i = 0; i < n; i++) {
      colSum += arr[i * n + j]
    }
    if (colSum !== targetSum) return false
  }
  // 校验对角线
  let d1 = 0, d2 = 0
  for (let i = 0; i < n; i++) {
    d1 += arr[i * n + i]
    d2 += arr[i * n + (n - 1 - i)]
  }
  if (d1 !== targetSum || d2 !== targetSum) return false
  return true
}

function generateMagic(n) {
  done = false
  attempt = 0
  timeDom.textContent = 0
  clearInterval(interval)
  startTimer()
  while(!done) {
    output = getnums(n)
    if(checkMagicSquare(output, n)) {
      clearInterval(interval)
      for (let i = 0; i < output.length; i++) {
        window.boxes[i].textContent = output[i]
      }
      done = true
      break
    }
  }
}

// select切换回调
function change() {
  const size = Number(selectDom.value)
  creategrid(size)
  generateMagic(size)
}

内容的提问来源于stack exchange,提问作者Shawn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 07:45:02