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

滑块拼图故障:Tile随机交换且无法识别相邻空Tile求助

3x3滑块拼图重构后交换逻辑异常问题

问题描述

我正在开发3x3滑块拼图项目,原本代码可用但存在控制台错误,重构后出现两个关键问题:

  • Tile会随机交换,而非仅与相邻的空Tile交换
  • 点击任意Tile时,控制台均输出错误提示:No adjacent empty tile found for (x,y)

我尝试修改moveTiles和chooseTile函数但未解决问题,附上项目的HTML与JavaScript代码,希望得到技术帮助:

项目代码

HTML

<div class="puzzle-container">
  <div class="tile" data-x="0" data-y="0">1</div>
  <div class="tile" data-x="0" data-y="1">2</div>
  <div class="tile" data-x="0" data-y="2">3</div>
  <div class="tile" data-x="1" data-y="0">4</div>
  <div class="tile" data-x="1" data-y="1">5</div>
  <div class="tile" data-x="1" data-y="2">6</div>
  <div class="tile" data-x="2" data-y="0">7</div>
  <div class="tile" data-x="2" data-y="1">8</div>
  <div class="tile empty" data-x="2" data-y="2"></div>
</div>

JavaScript

let emptyX = 2;
let emptyY = 2;

function chooseTile(e) {
  const tile = e.target;
  moveTiles(tile);
}

function moveTiles(tile) {
  const tileX = tile.dataset.x;
  const tileY = tile.dataset.y;
  
  // 原重构逻辑存在的问题:无相邻判断直接交换
  const emptyTile = document.querySelector('.empty');
  const temp = tile.textContent;
  tile.textContent = emptyTile.textContent;
  emptyTile.textContent = temp;
  
  console.log(`No adjacent empty tile found for (${tileX},${tileY})`);
}

document.querySelectorAll('.tile').forEach(tile => {
  tile.addEventListener('click', chooseTile);
});

问题分析与修复方案

1. 核心问题根源

  • 相邻检测逻辑失效:错误提示说明代码无法正确识别点击Tile与空Tile的相邻关系,大概率是空Tile坐标未实时更新,或相邻判断条件错误
  • 交换逻辑无限制:随机交换是因为代码没有先判断相邻,直接执行了交换操作

2. 具体修复步骤

步骤1:添加相邻判断函数

function isAdjacent(tileX, tileY) {
  // 转换为数字类型,避免字符串比较错误
  tileX = parseInt(tileX);
  tileY = parseInt(tileY);
  // 判断上下左右四个方向的相邻关系
  return (tileX === emptyX && Math.abs(tileY - emptyY) === 1) ||
         (tileY === emptyY && Math.abs(tileX - emptyX) === 1);
}

步骤2:重构moveTiles函数

仅当Tile与空Tile相邻时才执行交换,并实时更新空Tile坐标:

function moveTiles(tile) {
  const tileX = tile.dataset.x;
  const tileY = tile.dataset.y;
  
  if (isAdjacent(tileX, tileY)) {
    // 获取空Tile元素
    const emptyTile = document.querySelector(`[data-x="${emptyX}"][data-y="${emptyY}"]`);
    
    // 交换data属性(用于后续位置判断)
    [tile.dataset.x, emptyTile.dataset.x] = [emptyTile.dataset.x, tile.dataset.x];
    [tile.dataset.y, emptyTile.dataset.y] = [emptyTile.dataset.y, tile.dataset.y];
    
    // 交换显示内容
    [tile.textContent, emptyTile.textContent] = [emptyTile.textContent, tile.textContent];
    
    // 更新空Tile的全局坐标
    emptyX = parseInt(tileX);
    emptyY = parseInt(tileY);
    
    console.clear();
  } else {
    console.log(`No adjacent empty tile found for (${tileX},${tileY})`);
  }
}

步骤3:验证初始化逻辑

确保初始化时emptyX和emptyY与空Tile的data-x、data-y完全一致,避免初始坐标不匹配导致的检测错误。

额外调试建议

  • 在isAdjacent函数中打印tileX、tileY、emptyX、emptyY的值,确认坐标是否正确
  • 检查所有Tile的data-x和data-y属性是否从0开始正确赋值(3x3拼图坐标应为0-2)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 21:37:47