原生js实现N皇后问题,带页面展示

回溯算法解决N皇后问题,并渲染为页面展示,代码可以直接复制在本地跑

注意:img图片要自行替换为你本地的图片

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Eight Queens Puzzle(Recursive algorithm) - 八皇后问题(递归算法)</title>
  <style type="text/css">
    body {
      background-color: #ffffc0;
    }

    p {
      text-align: center;
    }

    .container {
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
    }

    .footer {
      display: flex;
      width: 100%;
      flex-direction: column;
      justify-content: start;
      align-items: center;
    }

    table {
      border-width: 8px;
      border-color: #604040;
      border-style: solid;
      background-color: #ffffff;
    }

    td {
      text-align: center;
      vertical-align: middle;
      width: 70px;
      height: 70px;
    }

    tr:nth-child(2n+1) td:nth-child(2n) {
      background-color: #000000;
    }

    tr:nth-child(2n) td:nth-child(2n+1) {
      background-color: #000000;
    }

    img {
      max-width: 100%;
      max-height: 70px;
      display: block;
      margin: auto;
    }

    #seekbtn {
      width: 350px;
      height: 30px;
    }
  </style>
</head>

<body>
  <p>
    Eight Queens Puzzle (Recursive algorithm) - 八皇后问题(递归算法)<br />
    2022.9.12</p>
  <div class="container">
    <table cellpadding="0" cellspacing="0" id='table'></table>
    <div class="footer">
      <p style="color: red;">使用说明:首先输入皇后数量,然后点击生成棋盘,然后不断点击生成解按钮,在棋盘中绘制皇后</p>
      <div style="margin-bottom: 10px;">
        <input type="text" id="input" placeholder="请输入皇后的个数" value="">
        <input type="button" id='confim' value="点击生成棋盘">
      </div>
      <input type="button" id="seekbtn" value="点击开始搜索解..." />
    </div>
  </div>
  </div>
</body>


<script>
  const result = [];
  function Nqueue(n) {
    if (n < 1) return 0;
    record = new Array(n);// record[i] 的值表示第i行,皇后所在的位置
    return process(record, 0, n);
  }

  function process(record, i, n) {
    if (i == n) {
      result.push([...record])
      return 1;
    }
    let res = 0;
    for (let j = 0; j < n; j++) {
      if (isValid(record, i, j)) {
        record[i] = j;
        res += process(record, i + 1, n);
      }
    }
    return res;
  }

  function isValid(record, i, j) {
    // 判断前i-1行每行中,皇后所在的位置,即在哪一列
    for (k = 0; k < i; k++) {
      if (j == record[k] || Math.abs(k - i) == Math.abs(record[k] - j)) {
        return false;
      }
    }
    return true;
  }

  let allCount = 0
  let count = 1;
  const btn = document.getElementById("seekbtn");
  const confimObj = document.getElementById('confim')

  const renderTable = (n) => {
    btn.disabled = false;
    count = 1;
    btn.value = `点击开始搜索解...`;

    let htmlStr = '';
    const trArr = [];
    for (let i = 0; i < n; i++) {
      let tr = `<tr>`;
      for (let j = 0; j < n; j++) {
        tr += `<td id='r${i}c${j}'></td>`
      }
      tr += `</tr>`;
      trArr.push(tr);
    }
    htmlStr += trArr.join('');
    document.getElementById('table').innerHTML = htmlStr;
  }


  const renderQueue = () => {
    // 将所有的td中的内容清空
    const tds = document.getElementsByTagName("TD");
    for (let i = 0; i < tds.length; i++) {
      tds[i].innerHTML = "";
    }
    // 绘制新的图片
    const curRes = result.length > 0 ? result.shift() : [];
    for (let r = 0; r < curRes.length; r++) {
      document.getElementById("r" + r + "c" + curRes[r]).innerHTML = `<img src="f0.png" />`;
    }
    if (allCount > 0) {
      btn.value = ""
      btn.value = `一共${allCount}组解,已经搜索到第${count}组解,点击搜索第${count + 1}组解...`;
      if (count === allCount) {
        btn.disabled = true;
      } else {
        count++;
      }
    } else {
      btn.value = `输入的皇后数量无解,请重置皇后数量`
    }

  }

  confimObj.addEventListener('click', () => {
    const inputObj = document.getElementById('input');
    renderTable(inputObj.value)
    allCount = Nqueue(Number.parseInt(inputObj.value))
  })

  btn.addEventListener('click', renderQueue)
</script>

</html>

在线演示地址:http://bianyinglong.3vkj.net/Nqueue/
参考文档:https://blog.51cto.com/mengliao/536391

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值