0

0

生成Double-Choco谜题:高效数据结构与算法实践

聖光之護

聖光之護

发布时间:2025-08-04 20:46:01

|

902人浏览过

|

来源于php中文网

原创

生成Double-Choco谜题:高效数据结构与算法实践

本文深入探讨了如何自动生成Double-Choco谜题,重点介绍了基于2D单元格矩阵的数据结构设计,以及利用递归式连通组件识别(如洪水填充算法)来提取和验证谜题块的算法。我们将详细阐述从棋盘初始化、形状生成与匹配到边界定义和最终验证的完整生成流程,并提供关键代码示例和实现注意事项,旨在为开发者提供一套可行的谜题生成方案。

一、核心数据结构:单元格表示

在double-choco谜题中,棋盘由一个个单元格组成,这些单元格可以是白色或灰色。为了有效地表示棋盘状态和块的边界,我们采用一个2d数组来存储自定义的cell对象。每个cell对象不仅包含其在棋盘上的坐标,还承载了颜色、数字(如果适用)、边界信息以及是否已被分配到某个块的状态。

一个cell对象的核心属性定义如下:

let cell = {
    x: Number,        // 单元格的X坐标
    y: Number,        // 单元格的Y坐标
    color: "white" | "gray", // 单元格的颜色
    number: null | Number,   // 如果有数字提示,表示该颜色区域的单元格数量
    top: true | false,    // 顶部是否有边界线 (true: 有边界, false: 无边界)
    bottom: true | false, // 底部是否有边界线
    left: true | false,   // 左侧是否有边界线
    right: true | false,  // 右侧是否有边界线
    taken: false,     // 是否已被分配到某个完成的谜题块中
    blockId: null     // 所属谜题块的唯一ID,或存储整个块的引用
};

关键属性解析:

  • x, y: 单元格的二维坐标,方便定位。
  • color, number: 用于表示谜题的特定规则,即白/灰区域及其大小提示。
  • top, bottom, left, right: 这四个布尔值是定义谜题块边界的关键。当值为true时,表示该方向存在一条实线,将当前单元格与相邻单元格分隔开;当值为false时,表示该方向没有实线,当前单元格与相邻单元格相连,属于同一个连通区域。
  • taken: 在生成过程中,用于标记已被成功分配到某个合法谜题块的单元格,避免重复处理。
  • blockId: 用于在提取块后,将所有属于同一块的单元格关联起来。

二、块提取算法:基于边界的连通组件识别

在谜题生成过程中,我们需要能够根据已定义的边界线(即cell对象的top/bottom/left/right属性)来识别和提取独立的谜题块。这可以通过一个递归的洪水填充(Flood-Fill)算法来实现。

网趣网上购物系统HTML静态版
网趣网上购物系统HTML静态版

网趣购物系统静态版支持网站一键静态生成,采用动态进度条模式生成静态,生成过程更加清晰明确,商品管理上增加淘宝数据包导入功能,与淘宝数据同步更新!采用领先的AJAX+XML相融技术,速度更快更高效!系统进行了大量的实用性更新,如优化核心算法、增加商品图片批量上传、谷歌地图浏览插入等,静态版独特的生成算法技术使静态生成过程可随意掌控,从而可以大大减轻服务器的负担,结合多种强大的SEO优化方式于一体,使

下载

该算法从一个未被标记的单元格开始,递归地访问所有与其相连(即之间没有边界线)的相邻单元格,直到遇到边界线或已访问过的单元格。所有被访问到的单元格共同构成一个完整的谜题块。

/**
 * 递归地提取一个连通的谜题块。
 * @param {Array>} cells - 整个棋盘的2D单元格数组。
 * @param {cell} currentCell - 当前正在处理的单元格。
 * @param {Array} currentBlock - 用于存储当前块中所有单元格的数组。
 * @param {number} blockId - 当前块的唯一标识符。
 */
function extractBlock(cells, currentCell, currentBlock, blockId) {
    // 边界检查:确保单元格在棋盘范围内
    if (!currentCell || currentCell.taken) {
        return;
    }

    currentCell.taken = true;      // 标记为已访问/已分配
    currentCell.blockId = blockId; // 分配块ID
    currentBlock.push(currentCell); // 将单元格添加到当前块中

    const { x, y } = currentCell;
    const rows = cells.length;
    const cols = cells[0].length;

    // 向上移动:如果顶部没有边界线且上方单元格存在
    if (!currentCell.top && y > 0) {
        extractBlock(cells, cells[y - 1][x], currentBlock, blockId);
    }
    // 向下移动:如果底部没有边界线且下方单元格存在
    if (!currentCell.bottom && y < rows - 1) {
        extractBlock(cells, cells[y + 1][x], currentBlock, blockId);
    }
    // 向左移动:如果左侧没有边界线且左侧单元格存在
    if (!currentCell.left && x > 0) {
        extractBlock(cells, cells[y][x - 1], currentBlock, blockId);
    }
    // 向右移动:如果右侧没有边界线且右侧单元格存在
    if (!currentCell.right && x < cols - 1) {
        extractBlock(cells, cells[y][x + 1], currentBlock, blockId);
    }
}

/**
 * 遍历整个棋盘,提取所有独立的谜题块。
 * @param {Array>} cells - 整个棋盘的2D单元格数组。
 * @returns {Array>} 所有提取出的谜题块的数组。
 */
function findAllBlocks(cells) {
    const allExtractedBlocks = [];
    let nextBlockId = 1;

    for (let y = 0; y < cells.length; y++) {
        for (let x = 0; x < cells[0].length; x++) {
            const currentCell = cells[y][x];
            if (!currentCell.taken) {
                const newBlock = [];
                extractBlock(cells, currentCell, newBlock, nextBlockId++);
                if (newBlock.length > 0) {
                    allExtractedBlocks.push(newBlock);
                }
            }
        }
    }
    return allExtractedBlocks;
}

工作原理:

  1. extractBlock函数是核心的递归函数。它接收当前单元格、一个用于累积当前块单元格的数组以及块ID。

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

48

2025.08.29

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

95

2025.10.23

treenode的用法
treenode的用法

​在计算机编程领域,TreeNode是一种常见的数据结构,通常用于构建树形结构。在不同的编程语言中,TreeNode可能有不同的实现方式和用法,通常用于表示树的节点信息。更多关于treenode相关问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

529

2023.12.01

C++ 高效算法与数据结构
C++ 高效算法与数据结构

本专题讲解 C++ 中常用算法与数据结构的实现与优化,涵盖排序算法(快速排序、归并排序)、查找算法、图算法、动态规划、贪心算法等,并结合实际案例分析如何选择最优算法来提高程序效率。通过深入理解数据结构(链表、树、堆、哈希表等),帮助开发者提升 在复杂应用中的算法设计与性能优化能力。

6

2025.12.22

页面置换算法
页面置换算法

页面置换算法是操作系统中用来决定在内存中哪些页面应该被换出以便为新的页面提供空间的算法。本专题为大家提供页面置换算法的相关文章,大家可以免费体验。

389

2023.08.14

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

7

2025.12.31

php网站源码教程大全
php网站源码教程大全

本专题整合了php网站源码相关教程,阅读专题下面的文章了解更多详细内容。

4

2025.12.31

视频文件格式
视频文件格式

本专题整合了视频文件格式相关内容,阅读专题下面的文章了解更多详细内容。

7

2025.12.31

不受国内限制的浏览器大全
不受国内限制的浏览器大全

想找真正自由、无限制的上网体验?本合集精选2025年最开放、隐私强、访问无阻的浏览器App,涵盖Tor、Brave、Via、X浏览器、Mullvad等高自由度工具。支持自定义搜索引擎、广告拦截、隐身模式及全球网站无障碍访问,部分更具备防追踪、去谷歌化、双内核切换等高级功能。无论日常浏览、隐私保护还是突破地域限制,总有一款适合你!

7

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号