基于jQuery Draggable/Droppable实现狐狸鸡燕麦过河游戏需求问询
完善狐狸、鸡、燕麦过河谜题的Web实现
我来帮你搞定这个经典的过河谜题!先梳理下你现有代码里的小问题,再一步步实现完整的拖拽逻辑和规则检测功能。
第一步:修正现有代码的基础问题
你当前的代码里有个明显的选择器错误:$("#pink-circle")应该是$("#pink-square"),因为你的鸡元素ID是pink-square。另外,别忘了引入jQuery和jQuery UI,否则draggable()和droppable()这些方法会直接失效。
第二步:设计位置跟踪逻辑
我们需要一个简单的对象来记录每个物品当前所在的侧(左侧初始岸/右侧对岸),这样才能随时检查是否触发违规规则:
// 初始化所有物品都在左侧初始岸 const positions = { fox: "left", chicken: "left", oats: "left" };
第三步:实现拖拽与位置更新
在droppable的drop事件里,我们需要更新对应物品的位置,然后调用规则检测函数:
$("#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




