You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

基于jQuery Draggable/Droppable实现狐狸鸡燕麦过河游戏需求问询

完善狐狸、鸡、燕麦过河谜题的Web实现

我来帮你搞定这个经典的过河谜题!先梳理下你现有代码里的小问题,再一步步实现完整的拖拽逻辑和规则检测功能。

第一步:修正现有代码的基础问题

你当前的代码里有个明显的选择器错误:$("#pink-circle")应该是$("#pink-square"),因为你的鸡元素ID是pink-square。另外,别忘了引入jQuery和jQuery UI,否则draggable()droppable()这些方法会直接失效。

第二步:设计位置跟踪逻辑

我们需要一个简单的对象来记录每个物品当前所在的侧(左侧初始岸/右侧对岸),这样才能随时检查是否触发违规规则:

// 初始化所有物品都在左侧初始岸
const positions = {
  fox: "left",
  chicken: "left",
  oats: "left"
};

第三步:实现拖拽与位置更新

droppabledrop事件里,我们需要更新对应物品的位置,然后调用规则检测函数:

$("#blue-square").droppable({
  drop: function(event, ui) {
    const itemId = ui.draggable.attr("id");
    // 根据ID判断是哪个物品,切换位置
    switch(itemId) {
      case "red-square":
        positions.fox = positions.fox === "left" ? "right" : "left";
        break;
      case "pink-square":
        positions.chicken = positions.chicken === "left" ? "right" : "left";
        break;
      case "yellow-square":
        positions.oats = positions.oats === "left" ? "right" : "left";
        break;
    }
    // 检查是否违规
    checkRules();
  }
});

第四步:编写规则检测函数

核心逻辑就是检查两侧是否存在狐狸+鸡单独共处,或者鸡+燕麦单独共处的情况:

function checkRules() {
  // 整理两侧的物品列表
  const leftItems = [];
  const rightItems = [];
  Object.entries(positions).forEach(([item, side]) => {
    if (side === "left") leftItems.push(item);
    else rightItems.push(item);
  });

  // 检测违规组合
  const isFoxChickenAlone = (leftItems.includes("fox") && leftItems.includes("chicken") && leftItems.length === 2) ||
                           (rightItems.includes("fox") && rightItems.includes("chicken") && rightItems.length === 2);
  const isChickenOatsAlone = (leftItems.includes("chicken") && leftItems.includes("oats") && leftItems.length === 2) ||
                            (rightItems.includes("chicken") && rightItems.includes("oats") && rightItems.length === 2);

  if (isFoxChickenAlone) {
    alert("警告:狐狸和鸡不能单独待在一起!");
  } else if (isChickenOatsAlone) {
    alert("警告:鸡和燕麦不能单独待在一起!");
  }
}

完整可运行代码示例

这里加上基础CSS让界面更直观,同时补全所有依赖:

<!DOCTYPE html>
<html>
<head>
  <title>Fox-Chicken-Oats Puzzle</title>
  <!-- 引入jQuery和jQuery UI -->
  <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
  <script src="https://code.jquery.com/ui/1.13.2/jquery-ui.min.js"></script>
  <style>
    .square {
      width: 100px;
      height: 100px;
      margin: 10px;
      padding: 10px;
      display: inline-block;
      text-align: center;
      line-height: 100px;
      color: white;
      font-weight: bold;
    }
    #red-square { background-color: red; }
    #pink-square { background-color: pink; color: black; }
    #yellow-square { background-color: goldenrod; }
    #blue-square { 
      background-color: lightblue; 
      width: 200px;
      height: 300px;
      float: right;
      line-height: 300px;
    }
  </style>
</head>
<body>
  <div class="square" id="red-square">Fox</div>
  <div class="square" id="pink-square">Chicken</div>
  <div class="square" id="yellow-square">Oats</div>
  <div id="blue-square">Other Side</div>

  <script type="text/javascript">
    // 初始化位置
    const positions = {
      fox: "left",
      chicken: "left",
      oats: "left"
    };

    // 初始化拖拽,revert: true模拟船往返后物品返回原位置
    $("#red-square, #pink-square, #yellow-square").draggable({ revert: true });

    // 初始化放置区域
    $("#blue-square").droppable({
      accept: "#red-square, #pink-square, #yellow-square",
      drop: function(event, ui) {
        const itemId = ui.draggable.attr("id");
        // 更新物品位置
        switch(itemId) {
          case "red-square":
            positions.fox = positions.fox === "left" ? "right" : "left";
            break;
          case "pink-square":
            positions.chicken = positions.chicken === "left" ? "right" : "left";
            break;
          case "yellow-square":
            positions.oats = positions.oats === "left" ? "right" : "left";
            break;
        }
        // 检查规则
        checkRules();
      }
    });

    // 规则检测函数
    function checkRules() {
      const leftItems = [];
      const rightItems = [];
      Object.entries(positions).forEach(([item, side]) => {
        side === "left" ? leftItems.push(item) : rightItems.push(item);
      });

      // 检测违规组合
      const foxChickenLeft = leftItems.includes("fox") && leftItems.includes("chicken") && leftItems.length === 2;
      const foxChickenRight = rightItems.includes("fox") && rightItems.includes("chicken") && rightItems.length === 2;
      const chickenOatsLeft = leftItems.includes("chicken") && leftItems.includes("oats") && leftItems.length === 2;
      const chickenOatsRight = rightItems.includes("chicken") && rightItems.includes("oats") && rightItems.length === 2;

      if (foxChickenLeft || foxChickenRight) {
        alert("Oh no! The fox will eat the chicken if they're left alone together!");
      } else if (chickenOatsLeft || chickenOatsRight) {
        alert("Oh no! The chicken will eat the oats if they're left alone together!");
      }
    }
  </script>
</body>
</html>

额外优化建议

  • 我给拖拽加了revert: true,这样物品拖拽到对岸后会返回原位置,更贴合“船每次只能运一个物品,然后需要返回”的谜题逻辑。
  • 可以再添加一个胜利检测函数,当三个物品都到达右侧时,弹出胜利提示。

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

火山引擎 最新活动