{"id":802,"date":"2025-12-09T04:36:20","date_gmt":"2025-12-09T04:36:20","guid":{"rendered":"https:\/\/learndeeplytw.com\/?p=802"},"modified":"2025-12-29T03:28:18","modified_gmt":"2025-12-29T03:28:18","slug":"routing-and-deadlock","status":"publish","type":"post","link":"https:\/\/learndeeplytw.com\/en\/routing-and-deadlock\/","title":{"rendered":"Who Stuck My Orange? Solving Network Traffic Jams with the \"Fruit Passing Game\""},"content":{"rendered":"\n<figure class=\"wp-embed-aspect-4-3 wp-has-aspect-ratio wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube\"><div class=\"wp-block-embed__wrapper\">\n<iframe title=\"The Orange Game\" width=\"1290\" height=\"968\" src=\"https:\/\/www.youtube.com\/embed\/WforXEBMm5k?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<p class=\"\">\u4f60\u6709\u6c92\u6709\u9047\u904e\u73a9\u904a\u6232\u73a9\u5230\u4e00\u534a\uff0c\u756b\u9762\u7a81\u7136\u5361\u4f4f\u4e0d\u52d5\uff1f\u6216\u8005\u662f\u7238\u7238\u958b\u8eca\u6642\uff0c\u5728\u5c0f\u5df7\u5b50\u88e1\u8ddf\u5225\u4eba\u7684\u8eca\u5b50\u300c\u5927\u773c\u77aa\u5c0f\u773c\u300d\uff0c\u8ab0\u4e5f\u904e\u4e0d\u53bb\uff1f\u9019\u5728\u96fb\u8166\u79d1\u5b78\u88e1\u53eb\u505a\u300c\u6b7b\u7d50 (Deadlock)\u300d\u3002<\/p>\n\n\n\n<p class=\"\">\u7db2\u8def\u4e16\u754c\u5c31\u50cf\u99ac\u8def\uff0c\u8cc7\u6599\uff08\u5c01\u5305\uff09\u5c31\u50cf\u8eca\u5b50\u3002\u5982\u679c\u6c92\u6709\u826f\u597d\u7684\u4ea4\u901a\u898f\u5247\uff0c\u6216\u8005\u5927\u5bb6\u90fd\u592a\u81ea\u79c1\uff08\u53ea\u9032\u4e0d\u51fa\uff09\uff0c\u7db2\u8def\u5c31\u6703\u5d29\u6f70\u3002<\/p>\n\n\n\n<p class=\"\">\u4eca\u5929\u6211\u5011\u8981\u628a\u5bb6\u88e1\u8b8a\u6210\u4e00\u500b\u5c0f\u578b\u7db2\u8def\uff0c\u7528\u5e7e\u9846\u300c\u6a58\u5b50\uff08\u6216\u7403\uff09\u300d\uff0c\u4f86\u4e00\u5834\u8003\u9a57\u5168\u5bb6\u4eba\u9ed8\u5951\u7684\u89e3\u8b0e\u904a\u6232\uff01<\/p>\n\n\n\n<p class=\"\">\u5728\u96fb\u8166\u7db2\u8def\u4e2d\uff0c\u5982\u679c\u6bcf\u500b\u7a0b\u5f0f\u90fd\u53ea\u9867\u81ea\u5df1\uff08\u8caa\u5a6a\uff09\uff0c\u6574\u500b\u7db2\u8def\u5c31\u6703\u7671\u7613\u3002\u6211\u5011\u8981\u900f\u904e\u9019\u500b\u300c\u50b3\u6c34\u679c\u300d\u7684\u904a\u6232\uff0c\u8b93\u5b69\u5b50\u89aa\u8eab\u9ad4\u9a57\u4ec0\u9ebc\u53eb\u300c\u5927\u585e\u8eca\uff08\u6b7b\u7d50\uff09\u300d\uff0c\u4ee5\u53ca\u5982\u4f55\u900f\u904e\u5408\u4f5c\u8b93\u7db2\u8def\u91cd\u65b0\u6d41\u52d5\u3002<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">\u7b2c\u4e00\u968e\u6bb5\uff1a<strong>\u81ea\u79c1\u7684\u4ee3\u50f9<\/strong><\/h4>\n\n\n\n<p class=\"\">\u9996\u5148\uff0c\u6211\u5011\u8981\u88fd\u9020\u4e00\u500b\u300c\u52d5\u5f48\u4e0d\u5f97\u300d\u7684\u72c0\u6cc1\uff0c\u8b93\u5b69\u5b50\u7406\u89e3\u70ba\u4ec0\u9ebc\u96fb\u8166\u6703\u7576\u6a5f\u3002<\/p>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\">\n<li class=\"\"><strong>\u4efb\u52d9\u8a2d\u5b9a\uff1a<\/strong>\n<ul class=\"wp-block-list\">\n<li class=\"\">\u627e 5 \u500b\u4eba\uff08\u6216\u7528\u73a9\u5076\u4f54\u4f4d\uff09\uff0c\u570d\u6210\u4e00\u500b\u5713\u5708\u5750\u4e0b\u3002<\/li>\n\n\n\n<li class=\"\">\u6bcf\u500b\u4eba\u8eab\u4e0a\u8cbc\u4e00\u5f35\u6a19\u7c64\uff08A\u3001B\u3001C\u3001D\u3001E\uff09\u3002<\/li>\n\n\n\n<li class=\"\">\u9053\u5177\u5206\u914d\uff1a \u6e96\u5099 5 \u5c0d\u6c34\u679c\uff08\u4f8b\u5982\u5169\u9846\u8cbc A\u3001\u5169\u9846\u8cbc B&#8230;\uff09\u3002\u628a\u9019\u4e9b\u6c34\u679c\u6253\u4e82\u5206\u7d66\u5927\u5bb6\u3002<\/li>\n\n\n\n<li class=\"\">\u95dc\u9375\u9650\u5236\uff1a \u6bcf\u500b\u4eba\u624b\u4e0a\u6709\u5169\u9846\u6c34\u679c\uff0c\u53ea\u6709\u5176\u4e2d\u4e00\u500b\u4eba\u624b\u4e0a\u53ea\u6709\u4e00\u9846\uff08\u7559\u4e00\u96bb\u7a7a\u624b\uff09\u3002<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li class=\"\"><strong>\u898f\u5247\u89e3\u8aaa\uff1a<\/strong>\n<ul class=\"wp-block-list\">\n<li class=\"\">\u76ee\u6a19\uff1a\u4f60\u8eab\u4e0a\u7684\u6a19\u7c64\u662f A\uff0c\u4f60\u6700\u5f8c\u624b\u4e0a\u5c31\u8981\u62ff\u5230\u5169\u9846 A \u6c34\u679c\u3002<\/li>\n\n\n\n<li class=\"\">\u79fb\u52d5\u898f\u5247\uff1a \u4f60\u53ea\u80fd\u628a\u6c34\u679c\u50b3\u7d66\u5de6\u53f3\u9130\u5c45\uff0c\u800c\u4e14\u53ea\u6709\u7576\u9130\u5c45\u6709\u4e00\u96bb\u624b\u662f\u7a7a\u7684\u6642\u5019\uff0c\u4f60\u624d\u80fd\u50b3\u7d66\u4ed6\uff08\u56e0\u70ba\u4e00\u96bb\u624b\u53ea\u80fd\u62ff\u4e00\u9846\uff09\u3002<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li class=\"\"><strong>\u88fd\u9020\u6b7b\u7d50 (Deadlock)\uff1a<\/strong>\n<ul class=\"wp-block-list\">\n<li class=\"\">\u544a\u8a34\u5b69\u5b50\uff1a\u300c\u73fe\u5728\uff0c\u53ea\u8981\u4f60\u62ff\u5230\u5c6c\u65bc\u4f60\u7684\u6c34\u679c\uff08\u4f8b\u5982 A \u62ff\u5230 A\uff09\uff0c\u5c31<strong>\u7dca\u7dca\u6293\u8457\u4e0d\u8981\u653e<\/strong>\uff0c\u7d55\u5c0d\u4e0d\u8981\u50b3\u7d66\u5225\u4eba\uff01\u300d<\/li>\n\n\n\n<li class=\"\">\u7d50\u679c\uff1a \u904a\u6232\u958b\u59cb\u6c92\u591a\u4e45\uff0c\u5927\u5bb6\u5c31\u6703\u5361\u4f4f\u3002\u56e0\u70ba\u6bcf\u500b\u4eba\u90fd\u6293\u8457\u81ea\u5df1\u7684\u6c34\u679c\u4e0d\u653e\uff0c\u6c92\u4eba\u9858\u610f\u9a30\u51fa\u624b\u4f86\u5e6b\u5fd9\u50b3\u905e\u5225\u4eba\u7684\u6c34\u679c\u3002\u90a3\u96bb\u300c\u7a7a\u624b\u300d\u6d88\u5931\u4e86\uff0c\u5927\u5bb6\u90fd\u52d5\u4e0d\u4e86\u3002<\/li>\n\n\n\n<li class=\"\">\u5bb6\u9577\uff1a \u300c\u9019\u5c31\u662f\u300e\u6b7b\u7d50\u300f\u3002\u5c31\u50cf\u56db\u8f1b\u8eca\u5728\u5341\u5b57\u8def\u53e3\uff0c\u5927\u5bb6\u90fd\u60f3\u5148\u904e\uff0c\u7d50\u679c\u8ab0\u4e5f\u904e\u4e0d\u4e86\u300d\u3002<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"556\" height=\"352\" loading=\"lazy\" src=\"https:\/\/learndeeplytw.com\/wp-content\/uploads\/2025\/12\/image-7.png\" alt=\"\" class=\"wp-image-807\" style=\"aspect-ratio:1.579556623348258;width:594px;height:auto\" srcset=\"https:\/\/learndeeplytw.com\/wp-content\/uploads\/2025\/12\/image-7.png 556w, https:\/\/learndeeplytw.com\/wp-content\/uploads\/2025\/12\/image-7-300x190.png 300w, https:\/\/learndeeplytw.com\/wp-content\/uploads\/2025\/12\/image-7-18x12.png 18w\" sizes=\"auto, (max-width: 556px) 100vw, 556px\" \/><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\">\u7b2c\u4e8c\u968e\u6bb5\uff1a\u904a\u6232\u91cd\u555f-<strong>\u8b93\u7a7a\u4f4d\u6d41\u52d5\u8d77\u4f86<\/strong><\/h4>\n\n\n\n<p class=\"\">\u6211\u5011\u8981\u6253\u7834\u50f5\u5c40\uff0c\u5f15\u5165\u300c\u8def\u7531 (Routing)\u300d\u7684\u6982\u5ff5\u3002<\/p>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\">\n<li class=\"\"><strong>\u5f15\u5c0e\u601d\u8003\uff1a<\/strong>\n<ul class=\"wp-block-list\">\n<li class=\"\">\u300c\u525b\u525b\u6211\u5011\u5931\u6557\u4e86\uff0c\u56e0\u70ba\u5927\u5bb6\u90fd\u592a\u300e\u81ea\u79c1\u300f\uff08\u4e5f\u5c31\u662f\u62ff\u5230\u81ea\u5df1\u8a72\u62ff\u7684\u6c34\u679c\u4e4b\u5f8c\u5c31\u4e0d\u518d\u50b3\u4e86\uff09\u3002\u70ba\u4e86\u8b93\uff21\u6c34\u679c\u80fd\u5f9e\u6700\u5de6\u908a\u50b3\u5230\u6700\u53f3\u908a\uff0c\u4e2d\u9593\u7684\uff22\u548c\uff23\u5c31\u7b97\u62ff\u5230\u4e86\u81ea\u5df1\u7684\u6c34\u679c\uff0c\u662f\u4e0d\u662f\u4e5f\u5f97\u66ab\u6642\u5e6b\u5fd9\u50b3\u905e\u4e00\u4e0b\uff1f\u300d<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li class=\"\"><strong>\u65b0\u7b56\u7565\uff1a<\/strong>\n<ul class=\"wp-block-list\">\n<li class=\"\">\u6211\u5011\u4e0d\u518d\u53ea\u9867\u81ea\u5df1\u3002\u6211\u5011\u7684\u76ee\u6a19\u662f\u8b93\u90a3\u4e00\u96bb\u300c\u7a7a\u624b\u300d\u5728\u5713\u5708\u88e1\u8dd1\u8d77\u4f86\u3002<\/li>\n\n\n\n<li class=\"\"><strong>\u53e3\u8a23\uff1a<\/strong> \u300c<strong>\u6709\u7a7a\u4f4d\u5c31\u88dc\uff0c\u6709\u7403\u5c31\u50b3\uff01<\/strong>\u300d<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\">\u7b2c\u4e09\u968e\u6bb5\uff1a<strong>\u5408\u4f5c\u7684\u6f14\u7b97\u6cd5<\/strong><\/h4>\n\n\n\n<ol start=\"1\" class=\"wp-block-list\">\n<li class=\"\"><strong>\u57f7\u884c\u4efb\u52d9\uff1a<\/strong>\n<ul class=\"wp-block-list\">\n<li class=\"\">\u91cd\u65b0\u958b\u59cb\u3002\u9019\u6b21\u5b69\u5b50\u5011\u8981\u89c0\u5bdf\uff1a\u54ea\u88e1\u6709\u7a7a\u4f4d\uff08\u7a7a\u624b\uff09\uff1f<\/li>\n\n\n\n<li class=\"\">\u5982\u679c\u6211\u662f B\uff0c\u6211\u624b\u4e0a\u62ff\u8457 C \u7684\u6a58\u5b50\uff0c\u800c\u53f3\u908a\u7684 C \u6b63\u597d\u6709\u7a7a\u624b\uff0c\u6211\u5c31\u8d95\u5feb\u628a\u6a58\u5b50\u50b3\u7d66\u4ed6\u3002<\/li>\n\n\n\n<li class=\"\">\u5982\u679c\u6211\u662f D\uff0c\u6211\u62ff\u5230\u4e86\u81ea\u5df1\u7684 D \u6a58\u5b50\uff0c\u4f46\u70ba\u4e86\u8b93\u5361\u4f4f\u7684 A \u6a58\u5b50\u901a\u904e\uff0c\u6211\u9858\u610f\u5148\u628a\u624b\u4e0a\u7684 D \u50b3\u7d66\u65c1\u908a\u66ab\u653e\uff0c\u9a30\u51fa\u7a7a\u9593\u8b93 A \u901a\u904e\u3002<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li class=\"\"><strong>\u52d5\u614b\u89c0\u5bdf\uff1a<\/strong>\n<ul class=\"wp-block-list\">\n<li class=\"\">\u4f60\u6703\u770b\u5230\u6a58\u5b50\u5728\u5713\u5708\u88e1\u5feb\u901f\u6d41\u52d5\uff0c\u5c31\u50cf\u8eca\u6d41\u5728\u79fb\u52d5\u4e00\u6a23\u3002<\/li>\n\n\n\n<li class=\"\">\u6700\u5f8c\uff0c\u6bcf\u500b\u4eba\u624b\u4e0a\u7684\u6a58\u5b50\u90fd\u8ddf\u8eab\u4e0a\u7684\u6a19\u7c64\u5c0d\u61c9\u4e86\uff01<\/li>\n\n\n\n<li class=\"\">\u6b61\u547c\uff1a \u300c\u6211\u5011\u89e3\u958b\u6b7b\u7d50\u4e86\uff01\u7db2\u8def\u901a\u4e86\uff01\u300d<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\">\u7b2c\u56db\u968e\u6bb5\uff1a\u6982\u5ff5\u9023\u7d50<\/h4>\n\n\n\n<p class=\"\"><strong>\u70ba\u4ec0\u9ebc\u5927\u5bb6\u90fd\u6703\u5361\u4f4f\uff1f<\/strong><\/p>\n\n\n\n<p class=\"\">\u525b\u525b\u6211\u5011\u770b\u5230\uff0c\u5982\u679c\u6bcf\u500b\u4eba\u90fd\u6b7b\u6293\u8457\u6a58\u5b50\u4e0d\u653e\uff0c\u904a\u6232\u5c31\u7d50\u675f\u4e86\u3002\u5728\u771f\u5be6\u4e16\u754c\u88e1\uff0c\u9019\u7a2e\u300c\u4e92\u4e0d\u76f8\u8b93\u300d\u7684\u60c5\u6cc1\u5230\u8655\u53ef\u898b\uff1a<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li class=\"\"><strong>\u99ac\u8def\u4e0a\u7684\u300c\u5927\u773c\u77aa\u5c0f\u773c\u300d (Traffic Gridlock)<\/strong>\n<ul class=\"wp-block-list\">\n<li class=\"\">\u60c5\u5883\uff1a \u60f3\u50cf\u5728\u4e00\u500b\u5341\u5b57\u8def\u53e3\uff0c\u56db\u500b\u65b9\u5411\u540c\u6642\u90fd\u6709\u8eca\u5b50\u958b\u51fa\u4f86\uff0c\u5927\u5bb6\u90fd\u60f3\u5f80\u524d\u885d\uff0c\u7d50\u679c\u5168\u90e8\u5361\u5728\u4e2d\u9593\u3002<\/li>\n\n\n\n<li class=\"\">\u9023\u7d50\uff1a \u9019\u5c31\u50cf\u6211\u5011\u525b\u525b\u7684\u904a\u6232\uff0cA \u8eca\u64cb\u4f4f\u4e86 B \u8eca\uff0cB \u8eca\u64cb\u4f4f\u4e86 C \u8eca\uff0cC \u8eca\u53c8\u64cb\u4f4f\u4e86 A \u8eca\u3002\u9019\u7a2e\u9023\u8b66\u5bdf\u4f86\u90fd\u5f88\u96e3\u89e3\u958b\u7684\u4ea4\u901a\u6253\u7d50\uff0c\u5c31\u662f\u5178\u578b\u7684\u6b7b\u7d50\u3002<\/li>\n\n\n\n<li class=\"\">\u89e3\u6c7a\u65b9\u6cd5\uff1a \u5fc5\u9808\u6709\u4eba\u5f8c\u9000\uff08\u91cb\u653e\u8cc7\u6e90\uff09\uff0c\u6216\u8005\u9075\u5b88\u7d05\u7da0\u71c8\u898f\u5247\uff08\u901a\u8a0a\u5354\u5b9a\uff09\u3002<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li class=\"\"><strong>\u8de8\u5e74\u591c\u7684\u6377\u904b\u7ad9 (Crowd Congestion)<\/strong>\n<ul class=\"wp-block-list\">\n<li class=\"\">\u60c5\u5883\uff1a \u8de8\u5e74\u7159\u706b\u7d50\u675f\u5f8c\uff0c\u6210\u5343\u4e0a\u842c\u7684\u4eba\u540c\u6642\u8981\u6e67\u9032\u6377\u904b\u7ad9\u3002<\/li>\n\n\n\n<li class=\"\">\u9023\u7d50\uff1a \u7576\u592a\u591a\u4eba\u540c\u6642\u60f3\u8981\u6436\u540c\u4e00\u500b\u8cc7\u6e90\uff08\u8eca\u5ec2\u9580\uff09\uff0c\u5c31\u6703\u767c\u751f\u63a8\u64e0\uff0c\u7d50\u679c\u53cd\u800c\u8ab0\u4e5f\u9032\u4e0d\u53bb\uff0c\u901f\u5ea6\u8b8a\u5f97\u8d85\u7d1a\u6162\u3002<\/li>\n\n\n\n<li class=\"\">\u8def\u7531\u7684\u6982\u5ff5\uff1a \u9019\u6642\u5019\u6377\u904b\u7ad9\u54e1\u6703\u62ff\u8457\u5927\u8072\u516c\u5f15\u5c0e\uff1a\u300c\u5f80\u53f0\u5317\u8eca\u7ad9\u7684\u8acb\u8d70\u5de6\u908a\uff0c\u5f80\u6de1\u6c34\u7684\u8acb\u8d70\u53f3\u908a\u3002\u300d\u9019\u5c31\u662f\u5728\u505a\u300c\u8def\u7531 (Routing)\u300d\u2014\u2014\u5e6b\u5927\u91cf\u7684\u4eba\u6f6e\uff08\u8cc7\u6599\u5c01\u5305\uff09\u898f\u5283\u51fa\u4e0d\u6703\u6253\u7d50\u7684\u8def\u7dda\u3002<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li class=\"\"><strong>\u9280\u884c\u8f49\u5e33\u7684\u5c37\u5c2c (Banking Deadlock)<\/strong>\n<ul class=\"wp-block-list\">\n<li class=\"\">\u60c5\u5883\uff1a \u9019\u662f\u96fb\u8166\u4e16\u754c\u6700\u6015\u767c\u751f\u7684\u4e8b\u3002\u5047\u8a2d\u5c0f\u660e\u8981\u532f\u9322\u7d66\u5c0f\u83ef\uff0c\u5c0f\u83ef\u4e5f\u8981\u532f\u9322\u7d66\u5c0f\u660e\u3002<\/li>\n\n\n\n<li class=\"\">\u9023\u7d50\uff1a \u70ba\u4e86\u5b89\u5168\uff0c\u96fb\u8166\u5728\u8655\u7406\u532f\u6b3e\u6642\u6703\u5148\u628a\u5e33\u6236\u300c\u9396\u4f4f (Lock)\u300d\u3002<\/li>\n\n\n\n<li class=\"\">\u5982\u679c\u7a0b\u5f0f\u5beb\u5f97\u4e0d\u597d\uff0c\u96fb\u8166\u628a\u5c0f\u660e\u7684\u5e33\u6236\u9396\u4f4f\uff08\u7b49\u5c0f\u83ef\u7684\u9322\u9032\u4f86\uff09\uff0c\u540c\u6642\u53c8\u628a\u5c0f\u83ef\u7684\u5e33\u6236\u9396\u4f4f\uff08\u7b49\u5c0f\u660e\u7684\u9322\u9032\u4f86\uff09\u3002<\/li>\n\n\n\n<li class=\"\">\u5169\u908a\u90fd\u5728\u300c\u7b49\u5c0d\u65b9\u5148\u52d5\u4f5c\u300d\uff0c\u7d50\u679c\u5c31\u662f\u6c38\u9060\u7b49\u4e0d\u5230\uff0c\u9280\u884c\u7cfb\u7d71\u5c31\u6703\u7576\u6a5f\u3002<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\">\u7b2c\u4e94\u968e\u6bb5\uff1a\u9664\u932f\u8207\u6311\u6230<\/h4>\n\n\n\n<p class=\"\"><strong>\u6539\u8b8a\u5730\u5716\u5f62\u72c0<\/strong><\/p>\n\n\n\n<p class=\"\">\u7db2\u8def\u4e0d\u4e00\u5b9a\u90fd\u662f\u5713\u5708\uff0c\u6211\u5011\u53ef\u4ee5\u6539\u8b8a\u968a\u5f62\u4f86\u589e\u52a0\u96e3\u5ea6\u3002<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li class=\"\"><strong>\u6311\u6230\u4e00\uff1a\u4e00\u5b57\u9577\u86c7\u9663 (Line Topology)<\/strong>\n<ul class=\"wp-block-list\">\n<li class=\"\">\u8b93\u5927\u5bb6\u6392\u6210\u4e00\u76f4\u7dda\u3002\u6700\u5de6\u908a\u7684\u4eba\u8981\u50b3\u7d66\u6700\u53f3\u908a\u7684\u4eba\uff0c\u4e2d\u9593\u7684\u4eba\u6703\u975e\u5e38\u5fd9\u788c\u3002<\/li>\n\n\n\n<li class=\"\">\u89c0\u5bdf\uff1a \u4e2d\u9593\u7684\u4eba\u5982\u679c\u4e0d\u5e6b\u5fd9\uff0c\u5169\u982d\u7684\u4eba\u6c38\u9060\u62ff\u4e0d\u5230\u6c34\u679c\u3002\u9019\u986f\u793a\u4e86\u300c\u8def\u7531\u5668 (Router)\u300d\u7684\u91cd\u8981\u5de5\u4f5c\u3002<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li class=\"\"><strong>\u6311\u6230\u4e8c\uff1a\u7981\u6b62\u8aaa\u8a71 (Silent Mode)<\/strong>\n<ul class=\"wp-block-list\">\n<li class=\"\">\u898f\u5247\uff1a \u5168\u7a0b\u4e0d\u51c6\u8b1b\u8a71\uff0c\u53ea\u80fd\u7528\u773c\u795e\u793a\u610f\u9130\u5c45\u628a\u624b\u4f38\u51fa\u4f86\u63a5\u6c34\u679c\u3002<\/li>\n\n\n\n<li class=\"\">\u767c\u73fe\uff1a \u9019\u662f\u6a21\u64ec\u771f\u5be6\u7684\u96fb\u8166\u7db2\u8def\uff0c\u96fb\u8166\u4e4b\u9593\u4e0d\u6703\u8aaa\u8a71\uff0c\u5b83\u5011\u53ea\u80fd\u4f9d\u7167\u8a2d\u5b9a\u597d\u7684\u300c\u901a\u8a0a\u5354\u5b9a (Protocol)\u300d\u4f86\u50b3\u905e\u8cc7\u6599\u3002<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"> \u6559\u5b78\u89c0\u5bdf\u91cd\u9ede\u8868 <\/h3>\n\n\n\n<p class=\"\">\u9019\u5f35\u8868\u5e6b\u52a9\u60a8\u5f15\u5c0e\u5b69\u5b50\u7406\u89e3\u300c\u5c40\u90e8\u8caa\u5fc3\u300d\u8207\u300c\u5168\u5c40\u5408\u4f5c\u300d\u7684\u885d\u7a81\u3002<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><td><strong>\u89c0\u5bdf\u9ede<\/strong><\/td><td><strong>\u274c \u8f03\u7121\u6548\u7684\u53cd\u61c9 (\u8aaa\u6559)<\/strong><\/td><td><strong>\u2705 \u8f03\u6709\u6548\u7684\u5f15\u5c0e (\u555f\u767c\u601d\u8003)<\/strong><\/td><\/tr><\/thead><tbody><tr><td><strong>\u7576\u5b69\u5b50\u62ff\u5230\u81ea\u5df1\u7684\u7403\u5c31\u4e0d\u50b3\u4e86<\/strong><\/td><td>\u300c\u4e0d\u8981\u9019\u9ebc\u81ea\u79c1\uff0c\u50b3\u51fa\u53bb\u3002\u300d<\/td><td>\u300c\u4f60\u770b\uff0c\u4f60\u624b\u4e0a\u62ff\u6eff\u4e86\uff0c\u65c1\u908a\u7684\u4eba\u60f3\u7d66\u4f60\u7403\u4e5f\u7d66\u4e0d\u4e86\u3002\u5982\u679c\u4f60\u4e0d\u628a\u9019\u9846\u50b3\u51fa\u53bb\uff0c\u90a3\u500b\u4f60\u4e5f\u60f3\u8981\u7684\u53e6\u4e00\u9846\u7403\uff0c\u662f\u4e0d\u662f\u6c38\u9060\u50b3\u4e0d\u904e\u4f86\uff1f\u300d<\/td><\/tr><tr><td><strong>\u7576\u904a\u6232\u5361\u4f4f\u52d5\u4e0d\u4e86\u6642<\/strong><\/td><td>\u300c\u4f60\u5011\u73a9\u932f\u4e86\uff0c\u91cd\u4f86\u3002\u300d<\/td><td>\u300c\u73fe\u5728\u767c\u751f\u4e86\u4ec0\u9ebc\u4e8b\uff1f\u50cf\u4e0d\u50cf\u904e\u5e74\u585e\u8eca\uff1f\u6709\u6c92\u6709\u4eba\u9858\u610f\u7576\u90a3\u500b\u300e\u5012\u8eca\u300f\u8b93\u8def\u7684\u4eba\uff0c\u8b93\u4ea4\u901a\u6062\u5fa9\u9806\u66a2\uff1f\u300d<\/td><\/tr><tr><td><strong>\u89e3\u91cb\u70ba\u4ec0\u9ebc\u9700\u8981\u7a7a\u624b<\/strong><\/td><td>\u300c\u9019\u662f\u904a\u6232\u898f\u5247\u3002\u300d<\/td><td>\u300c\u9019\u96bb\u7a7a\u624b\u5c31\u50cf\u662f\u99ac\u8def\u4e0a\u8981\u4fdd\u6301\u7684\u300e\u5b89\u5168\u8ddd\u96e2\u300f\u3002\u5982\u679c\u99ac\u8def\u4e0a\u4e00\u8f1b\u8eca\u8cbc\u8457\u4e00\u8f1b\u8eca\uff0c\u5b8c\u5168\u6c92\u6709\u7a7a\u9699\uff0c\u8eca\u5b50\u9084\u80fd\u8b8a\u63db\u8eca\u9053\u55ce\uff1f\u300d<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">\ud83d\udca1 \u7d66\u5bb6\u9577\u7684\u5efa\u8b70<\/h3>\n\n\n\n<p class=\"\">\u9019\u500b\u6d3b\u52d5\u81f3\u5c11\u9700\u8981 5 \u500b\u4eba \u624d\u597d\u73a9\uff08\u5982\u679c\u4eba\u5920\u591a\uff0c\u751a\u81f3\u53ef\u4ee5\u8b93\u4e00\u500b\u4eba\u62ff\u5169\u9846\u7403\uff0c\u589e\u52a0\u64c1\u64e0\u611f\uff09\u3002\u5982\u679c\u4eba\u6578\u4e0d\u8db3\uff0c\u53ef\u4ee5\u7528\u73a9\u5076\u4ee3\u66ff\u5176\u4e2d\u5e7e\u500b\u4f4d\u7f6e\uff0c\u7531\u5bb6\u9577\u6216\u5b69\u5b50\u5e6b\u5fd9\u64cd\u4f5c\u73a9\u5076\u7684\u624b\u3002\u6700\u91cd\u8981\u7684\u662f\u8981\u8b93\u5b69\u5b50\u9ad4\u9a57\u5230\u300c\u6211\u5fc5\u9808\u5148\u628a\u624b\u4e0a\u7684\u6771\u897f\u7d66\u51fa\u53bb\uff0c\u6700\u7d42\u6211\u624d\u80fd\u62ff\u5230\u6211\u8981\u7684\u6771\u897f\u300d\u9019\u7a2e\u5408\u4f5c\u908f\u8f2f\uff0c\u9019\u6b63\u662f\u7db2\u969b\u7db2\u8def\u80fd\u904b\u4f5c\u5230\u4eca\u5929\u7684\u6838\u5fc3\u7cbe\u795e\uff01<\/p>\n\n\n\n<div class=\"wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/learndeeplytw.com\/game\/TheOrangeGame\/\" target=\"_blank\" rel=\"noreferrer noopener\">\u9019\u88e1\u6709\u5c0f\u904a\u6232\u5537<\/a><\/div>\n<\/div>\n\n\n\n<!-- Orange Game WordPress Embed - Auto Demo Version -->\n<!-- Copy and paste this into a Custom HTML block in WordPress -->\n\n<div id=\"orange-game-wrapper\" class=\"orange-game-container\">\n    <!-- Load Fonts -->\n    <link\n        href=\"https:\/\/fonts.googleapis.com\/css2?family=JetBrains+Mono:wght@400;700&#038;family=Share+Tech+Mono&#038;display=swap\"\n        rel=\"stylesheet\">\n\n    <style>\n        \/* Scoped Styles for #orange-game-wrapper *\/\n        #orange-game-wrapper {\n            background-color: #000000;\n            color: #c7d0d9;\n            font-family: 'JetBrains Mono', monospace;\n            padding: 1rem;\n            border-radius: 0.5rem;\n            position: relative;\n            overflow: hidden;\n            max-width: 800px;\n            margin: 0 auto;\n        }\n\n        #orange-game-wrapper * {\n            box-sizing: border-box;\n        }\n\n        \/* Scanline Effect *\/\n        #orange-game-wrapper .og-scanline {\n            background: linear-gradient(to bottom,\n                    rgba(255, 255, 255, 0),\n                    rgba(255, 255, 255, 0) 50%,\n                    rgba(0, 0, 0, 0.2) 50%,\n                    rgba(0, 0, 0, 0.2));\n            background-size: 100% 4px;\n            position: absolute;\n            top: 0;\n            left: 0;\n            right: 0;\n            bottom: 0;\n            pointer-events: none;\n            z-index: 50;\n            opacity: 0.15;\n        }\n\n        #orange-game-wrapper .og-text-glow {\n            text-shadow: 0 0 10px rgba(87, 242, 135, 0.5);\n        }\n\n        #orange-game-wrapper .og-panel {\n            border: 1px solid #22252b;\n            border-radius: 4px;\n            background-color: #111217;\n            padding: 1rem;\n        }\n\n        \/* Header *\/\n        #orange-game-wrapper .og-header {\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n            margin-bottom: 1rem;\n            padding-bottom: 0.75rem;\n            border-bottom: 1px solid #22252b;\n        }\n\n        #orange-game-wrapper .og-header-left {\n            display: flex;\n            align-items: center;\n            gap: 0.5rem;\n        }\n\n        #orange-game-wrapper .og-status-dot {\n            width: 10px;\n            height: 10px;\n            background-color: #57f287;\n            border-radius: 50%;\n            animation: og-pulse 2s infinite;\n            box-shadow: 0 0 5px rgba(87, 242, 135, 0.5);\n        }\n\n        @keyframes og-pulse {\n\n            0%,\n            100% {\n                opacity: 1;\n            }\n\n            50% {\n                opacity: 0.5;\n            }\n        }\n\n        #orange-game-wrapper .og-title {\n            color: #57f287;\n            font-family: 'Share Tech Mono', monospace;\n            font-size: 1rem;\n            letter-spacing: 0.05em;\n            margin: 0;\n        }\n\n        #orange-game-wrapper .og-title-sep {\n            color: #4a5568;\n        }\n\n        \/* Status bar *\/\n        #orange-game-wrapper .og-status-bar {\n            display: flex;\n            justify-content: space-between;\n            align-items: center;\n            font-size: 0.75rem;\n            color: #6b7280;\n            margin-bottom: 1rem;\n        }\n\n        #orange-game-wrapper .og-status-active {\n            color: #57f287;\n            animation: og-pulse 2s infinite;\n        }\n\n        \/* Game area *\/\n        #orange-game-wrapper .og-game-area {\n            display: flex;\n            flex-direction: column;\n            align-items: center;\n            padding: 1rem 0;\n        }\n\n        \/* Circle container *\/\n        #orange-game-wrapper .og-circle {\n            position: relative;\n            width: 320px;\n            height: 320px;\n        }\n\n        @media (max-width: 400px) {\n            #orange-game-wrapper .og-circle {\n                width: 260px;\n                height: 260px;\n            }\n        }\n\n        \/* Player node *\/\n        #orange-game-wrapper .og-player {\n            position: absolute;\n            display: flex;\n            flex-direction: column;\n            align-items: center;\n            transform: translate(-50%, -50%);\n            transition: all 0.3s ease;\n        }\n\n        #orange-game-wrapper .og-player-label {\n            width: 40px;\n            height: 40px;\n            border: 2px solid #57f287;\n            border-radius: 50%;\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            font-family: 'Share Tech Mono', monospace;\n            font-size: 1rem;\n            font-weight: bold;\n            color: #57f287;\n            background: rgba(87, 242, 135, 0.1);\n            box-shadow: 0 0 5px rgba(87, 242, 135, 0.3);\n        }\n\n        #orange-game-wrapper .og-player.og-matched .og-player-label {\n            background: #57f287;\n            color: #000;\n        }\n\n        \/* Player hands *\/\n        #orange-game-wrapper .og-hands {\n            display: flex;\n            gap: 3px;\n            margin-top: 6px;\n        }\n\n        #orange-game-wrapper .og-hand {\n            width: 28px;\n            height: 28px;\n            border: 2px dashed #4a5568;\n            border-radius: 50%;\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            transition: all 0.3s ease;\n        }\n\n        #orange-game-wrapper .og-hand.og-highlight {\n            border-color: #57f287;\n            background: rgba(87, 242, 135, 0.2);\n            animation: og-pulse 0.5s infinite;\n        }\n\n        \/* Orange *\/\n        #orange-game-wrapper .og-orange {\n            width: 24px;\n            height: 24px;\n            background: #ff9830;\n            border-radius: 50%;\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            font-size: 0.65rem;\n            font-weight: bold;\n            color: #000;\n            box-shadow: 0 0 6px rgba(255, 152, 48, 0.5);\n            transition: all 0.5s ease;\n        }\n\n        #orange-game-wrapper .og-orange.og-moving {\n            position: absolute;\n            z-index: 100;\n        }\n\n        #orange-game-wrapper .og-orange.og-matched {\n            background: #57f287;\n            box-shadow: 0 0 8px rgba(87, 242, 135, 0.6);\n        }\n\n        \/* Message *\/\n        #orange-game-wrapper .og-message {\n            text-align: center;\n            font-size: 0.75rem;\n            color: #6b7280;\n            margin-top: 1rem;\n            min-height: 20px;\n        }\n\n        #orange-game-wrapper .og-message.og-success {\n            color: #57f287;\n        }\n\n        \/* Control buttons *\/\n        #orange-game-wrapper .og-controls {\n            display: flex;\n            gap: 0.5rem;\n            margin-top: 1rem;\n            justify-content: center;\n        }\n\n        #orange-game-wrapper .og-btn {\n            padding: 0.5rem 1rem;\n            border: 1px solid #57f287;\n            background: rgba(87, 242, 135, 0.1);\n            color: #57f287;\n            font-family: 'JetBrains Mono', monospace;\n            font-size: 0.75rem;\n            font-weight: bold;\n            cursor: pointer;\n            transition: all 0.2s;\n        }\n\n        #orange-game-wrapper .og-btn:hover {\n            background: #57f287;\n            color: #000;\n        }\n\n        #orange-game-wrapper .og-btn:disabled {\n            opacity: 0.5;\n            cursor: not-allowed;\n        }\n\n        #orange-game-wrapper .og-btn:disabled:hover {\n            background: rgba(87, 242, 135, 0.1);\n            color: #57f287;\n        }\n\n        \/* Log panel *\/\n        #orange-game-wrapper .og-log {\n            background: #000;\n            border: 1px solid #22252b;\n            padding: 0.5rem;\n            margin-top: 1rem;\n            max-height: 100px;\n            overflow-y: auto;\n            font-size: 0.7rem;\n            color: #6b7280;\n        }\n\n        #orange-game-wrapper .og-log-entry {\n            margin-bottom: 0.25rem;\n        }\n\n        #orange-game-wrapper .og-log-entry.og-log-success {\n            color: #57f287;\n        }\n\n        #orange-game-wrapper .og-log-entry.og-log-move {\n            color: #ff9830;\n        }\n\n        \/* Progress bar *\/\n        #orange-game-wrapper .og-progress-bar {\n            width: 100%;\n            height: 4px;\n            background: #22252b;\n            border-radius: 2px;\n            overflow: hidden;\n            margin-top: 0.5rem;\n        }\n\n        #orange-game-wrapper .og-progress-fill {\n            height: 100%;\n            background: #57f287;\n            transition: width 0.3s ease;\n            box-shadow: 0 0 8px rgba(87, 242, 135, 0.5);\n        }\n\n        \/* Win celebration *\/\n        @keyframes og-celebrate {\n\n            0%,\n            100% {\n                transform: scale(1);\n            }\n\n            50% {\n                transform: scale(1.02);\n            }\n        }\n\n        #orange-game-wrapper.og-won .og-circle {\n            animation: og-celebrate 1s ease-in-out infinite;\n        }\n    <\/style>\n\n    <div class=\"og-scanline\"><\/div>\n\n    <!-- Header -->\n    <div class=\"og-header\">\n        <div class=\"og-header-left\">\n            <div class=\"og-status-dot\"><\/div>\n            <h3 class=\"og-title\">ORANGE_GAME <span class=\"og-title-sep\">\/\/<\/span> AUTO_DEMO<\/h3>\n        <\/div>\n    <\/div>\n\n    <!-- Status Bar -->\n    <div class=\"og-status-bar\">\n        <span>MOVES: <span id=\"og-moves\">0<\/span><\/span>\n        <span>MATCHED: <span id=\"og-matched\">0\/0<\/span><\/span>\n        <span id=\"og-status\" class=\"og-status-active\">IDLE<\/span>\n    <\/div>\n\n    <!-- Progress Bar -->\n    <div class=\"og-progress-bar\">\n        <div class=\"og-progress-fill\" id=\"og-progress\" style=\"width: 0%\"><\/div>\n    <\/div>\n\n    <!-- Game Area -->\n    <div class=\"og-game-area\" id=\"og-game-area\">\n        <!-- Circle rendered here -->\n    <\/div>\n\n    <!-- Message -->\n    <div class=\"og-message\" id=\"og-message\">\u9ede\u64ca\u300c\u958b\u59cb\u6f14\u793a\u300d\u89c0\u770b\u81ea\u52d5\u89e3\u8b0e\u904e\u7a0b<\/div>\n\n    <!-- Controls -->\n    <div class=\"og-controls\">\n        <button class=\"og-btn\" id=\"og-btn-demo\">\u25b6 \u958b\u59cb\u6f14\u793a<\/button>\n        <button class=\"og-btn\" id=\"og-btn-reset\" disabled>\u21ba \u91cd\u7f6e<\/button>\n    <\/div>\n\n    <!-- Log -->\n    <div class=\"og-log\" id=\"og-log\">\n        <div class=\"og-log-entry og-log-success\">> SYSTEM_READY<\/div>\n    <\/div>\n\n    <script>\n        (function () {\n            'use strict';\n\n            \/\/ Game state\n            const state = {\n                players: [],\n                playerCount: 5,\n                moves: 0,\n                isRunning: false,\n                moveQueue: [],\n                currentMoveIndex: 0,\n                animationSpeed: 1200 \/\/ ms per move\n            };\n\n            \/\/ DOM elements\n            const els = {\n                gameArea: document.getElementById('og-game-area'),\n                moves: document.getElementById('og-moves'),\n                matched: document.getElementById('og-matched'),\n                status: document.getElementById('og-status'),\n                progress: document.getElementById('og-progress'),\n                message: document.getElementById('og-message'),\n                log: document.getElementById('og-log'),\n                btnDemo: document.getElementById('og-btn-demo'),\n                btnReset: document.getElementById('og-btn-reset')\n            };\n\n            function log(msg, type) {\n                type = type || 'info';\n                const div = document.createElement('div');\n                div.className = 'og-log-entry' + (type === 'success' ? ' og-log-success' : (type === 'move' ? ' og-log-move' : ''));\n                div.textContent = '> ' + msg;\n                els.log.appendChild(div);\n                els.log.scrollTop = els.log.scrollHeight;\n            }\n\n            \/\/ Initialize game with a solvable configuration\n            function initGame() {\n                state.players = [];\n                state.moves = 0;\n                state.moveQueue = [];\n                state.currentMoveIndex = 0;\n\n                const letters = 'ABCDE';\n\n                \/\/ Create players (arranged in a circle: A-B-C-D-E-A)\n                \/\/ Adjacent pairs: A\u2194B, B\u2194C, C\u2194D, D\u2194E, E\u2194A\n                for (let i = 0; i < state.playerCount; i++) {\n                    state.players.push({\n                        id: i,\n                        letter: letters[i],\n                        hands: [null, null]\n                    });\n                }\n\n                \/\/ Create a solvable puzzle with valid moves only\n                \/\/ Initial configuration:\n                \/\/ A: [B, _]  - has B, one empty hand\n                \/\/ B: [A, C]  - has A and C\n                \/\/ C: [C, D]  - has C (matched!) and D\n                \/\/ D: [D, E]  - has D (matched!) and E\n                \/\/ E: [E, B]  - has E (matched!) and B\n                \/\/ Count: A\u00d71, B\u00d72, C\u00d72, D\u00d72, E\u00d72 = 9 oranges \u2713\n\n                state.players[0].hands = ['B', null];  \/\/ A: has B, empty\n                state.players[1].hands = ['A', 'C'];   \/\/ B: has A, C\n                state.players[2].hands = ['C', 'D'];   \/\/ C: has C\u2713, D\n                state.players[3].hands = ['D', 'E'];   \/\/ D: has D\u2713, E\n                state.players[4].hands = ['E', 'B'];   \/\/ E: has E\u2713, B\n\n                \/\/ Solution: All moves verified to be adjacent + to empty hand\n                \/\/ Circle: A(0)\u2194B(1)\u2194C(2)\u2194D(3)\u2194E(4)\u2194A(0)\n                state.moveQueue = [\n                    \/\/ Step 1: B passes A to A's empty hand (B\u2194A adjacent) \u2713\n                    { from: 1, fromHand: 0, to: 0, toHand: 1, desc: 'B \u2192 A: \u50b3\u905e [A]' },\n                    \/\/ After: A:[B,A], B:[_,C]\n\n                    \/\/ Step 2: A passes B to B's empty hand (A\u2194B adjacent) \u2713\n                    { from: 0, fromHand: 0, to: 1, toHand: 0, desc: 'A \u2192 B: \u50b3\u905e [B]' },\n                    \/\/ After: A:[_,A]\u2713, B:[B,C]\n\n                    \/\/ Step 3: E passes B to A's empty hand (E\u2194A adjacent) \u2713\n                    { from: 4, fromHand: 1, to: 0, toHand: 0, desc: 'E \u2192 A: \u50b3\u905e [B]' },\n                    \/\/ After: A:[B,A], E:[E,_]\n\n                    \/\/ Step 4: D passes E to E's empty hand (D\u2194E adjacent) \u2713\n                    { from: 3, fromHand: 1, to: 4, toHand: 1, desc: 'D \u2192 E: \u50b3\u905e [E]' },\n                    \/\/ After: D:[D,_]\u2713, E:[E,E]\u2713\n\n                    \/\/ Step 5: C passes D to D's empty hand (C\u2194D adjacent) \u2713\n                    { from: 2, fromHand: 1, to: 3, toHand: 1, desc: 'C \u2192 D: \u50b3\u905e [D]' },\n                    \/\/ After: C:[C,_]\u2713, D:[D,D]\u2713\n\n                    \/\/ Step 6: B passes C to C's empty hand (B\u2194C adjacent) \u2713\n                    { from: 1, fromHand: 1, to: 2, toHand: 1, desc: 'B \u2192 C: \u50b3\u905e [C]' },\n                    \/\/ After: B:[B,_], C:[C,C]\u2713\n\n                    \/\/ Step 7: A passes B to B's empty hand (A\u2194B adjacent) \u2713\n                    { from: 0, fromHand: 0, to: 1, toHand: 1, desc: 'A \u2192 B: \u50b3\u905e [B]' },\n                    \/\/ Final: A:[_,A]\u2713, B:[B,B]\u2713, C:[C,C]\u2713, D:[D,D]\u2713, E:[E,E]\u2713\n                ];\n\n                render();\n                updateStats();\n                els.message.textContent = '\u9ede\u64ca\u300c\u958b\u59cb\u6f14\u793a\u300d\u89c0\u770b\u81ea\u52d5\u89e3\u8b0e\u904e\u7a0b';\n                els.message.className = 'og-message';\n                els.log.innerHTML = '<div class=\"og-log-entry og-log-success\">> SYSTEM_READY<\/div>';\n                log('PUZZLE_INITIALIZED [5 PLAYERS]', 'success');\n            }\n\n            function isAdjacent(from, to) {\n                const diff = Math.abs(from - to);\n                return diff === 1 || diff === state.playerCount - 1;\n            }\n\n            function countMatched() {\n                let matched = 0;\n                let total = 0;\n                state.players.forEach(function (p) {\n                    p.hands.forEach(function (o) {\n                        if (o !== null) {\n                            total++;\n                            if (o === p.letter) matched++;\n                        }\n                    });\n                });\n                return { matched: matched, total: total };\n            }\n\n            function updateStats() {\n                els.moves.textContent = state.moves;\n                const stats = countMatched();\n                els.matched.textContent = stats.matched + '\/' + stats.total;\n\n                const progress = stats.total > 0 ? (stats.matched \/ stats.total * 100) : 0;\n                els.progress.style.width = progress + '%';\n            }\n\n            function render() {\n                const size = 320;\n                const radius = size \/ 2 - 50;\n                const cx = size \/ 2;\n                const cy = size \/ 2;\n\n                let html = '<div class=\"og-circle\">';\n\n                state.players.forEach(function (player, i) {\n                    const angle = (2 * Math.PI * i \/ state.playerCount) - Math.PI \/ 2;\n                    const x = cx + radius * Math.cos(angle);\n                    const y = cy + radius * Math.sin(angle);\n\n                    \/\/ Check if player has ALL their letters (fully matched)\n                    const ownOranges = player.hands.filter(function (o) { return o === player.letter; }).length;\n                    const totalOranges = player.hands.filter(function (o) { return o !== null; }).length;\n                    const isFullyMatched = ownOranges === totalOranges && totalOranges > 0;\n\n                    const pClass = isFullyMatched ? 'og-player og-matched' : 'og-player';\n\n                    let handsHtml = '';\n                    player.hands.forEach(function (orange, h) {\n                        const isMatch = orange === player.letter;\n                        if (orange) {\n                            const oClass = isMatch ? 'og-orange og-matched' : 'og-orange';\n                            handsHtml += '<div class=\"og-hand\" data-player=\"' + i + '\" data-hand=\"' + h + '\">' +\n                                '<div class=\"' + oClass + '\">' + orange + '<\/div><\/div>';\n                        } else {\n                            handsHtml += '<div class=\"og-hand\" data-player=\"' + i + '\" data-hand=\"' + h + '\" data-empty=\"1\"><\/div>';\n                        }\n                    });\n\n                    html += '<div class=\"' + pClass + '\" style=\"left:' + x + 'px;top:' + y + 'px;\" data-player=\"' + i + '\">' +\n                        '<div class=\"og-player-label\">' + player.letter + '<\/div>' +\n                        '<div class=\"og-hands\">' + handsHtml + '<\/div><\/div>';\n                });\n\n                html += '<\/div>';\n                els.gameArea.innerHTML = html;\n            }\n\n            function executeMove(move, callback) {\n                const fromPlayer = state.players[move.from];\n                const orange = fromPlayer.hands[move.fromHand];\n\n                \/\/ Highlight source and target\n                const fromHand = els.gameArea.querySelector('[data-player=\"' + move.from + '\"][data-hand=\"' + move.fromHand + '\"]');\n                const toHand = els.gameArea.querySelector('[data-player=\"' + move.to + '\"][data-hand=\"' + move.toHand + '\"]');\n\n                if (fromHand) fromHand.classList.add('og-highlight');\n\n                setTimeout(function () {\n                    if (toHand) toHand.classList.add('og-highlight');\n\n                    setTimeout(function () {\n                        \/\/ Execute the move\n                        const toPlayer = state.players[move.to];\n                        fromPlayer.hands[move.fromHand] = null;\n                        toPlayer.hands[move.toHand] = orange;\n                        state.moves++;\n\n                        log(move.desc, 'move');\n                        updateStats();\n                        render();\n\n                        callback();\n                    }, 400);\n                }, 400);\n            }\n\n            function checkAllMatched() {\n                return state.players.every(function (p) {\n                    return p.hands.every(function (o) {\n                        return o === null || o === p.letter;\n                    }) && p.hands.some(function (o) { return o === p.letter; });\n                });\n            }\n\n            function runDemo() {\n                if (state.currentMoveIndex >= state.moveQueue.length || checkAllMatched()) {\n                    \/\/ Demo complete\n                    state.isRunning = false;\n                    els.status.textContent = 'COMPLETE';\n                    els.message.textContent = '\ud83c\udf89 \u6f14\u793a\u5b8c\u6210\uff01\u6240\u6709\u6a58\u5b50\u5df2\u6b78\u4f4d\uff01';\n                    els.message.className = 'og-message og-success';\n                    els.btnDemo.disabled = false;\n                    els.btnReset.disabled = false;\n                    document.getElementById('orange-game-wrapper').classList.add('og-won');\n                    log('DEMO_COMPLETE - ALL_MATCHED', 'success');\n                    return;\n                }\n\n                const move = state.moveQueue[state.currentMoveIndex];\n                els.status.textContent = 'STEP_' + (state.currentMoveIndex + 1) + '\/' + state.moveQueue.length;\n                els.message.textContent = move.desc;\n\n                executeMove(move, function () {\n                    state.currentMoveIndex++;\n                    setTimeout(function () {\n                        runDemo();\n                    }, 800);\n                });\n            }\n\n            function startDemo() {\n                if (state.isRunning) return;\n\n                state.isRunning = true;\n                els.btnDemo.disabled = true;\n                els.btnReset.disabled = true;\n                els.status.textContent = 'RUNNING';\n                els.message.textContent = '\u81ea\u52d5\u6f14\u793a\u9032\u884c\u4e2d...';\n                log('DEMO_STARTED', 'success');\n\n                setTimeout(runDemo, 500);\n            }\n\n            function reset() {\n                state.isRunning = false;\n                document.getElementById('orange-game-wrapper').classList.remove('og-won');\n                els.btnDemo.disabled = false;\n                els.btnReset.disabled = true;\n                els.status.textContent = 'IDLE';\n                initGame();\n            }\n\n            \/\/ Event listeners\n            els.btnDemo.addEventListener('click', startDemo);\n            els.btnReset.addEventListener('click', reset);\n\n            \/\/ Initialize\n            initGame();\n        })();\n    <\/script>\n<\/div>\n\n\n\n<div style=\"height:100px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\"><\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\"><\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>\u4f60\u6709\u6c92\u6709\u9047\u904e\u73a9\u904a\u6232\u73a9\u5230\u4e00\u534a\uff0c\u756b\u9762\u7a81\u7136\u5361\u4f4f\u4e0d\u52d5\uff1f\u6216\u8005\u662f\u7238\u7238\u958b\u8eca\u6642\uff0c\u5728\u5c0f\u5df7\u5b50\u88e1\u8ddf\u5225\u4eba\u7684\u8eca\u5b50\u300c\u5927\u773c\u77aa\u5c0f\u773c\u300d\uff0c\u8ab0\u4e5f\u904e\u4e0d [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":809,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"nf_dc_page":"","footnotes":""},"categories":[9,18],"tags":[47,48,26,41,46,24],"class_list":["post-802","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cs-unplugged","category-algorithms","tag-deadlock","tag-routering","tag-26","tag-41","tag-46","tag-24"],"blocksy_meta":[],"_links":{"self":[{"href":"https:\/\/learndeeplytw.com\/en\/wp-json\/wp\/v2\/posts\/802","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/learndeeplytw.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/learndeeplytw.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/learndeeplytw.com\/en\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/learndeeplytw.com\/en\/wp-json\/wp\/v2\/comments?post=802"}],"version-history":[{"count":4,"href":"https:\/\/learndeeplytw.com\/en\/wp-json\/wp\/v2\/posts\/802\/revisions"}],"predecessor-version":[{"id":867,"href":"https:\/\/learndeeplytw.com\/en\/wp-json\/wp\/v2\/posts\/802\/revisions\/867"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/learndeeplytw.com\/en\/wp-json\/wp\/v2\/media\/809"}],"wp:attachment":[{"href":"https:\/\/learndeeplytw.com\/en\/wp-json\/wp\/v2\/media?parent=802"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/learndeeplytw.com\/en\/wp-json\/wp\/v2\/categories?post=802"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/learndeeplytw.com\/en\/wp-json\/wp\/v2\/tags?post=802"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}