纠正仓库内容为衍生项目,标明 campaign-200-r2 最新版
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 380 266.66666666666663" role="img" aria-label="认识共边上的永久墙"><polygon points="20,20 133.33333333333331,20 133.33333333333331,133.33333333333331 20,133.33333333333331" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="133.33333333333331,20 246.66666666666666,20 246.66666666666666,133.33333333333331 133.33333333333331,133.33333333333331" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="246.66666666666666,20 360,20 360,133.33333333333331 246.66666666666666,133.33333333333331" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="20,133.33333333333331 133.33333333333331,133.33333333333331 133.33333333333331,246.66666666666666 20,246.66666666666666" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="133.33333333333331,133.33333333333331 246.66666666666666,133.33333333333331 246.66666666666666,246.66666666666666 133.33333333333331,246.66666666666666" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="246.66666666666666,133.33333333333331 360,133.33333333333331 360,246.66666666666666 246.66666666666666,246.66666666666666" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><line x1="246.66666666666666" y1="33.599999999999994" x2="246.66666666666666" y2="119.73333333333332" stroke="#272638" stroke-width="8" transform="rotate(0 246.66666666666666 76.66666666666666)"/><line x1="246.66666666666666" y1="33.599999999999994" x2="246.66666666666666" y2="119.73333333333332" stroke="#ffc542" stroke-width="4" stroke-dasharray="5 4" transform="rotate(0 246.66666666666666 76.66666666666666)"/><text x="76.66666666666666" y="68.66666666666666" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700"></text><text x="76.66666666666666" y="86.66666666666666" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c0</text><text x="190" y="68.66666666666666" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700"></text><text x="190" y="86.66666666666666" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c1</text><text x="303.3333333333333" y="68.66666666666666" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">1</text><text x="303.3333333333333" y="86.66666666666666" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c2</text><text x="76.66666666666666" y="182" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">4</text><text x="76.66666666666666" y="200" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c3</text><text x="190" y="182" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700"></text><text x="190" y="200" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c4</text><text x="303.3333333333333" y="182" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700"></text><text x="303.3333333333333" y="200" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c5</text></svg>
|
||||
|
After Width: | Height: | Size: 3.1 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 380 266.66666666666663" role="img" aria-label="认识共边上的永久墙"><polygon points="20,20 133.33333333333331,20 133.33333333333331,133.33333333333331 20,133.33333333333331" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="133.33333333333331,20 246.66666666666666,20 246.66666666666666,133.33333333333331 133.33333333333331,133.33333333333331" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="246.66666666666666,20 360,20 360,133.33333333333331 246.66666666666666,133.33333333333331" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="20,133.33333333333331 133.33333333333331,133.33333333333331 133.33333333333331,246.66666666666666 20,246.66666666666666" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="133.33333333333331,133.33333333333331 246.66666666666666,133.33333333333331 246.66666666666666,246.66666666666666 133.33333333333331,246.66666666666666" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="246.66666666666666,133.33333333333331 360,133.33333333333331 360,246.66666666666666 246.66666666666666,246.66666666666666" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polyline points="303.3333333333333,76.66666666666666 303.3333333333333,190 190,190 76.66666666666666,190 76.66666666666666,76.66666666666666 190,76.66666666666666" fill="none" stroke="#7963c9" stroke-width="5" opacity=".4"/><line x1="246.66666666666666" y1="33.599999999999994" x2="246.66666666666666" y2="119.73333333333332" stroke="#272638" stroke-width="8" transform="rotate(0 246.66666666666666 76.66666666666666)"/><line x1="246.66666666666666" y1="33.599999999999994" x2="246.66666666666666" y2="119.73333333333332" stroke="#ffc542" stroke-width="4" stroke-dasharray="5 4" transform="rotate(0 246.66666666666666 76.66666666666666)"/><text x="76.66666666666666" y="68.66666666666666" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">5</text><text x="76.66666666666666" y="86.66666666666666" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c0</text><text x="190" y="68.66666666666666" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">6</text><text x="190" y="86.66666666666666" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c1</text><text x="303.3333333333333" y="68.66666666666666" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">1</text><text x="303.3333333333333" y="86.66666666666666" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c2</text><text x="76.66666666666666" y="182" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">4</text><text x="76.66666666666666" y="200" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c3</text><text x="190" y="182" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">3</text><text x="190" y="200" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c4</text><text x="303.3333333333333" y="182" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">2</text><text x="303.3333333333333" y="200" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c5</text></svg>
|
||||
|
After Width: | Height: | Size: 3.4 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 380 380" role="img" aria-label="近在旁边也要绕墙"><polygon points="20,20 133.33333333333331,20 133.33333333333331,133.33333333333331 20,133.33333333333331" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="133.33333333333331,20 246.66666666666666,20 246.66666666666666,133.33333333333331 133.33333333333331,133.33333333333331" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="246.66666666666666,20 360,20 360,133.33333333333331 246.66666666666666,133.33333333333331" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="20,133.33333333333331 133.33333333333331,133.33333333333331 133.33333333333331,246.66666666666666 20,246.66666666666666" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="133.33333333333331,133.33333333333331 246.66666666666666,133.33333333333331 246.66666666666666,246.66666666666666 133.33333333333331,246.66666666666666" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="246.66666666666666,133.33333333333331 360,133.33333333333331 360,246.66666666666666 246.66666666666666,246.66666666666666" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="20,246.66666666666666 133.33333333333331,246.66666666666666 133.33333333333331,360 20,360" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="133.33333333333331,246.66666666666666 246.66666666666666,246.66666666666666 246.66666666666666,360 133.33333333333331,360" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><line x1="190" y1="203.6" x2="190" y2="289.73333333333335" stroke="#272638" stroke-width="8" transform="rotate(90 190 246.66666666666666)"/><line x1="190" y1="203.6" x2="190" y2="289.73333333333335" stroke="#ffc542" stroke-width="4" stroke-dasharray="5 4" transform="rotate(90 190 246.66666666666666)"/><text x="76.66666666666666" y="68.66666666666666" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700"></text><text x="76.66666666666666" y="86.66666666666666" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c0</text><text x="190" y="68.66666666666666" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700"></text><text x="190" y="86.66666666666666" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c1</text><text x="303.3333333333333" y="68.66666666666666" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">1</text><text x="303.3333333333333" y="86.66666666666666" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c2</text><text x="76.66666666666666" y="182" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700"></text><text x="76.66666666666666" y="200" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c3</text><text x="190" y="182" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700"></text><text x="190" y="200" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c4</text><text x="303.3333333333333" y="182" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700"></text><text x="303.3333333333333" y="200" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c5</text><text x="76.66666666666666" y="295.3333333333333" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700"></text><text x="76.66666666666666" y="313.3333333333333" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c6</text><text x="190" y="295.3333333333333" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700"></text><text x="190" y="313.3333333333333" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c7</text></svg>
|
||||
|
After Width: | Height: | Size: 3.9 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 380 380" role="img" aria-label="近在旁边也要绕墙"><polygon points="20,20 133.33333333333331,20 133.33333333333331,133.33333333333331 20,133.33333333333331" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="133.33333333333331,20 246.66666666666666,20 246.66666666666666,133.33333333333331 133.33333333333331,133.33333333333331" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="246.66666666666666,20 360,20 360,133.33333333333331 246.66666666666666,133.33333333333331" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="20,133.33333333333331 133.33333333333331,133.33333333333331 133.33333333333331,246.66666666666666 20,246.66666666666666" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="133.33333333333331,133.33333333333331 246.66666666666666,133.33333333333331 246.66666666666666,246.66666666666666 133.33333333333331,246.66666666666666" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="246.66666666666666,133.33333333333331 360,133.33333333333331 360,246.66666666666666 246.66666666666666,246.66666666666666" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="20,246.66666666666666 133.33333333333331,246.66666666666666 133.33333333333331,360 20,360" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="133.33333333333331,246.66666666666666 246.66666666666666,246.66666666666666 246.66666666666666,360 133.33333333333331,360" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polyline points="303.3333333333333,76.66666666666666 303.3333333333333,190 190,190 190,76.66666666666666 76.66666666666666,76.66666666666666 76.66666666666666,190 76.66666666666666,303.3333333333333 190,303.3333333333333" fill="none" stroke="#7963c9" stroke-width="5" opacity=".4"/><line x1="190" y1="203.6" x2="190" y2="289.73333333333335" stroke="#272638" stroke-width="8" transform="rotate(90 190 246.66666666666666)"/><line x1="190" y1="203.6" x2="190" y2="289.73333333333335" stroke="#ffc542" stroke-width="4" stroke-dasharray="5 4" transform="rotate(90 190 246.66666666666666)"/><text x="76.66666666666666" y="68.66666666666666" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">5</text><text x="76.66666666666666" y="86.66666666666666" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c0</text><text x="190" y="68.66666666666666" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">4</text><text x="190" y="86.66666666666666" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c1</text><text x="303.3333333333333" y="68.66666666666666" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">1</text><text x="303.3333333333333" y="86.66666666666666" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c2</text><text x="76.66666666666666" y="182" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">6</text><text x="76.66666666666666" y="200" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c3</text><text x="190" y="182" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">3</text><text x="190" y="200" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c4</text><text x="303.3333333333333" y="182" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">2</text><text x="303.3333333333333" y="200" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c5</text><text x="76.66666666666666" y="295.3333333333333" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">7</text><text x="76.66666666666666" y="313.3333333333333" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c6</text><text x="190" y="295.3333333333333" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">8</text><text x="190" y="313.3333333333333" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c7</text></svg>
|
||||
|
After Width: | Height: | Size: 4.2 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 380 295" role="img" aria-label="两堵墙改变出口选择"><polygon points="20,20 105,20 105,105 20,105" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="105,20 190,20 190,105 105,105" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="190,20 275,20 275,105 190,105" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="275,20 360,20 360,105 275,105" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="20,105 105,105 105,190 20,190" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="105,105 190,105 190,190 105,190" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="190,105 275,105 275,190 190,190" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="275,105 360,105 360,190 275,190" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="105,190 190,190 190,275 105,275" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="190,190 275,190 275,275 190,275" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><line x1="275" y1="115.2" x2="275" y2="179.8" stroke="#272638" stroke-width="8" transform="rotate(0 275 147.5)"/><line x1="275" y1="115.2" x2="275" y2="179.8" stroke="#ffc542" stroke-width="4" stroke-dasharray="5 4" transform="rotate(0 275 147.5)"/><line x1="190" y1="115.2" x2="190" y2="179.8" stroke="#272638" stroke-width="8" transform="rotate(0 190 147.5)"/><line x1="190" y1="115.2" x2="190" y2="179.8" stroke="#ffc542" stroke-width="4" stroke-dasharray="5 4" transform="rotate(0 190 147.5)"/><text x="62.5" y="54.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700"></text><text x="62.5" y="72.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c0</text><text x="147.5" y="54.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700"></text><text x="147.5" y="72.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c1</text><text x="232.5" y="54.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700"></text><text x="232.5" y="72.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c2</text><text x="317.5" y="54.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700"></text><text x="317.5" y="72.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c3</text><text x="62.5" y="139.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">6</text><text x="62.5" y="157.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c4</text><text x="147.5" y="139.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700"></text><text x="147.5" y="157.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c5</text><text x="232.5" y="139.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700"></text><text x="232.5" y="157.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c6</text><text x="317.5" y="139.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">1</text><text x="317.5" y="157.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c7</text><text x="147.5" y="224.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700"></text><text x="147.5" y="242.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c8</text><text x="232.5" y="224.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700"></text><text x="232.5" y="242.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c9</text></svg>
|
||||
|
After Width: | Height: | Size: 3.9 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 380 295" role="img" aria-label="两堵墙改变出口选择"><polygon points="20,20 105,20 105,105 20,105" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="105,20 190,20 190,105 105,105" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="190,20 275,20 275,105 190,105" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="275,20 360,20 360,105 275,105" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="20,105 105,105 105,190 20,190" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="105,105 190,105 190,190 105,190" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="190,105 275,105 275,190 190,190" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="275,105 360,105 360,190 275,190" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="105,190 190,190 190,275 105,275" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="190,190 275,190 275,275 190,275" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polyline points="317.5,147.5 317.5,62.5 232.5,62.5 147.5,62.5 62.5,62.5 62.5,147.5 147.5,147.5 147.5,232.5 232.5,232.5 232.5,147.5" fill="none" stroke="#7963c9" stroke-width="5" opacity=".4"/><line x1="275" y1="115.2" x2="275" y2="179.8" stroke="#272638" stroke-width="8" transform="rotate(0 275 147.5)"/><line x1="275" y1="115.2" x2="275" y2="179.8" stroke="#ffc542" stroke-width="4" stroke-dasharray="5 4" transform="rotate(0 275 147.5)"/><line x1="190" y1="115.2" x2="190" y2="179.8" stroke="#272638" stroke-width="8" transform="rotate(0 190 147.5)"/><line x1="190" y1="115.2" x2="190" y2="179.8" stroke="#ffc542" stroke-width="4" stroke-dasharray="5 4" transform="rotate(0 190 147.5)"/><text x="62.5" y="54.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">5</text><text x="62.5" y="72.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c0</text><text x="147.5" y="54.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">4</text><text x="147.5" y="72.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c1</text><text x="232.5" y="54.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">3</text><text x="232.5" y="72.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c2</text><text x="317.5" y="54.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">2</text><text x="317.5" y="72.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c3</text><text x="62.5" y="139.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">6</text><text x="62.5" y="157.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c4</text><text x="147.5" y="139.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">7</text><text x="147.5" y="157.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c5</text><text x="232.5" y="139.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">10</text><text x="232.5" y="157.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c6</text><text x="317.5" y="139.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">1</text><text x="317.5" y="157.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c7</text><text x="147.5" y="224.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">8</text><text x="147.5" y="242.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c8</text><text x="232.5" y="224.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">9</text><text x="232.5" y="242.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c9</text></svg>
|
||||
|
After Width: | Height: | Size: 4.1 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 380 295" role="img" aria-label="墙与中段数字配合"><polygon points="20,20 105,20 105,105 20,105" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="105,20 190,20 190,105 105,105" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="190,20 275,20 275,105 190,105" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="275,20 360,20 360,105 275,105" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="20,105 105,105 105,190 20,190" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="105,105 190,105 190,190 105,190" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="190,105 275,105 275,190 190,190" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="275,105 360,105 360,190 275,190" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="20,190 105,190 105,275 20,275" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="105,190 190,190 190,275 105,275" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="190,190 275,190 275,275 190,275" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="275,190 360,190 360,275 275,275" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><line x1="190" y1="115.2" x2="190" y2="179.8" stroke="#272638" stroke-width="8" transform="rotate(0 190 147.5)"/><line x1="190" y1="115.2" x2="190" y2="179.8" stroke="#ffc542" stroke-width="4" stroke-dasharray="5 4" transform="rotate(0 190 147.5)"/><line x1="105" y1="115.2" x2="105" y2="179.8" stroke="#272638" stroke-width="8" transform="rotate(0 105 147.5)"/><line x1="105" y1="115.2" x2="105" y2="179.8" stroke="#ffc542" stroke-width="4" stroke-dasharray="5 4" transform="rotate(0 105 147.5)"/><text x="62.5" y="54.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">1</text><text x="62.5" y="72.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c0</text><text x="147.5" y="54.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700"></text><text x="147.5" y="72.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c1</text><text x="232.5" y="54.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700"></text><text x="232.5" y="72.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c2</text><text x="317.5" y="54.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700"></text><text x="317.5" y="72.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c3</text><text x="62.5" y="139.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700"></text><text x="62.5" y="157.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c4</text><text x="147.5" y="139.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700"></text><text x="147.5" y="157.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c5</text><text x="232.5" y="139.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">10</text><text x="232.5" y="157.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c6</text><text x="317.5" y="139.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700"></text><text x="317.5" y="157.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c7</text><text x="62.5" y="224.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700"></text><text x="62.5" y="242.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c8</text><text x="147.5" y="224.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700"></text><text x="147.5" y="242.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c9</text><text x="232.5" y="224.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700"></text><text x="232.5" y="242.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c10</text><text x="317.5" y="224.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700"></text><text x="317.5" y="242.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c11</text></svg>
|
||||
|
After Width: | Height: | Size: 4.5 KiB |
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 380 295" role="img" aria-label="墙与中段数字配合"><polygon points="20,20 105,20 105,105 20,105" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="105,20 190,20 190,105 105,105" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="190,20 275,20 275,105 190,105" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="275,20 360,20 360,105 275,105" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="20,105 105,105 105,190 20,190" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="105,105 190,105 190,190 105,190" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="190,105 275,105 275,190 190,190" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="275,105 360,105 360,190 275,190" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="20,190 105,190 105,275 20,275" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="105,190 190,190 190,275 105,275" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="190,190 275,190 275,275 190,275" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polygon points="275,190 360,190 360,275 275,275" fill="#f1eef9" stroke="#aaa1c7" stroke-width="2"/><polyline points="62.5,62.5 62.5,147.5 62.5,232.5 147.5,232.5 147.5,147.5 147.5,62.5 232.5,62.5 317.5,62.5 317.5,147.5 232.5,147.5 232.5,232.5 317.5,232.5" fill="none" stroke="#7963c9" stroke-width="5" opacity=".4"/><line x1="190" y1="115.2" x2="190" y2="179.8" stroke="#272638" stroke-width="8" transform="rotate(0 190 147.5)"/><line x1="190" y1="115.2" x2="190" y2="179.8" stroke="#ffc542" stroke-width="4" stroke-dasharray="5 4" transform="rotate(0 190 147.5)"/><line x1="105" y1="115.2" x2="105" y2="179.8" stroke="#272638" stroke-width="8" transform="rotate(0 105 147.5)"/><line x1="105" y1="115.2" x2="105" y2="179.8" stroke="#ffc542" stroke-width="4" stroke-dasharray="5 4" transform="rotate(0 105 147.5)"/><text x="62.5" y="54.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">1</text><text x="62.5" y="72.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c0</text><text x="147.5" y="54.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">6</text><text x="147.5" y="72.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c1</text><text x="232.5" y="54.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">7</text><text x="232.5" y="72.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c2</text><text x="317.5" y="54.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">8</text><text x="317.5" y="72.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c3</text><text x="62.5" y="139.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">2</text><text x="62.5" y="157.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c4</text><text x="147.5" y="139.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">5</text><text x="147.5" y="157.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c5</text><text x="232.5" y="139.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">10</text><text x="232.5" y="157.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c6</text><text x="317.5" y="139.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">9</text><text x="317.5" y="157.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c7</text><text x="62.5" y="224.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">3</text><text x="62.5" y="242.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c8</text><text x="147.5" y="224.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">4</text><text x="147.5" y="242.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c9</text><text x="232.5" y="224.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">11</text><text x="232.5" y="242.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c10</text><text x="317.5" y="224.5" text-anchor="middle" font-family="system-ui,Microsoft YaHei" font-size="21" font-weight="700">12</text><text x="317.5" y="242.5" text-anchor="middle" font-family="system-ui" font-size="10" fill="#665c78">c11</text></svg>
|
||||
|
After Width: | Height: | Size: 4.8 KiB |
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 5.7 KiB |
|
After Width: | Height: | Size: 6.1 KiB |
|
After Width: | Height: | Size: 6.4 KiB |
|
After Width: | Height: | Size: 6.9 KiB |
|
After Width: | Height: | Size: 7.1 KiB |
|
After Width: | Height: | Size: 7.2 KiB |
|
After Width: | Height: | Size: 7.4 KiB |
@@ -0,0 +1,191 @@
|
||||
# 永久墙壁
|
||||
|
||||
每格一次,数字必须踩在对应步。黑黄墙封住两格之间的一条共边,整局不会打开,必须绕开。墙不占格,也不是开关。
|
||||
|
||||
固定数字表示必须在该步到达;每格一次、共边移动、完整路线唯一。所有关卡开放。
|
||||
|
||||
这些是机制验证候选关,难度标签按设计任务编排,尚未经真人校准。
|
||||
|
||||
## 01 · 入门 · 认识共边上的永久墙
|
||||
|
||||
格数 6;基础完整路线 16 条;新约束 1 项。
|
||||
|
||||
作者解:c2 → c5 → c4 → c3 → c0 → c1。
|
||||
|
||||
推理检查点:
|
||||
|
||||
- 永久墙 c1—c2 断开表面邻接,需绕行
|
||||
|
||||
关键分叉:第 2 步应选 c5,解除机制后的诱惑路线选择 c1。排除依据:永久墙不能穿过。
|
||||
|
||||
诱惑路线:c2 → c1 → c0 → c3 → c4 → c5。这是符合几何与辅助数字的完整路线,由新机制排除。
|
||||
|
||||
逐项必要性证据:
|
||||
|
||||
- 解除 wall:0 后可走 c2 → c1 → c0 → c3 → c4 → c5
|
||||
|
||||
人工评审:请先隐藏作者解,依据盘面复述排除理由;记录是否主要依靠试错。
|
||||
|
||||
## 02 · 入门 · 近在旁边也要绕墙
|
||||
|
||||
格数 8;基础完整路线 24 条;新约束 1 项。
|
||||
|
||||
作者解:c2 → c5 → c4 → c1 → c0 → c3 → c6 → c7。
|
||||
|
||||
推理检查点:
|
||||
|
||||
- 永久墙 c4—c7 断开表面邻接,需绕行
|
||||
|
||||
关键分叉:第 4 步应选 c1,解除机制后的诱惑路线选择 c7。排除依据:永久墙不能穿过。
|
||||
|
||||
诱惑路线:c2 → c5 → c4 → c7 → c6 → c3 → c0 → c1。这是符合几何与辅助数字的完整路线,由新机制排除。
|
||||
|
||||
逐项必要性证据:
|
||||
|
||||
- 解除 wall:0 后可走 c2 → c5 → c4 → c7 → c6 → c3 → c0 → c1
|
||||
|
||||
人工评审:请先隐藏作者解,依据盘面复述排除理由;记录是否主要依靠试错。
|
||||
|
||||
## 03 · 普通 · 两堵墙改变出口选择
|
||||
|
||||
格数 10;基础完整路线 34 条;新约束 2 项。
|
||||
|
||||
作者解:c7 → c3 → c2 → c1 → c0 → c4 → c5 → c8 → c9 → c6。
|
||||
|
||||
推理检查点:
|
||||
|
||||
- 永久墙 c6—c7 断开表面邻接,需绕行
|
||||
- 永久墙 c5—c6 断开表面邻接,需绕行
|
||||
|
||||
关键分叉:第 2 步应选 c3,解除机制后的诱惑路线选择 c6。排除依据:永久墙不能穿过。
|
||||
|
||||
诱惑路线:c7 → c6 → c9 → c8 → c5 → c4 → c0 → c1 → c2 → c3。这是符合几何与辅助数字的完整路线,由新机制排除。
|
||||
|
||||
逐项必要性证据:
|
||||
|
||||
- 解除 wall:0 后可走 c7 → c6 → c9 → c8 → c5 → c4 → c0 → c1 → c2 → c3
|
||||
- 解除 wall:1 后可走 c7 → c3 → c2 → c1 → c0 → c4 → c5 → c6 → c9 → c8
|
||||
|
||||
人工评审:请先隐藏作者解,依据盘面复述排除理由;记录是否主要依靠试错。
|
||||
|
||||
## 04 · 普通 · 墙与中段数字配合
|
||||
|
||||
格数 12;基础完整路线 124 条;新约束 2 项。
|
||||
|
||||
作者解:c0 → c4 → c8 → c9 → c5 → c1 → c2 → c3 → c7 → c6 → c10 → c11。
|
||||
|
||||
推理检查点:
|
||||
|
||||
- 永久墙 c5—c6 断开表面邻接,需绕行
|
||||
- 永久墙 c4—c5 断开表面邻接,需绕行
|
||||
|
||||
关键分叉:第 5 步应选 c5,解除机制后的诱惑路线选择 c10。排除依据:永久墙不能穿过。
|
||||
|
||||
诱惑路线:c0 → c4 → c8 → c9 → c10 → c11 → c7 → c3 → c2 → c6 → c5 → c1。这是符合几何与辅助数字的完整路线,由新机制排除。
|
||||
|
||||
逐项必要性证据:
|
||||
|
||||
- 解除 wall:0 后可走 c0 → c4 → c8 → c9 → c10 → c11 → c7 → c3 → c2 → c6 → c5 → c1
|
||||
- 解除 wall:1 后可走 c0 → c1 → c5 → c4 → c8 → c9 → c10 → c11 → c7 → c6 → c2 → c3
|
||||
|
||||
人工评审:请先隐藏作者解,依据盘面复述排除理由;记录是否主要依靠试错。
|
||||
|
||||
## 05 · 进阶 · 多墙留下区域通口
|
||||
|
||||
格数 14;基础完整路线 100 条;新约束 3 项。
|
||||
|
||||
作者解:c11 → c7 → c3 → c2 → c6 → c10 → c13 → c12 → c9 → c8 → c4 → c0 → c1 → c5。
|
||||
|
||||
推理检查点:
|
||||
|
||||
- 永久墙 c5—c6 断开表面邻接,需绕行
|
||||
- 永久墙 c5—c9 断开表面邻接,需绕行
|
||||
- 永久墙 c4—c5 断开表面邻接,需绕行
|
||||
|
||||
关键分叉:第 5 步应选 c6,解除机制后的诱惑路线选择 c1。排除依据:永久墙不能穿过。
|
||||
|
||||
诱惑路线:c11 → c7 → c3 → c2 → c1 → c0 → c4 → c8 → c9 → c12 → c13 → c10 → c6 → c5。这是符合几何与辅助数字的完整路线,由新机制排除。
|
||||
|
||||
逐项必要性证据:
|
||||
|
||||
- 解除 wall:0 后可走 c11 → c7 → c3 → c2 → c1 → c0 → c4 → c8 → c9 → c12 → c13 → c10 → c6 → c5
|
||||
- 解除 wall:1 后可走 c11 → c7 → c3 → c2 → c6 → c10 → c13 → c12 → c9 → c5 → c1 → c0 → c4 → c8
|
||||
- 解除 wall:2 后可走 c11 → c7 → c3 → c2 → c6 → c10 → c13 → c12 → c9 → c8 → c4 → c5 → c1 → c0
|
||||
|
||||
人工评审:请先隐藏作者解,依据盘面复述排除理由;记录是否主要依靠试错。
|
||||
|
||||
## 06 · 进阶 · 先收尾,再绕墙跨区
|
||||
|
||||
格数 16;基础完整路线 552 条;新约束 3 项。
|
||||
|
||||
作者解:c12 → c13 → c14 → c15 → c11 → c10 → c9 → c8 → c4 → c0 → c1 → c5 → c6 → c2 → c3 → c7。
|
||||
|
||||
推理检查点:
|
||||
|
||||
- 永久墙 c5—c9 断开表面邻接,需绕行
|
||||
- 永久墙 c4—c5 断开表面邻接,需绕行
|
||||
- 永久墙 c6—c7 断开表面邻接,需绕行
|
||||
|
||||
关键分叉:第 4 步应选 c15,解除机制后的诱惑路线选择 c10。排除依据:永久墙不能穿过。
|
||||
|
||||
诱惑路线:c12 → c13 → c14 → c10 → c6 → c5 → c9 → c8 → c4 → c0 → c1 → c2 → c3 → c7 → c11 → c15。这是符合几何与辅助数字的完整路线,由新机制排除。
|
||||
|
||||
逐项必要性证据:
|
||||
|
||||
- 解除 wall:0 后可走 c12 → c13 → c14 → c10 → c6 → c5 → c9 → c8 → c4 → c0 → c1 → c2 → c3 → c7 → c11 → c15
|
||||
- 解除 wall:1 后可走 c12 → c8 → c9 → c13 → c14 → c10 → c6 → c5 → c4 → c0 → c1 → c2 → c3 → c7 → c11 → c15
|
||||
- 解除 wall:2 后可走 c12 → c13 → c14 → c15 → c11 → c10 → c9 → c8 → c4 → c0 → c1 → c5 → c6 → c7 → c3 → c2
|
||||
|
||||
人工评审:请先隐藏作者解,依据盘面复述排除理由;记录是否主要依靠试错。
|
||||
|
||||
## 07 · 难 · 多区域墙壁与步号联动
|
||||
|
||||
格数 18;基础完整路线 464 条;新约束 4 项。
|
||||
|
||||
作者解:c17 → c16 → c13 → c14 → c15 → c11 → c7 → c3 → c2 → c6 → c10 → c9 → c5 → c1 → c0 → c4 → c8 → c12。
|
||||
|
||||
推理检查点:
|
||||
|
||||
- 永久墙 c4—c5 断开表面邻接,需绕行
|
||||
- 永久墙 c6—c7 断开表面邻接,需绕行
|
||||
- 永久墙 c12—c13 断开表面邻接,需绕行
|
||||
- 永久墙 c10—c14 断开表面邻接,需绕行
|
||||
|
||||
关键分叉:第 10 步应选 c6,解除机制后的诱惑路线选择 c1。排除依据:永久墙不能穿过。
|
||||
|
||||
诱惑路线:c17 → c16 → c13 → c14 → c15 → c11 → c7 → c3 → c2 → c1 → c0 → c4 → c5 → c6 → c10 → c9 → c8 → c12。这是符合几何与辅助数字的完整路线,由新机制排除。
|
||||
|
||||
逐项必要性证据:
|
||||
|
||||
- 解除 wall:0 后可走 c17 → c16 → c13 → c14 → c15 → c11 → c7 → c3 → c2 → c1 → c0 → c4 → c5 → c6 → c10 → c9 → c8 → c12
|
||||
- 解除 wall:1 后可走 c17 → c16 → c13 → c14 → c15 → c11 → c10 → c9 → c5 → c6 → c7 → c3 → c2 → c1 → c0 → c4 → c8 → c12
|
||||
- 解除 wall:2 后可走 c17 → c16 → c13 → c12 → c8 → c4 → c0 → c1 → c5 → c9 → c10 → c6 → c2 → c3 → c7 → c11 → c15 → c14
|
||||
- 解除 wall:3 后可走 c17 → c16 → c13 → c9 → c5 → c6 → c10 → c14 → c15 → c11 → c7 → c3 → c2 → c1 → c0 → c4 → c8 → c12
|
||||
|
||||
人工评审:请先隐藏作者解,依据盘面复述排除理由;记录是否主要依靠试错。
|
||||
|
||||
## 08 · 难 · 起点未知:墙与数字共同定路
|
||||
|
||||
格数 19;基础完整路线 544 条;新约束 4 项。
|
||||
|
||||
作者解:c10 → c6 → c5 → c4 → c0 → c1 → c2 → c3 → c7 → c11 → c15 → c14 → c13 → c9 → c8 → c12 → c16 → c17 → c18。
|
||||
|
||||
推理检查点:
|
||||
|
||||
- 永久墙 c10—c11 断开表面邻接,需绕行
|
||||
- 永久墙 c12—c13 断开表面邻接,需绕行
|
||||
- 永久墙 c10—c14 断开表面邻接,需绕行
|
||||
- 永久墙 c9—c10 断开表面邻接,需绕行
|
||||
|
||||
关键分叉:第 1 步应选 c10,解除机制后的诱惑路线选择 c0。排除依据:永久墙不能穿过。
|
||||
|
||||
诱惑路线:c0 → c1 → c2 → c3 → c7 → c6 → c10 → c11 → c15 → c14 → c18 → c17 → c13 → c9 → c5 → c4 → c8 → c12 → c16。这是符合几何与辅助数字的完整路线,由新机制排除。
|
||||
|
||||
逐项必要性证据:
|
||||
|
||||
- 解除 wall:0 后可走 c0 → c1 → c2 → c3 → c7 → c6 → c10 → c11 → c15 → c14 → c18 → c17 → c13 → c9 → c5 → c4 → c8 → c12 → c16
|
||||
- 解除 wall:1 后可走 c0 → c1 → c2 → c3 → c7 → c11 → c15 → c14 → c18 → c17 → c16 → c12 → c13 → c9 → c8 → c4 → c5 → c6 → c10
|
||||
- 解除 wall:2 后可走 c15 → c11 → c7 → c3 → c2 → c1 → c0 → c4 → c5 → c6 → c10 → c14 → c13 → c9 → c8 → c12 → c16 → c17 → c18
|
||||
- 解除 wall:3 后可走 c15 → c11 → c7 → c3 → c2 → c1 → c0 → c4 → c5 → c6 → c10 → c9 → c13 → c14 → c18 → c17 → c16 → c12 → c8
|
||||
|
||||
人工评审:请先隐藏作者解,依据盘面复述排除理由;记录是否主要依靠试错。
|
||||
@@ -0,0 +1,916 @@
|
||||
{
|
||||
"mode": "walls",
|
||||
"title": "永久墙壁",
|
||||
"rule": "每格一次,数字必须踩在对应步。黑黄墙封住两格之间的一条共边,整局不会打开,必须绕开。墙不占格,也不是开关。",
|
||||
"levels": [
|
||||
{
|
||||
"id": "01",
|
||||
"mode": "walls",
|
||||
"geometry": "square",
|
||||
"difficulty": "入门",
|
||||
"title": "认识共边上的永久墙",
|
||||
"caption": "每格一次,数字必须踩在对应步。黑黄墙封住两格之间的一条共边,整局不会打开,必须绕开。墙不占格,也不是开关。",
|
||||
"cells": [
|
||||
{
|
||||
"id": "c0",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c1",
|
||||
"x": 1,
|
||||
"y": 0,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c2",
|
||||
"x": 2,
|
||||
"y": 0,
|
||||
"w": 1,
|
||||
"h": 1,
|
||||
"clue": 1
|
||||
},
|
||||
{
|
||||
"id": "c3",
|
||||
"x": 0,
|
||||
"y": 1,
|
||||
"w": 1,
|
||||
"h": 1,
|
||||
"clue": 4
|
||||
},
|
||||
{
|
||||
"id": "c4",
|
||||
"x": 1,
|
||||
"y": 1,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c5",
|
||||
"x": 2,
|
||||
"y": 1,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
}
|
||||
],
|
||||
"walls": [
|
||||
[
|
||||
"c1",
|
||||
"c2"
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "02",
|
||||
"mode": "walls",
|
||||
"geometry": "square",
|
||||
"difficulty": "入门",
|
||||
"title": "近在旁边也要绕墙",
|
||||
"caption": "每格一次,数字必须踩在对应步。黑黄墙封住两格之间的一条共边,整局不会打开,必须绕开。墙不占格,也不是开关。",
|
||||
"cells": [
|
||||
{
|
||||
"id": "c0",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c1",
|
||||
"x": 1,
|
||||
"y": 0,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c2",
|
||||
"x": 2,
|
||||
"y": 0,
|
||||
"w": 1,
|
||||
"h": 1,
|
||||
"clue": 1
|
||||
},
|
||||
{
|
||||
"id": "c3",
|
||||
"x": 0,
|
||||
"y": 1,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c4",
|
||||
"x": 1,
|
||||
"y": 1,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c5",
|
||||
"x": 2,
|
||||
"y": 1,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c6",
|
||||
"x": 0,
|
||||
"y": 2,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c7",
|
||||
"x": 1,
|
||||
"y": 2,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
}
|
||||
],
|
||||
"walls": [
|
||||
[
|
||||
"c4",
|
||||
"c7"
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "03",
|
||||
"mode": "walls",
|
||||
"geometry": "square",
|
||||
"difficulty": "普通",
|
||||
"title": "两堵墙改变出口选择",
|
||||
"caption": "",
|
||||
"cells": [
|
||||
{
|
||||
"id": "c0",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c1",
|
||||
"x": 1,
|
||||
"y": 0,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c2",
|
||||
"x": 2,
|
||||
"y": 0,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c3",
|
||||
"x": 3,
|
||||
"y": 0,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c4",
|
||||
"x": 0,
|
||||
"y": 1,
|
||||
"w": 1,
|
||||
"h": 1,
|
||||
"clue": 6
|
||||
},
|
||||
{
|
||||
"id": "c5",
|
||||
"x": 1,
|
||||
"y": 1,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c6",
|
||||
"x": 2,
|
||||
"y": 1,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c7",
|
||||
"x": 3,
|
||||
"y": 1,
|
||||
"w": 1,
|
||||
"h": 1,
|
||||
"clue": 1
|
||||
},
|
||||
{
|
||||
"id": "c8",
|
||||
"x": 1,
|
||||
"y": 2,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c9",
|
||||
"x": 2,
|
||||
"y": 2,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
}
|
||||
],
|
||||
"walls": [
|
||||
[
|
||||
"c6",
|
||||
"c7"
|
||||
],
|
||||
[
|
||||
"c5",
|
||||
"c6"
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "04",
|
||||
"mode": "walls",
|
||||
"geometry": "square",
|
||||
"difficulty": "普通",
|
||||
"title": "墙与中段数字配合",
|
||||
"caption": "",
|
||||
"cells": [
|
||||
{
|
||||
"id": "c0",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 1,
|
||||
"h": 1,
|
||||
"clue": 1
|
||||
},
|
||||
{
|
||||
"id": "c1",
|
||||
"x": 1,
|
||||
"y": 0,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c2",
|
||||
"x": 2,
|
||||
"y": 0,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c3",
|
||||
"x": 3,
|
||||
"y": 0,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c4",
|
||||
"x": 0,
|
||||
"y": 1,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c5",
|
||||
"x": 1,
|
||||
"y": 1,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c6",
|
||||
"x": 2,
|
||||
"y": 1,
|
||||
"w": 1,
|
||||
"h": 1,
|
||||
"clue": 10
|
||||
},
|
||||
{
|
||||
"id": "c7",
|
||||
"x": 3,
|
||||
"y": 1,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c8",
|
||||
"x": 0,
|
||||
"y": 2,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c9",
|
||||
"x": 1,
|
||||
"y": 2,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c10",
|
||||
"x": 2,
|
||||
"y": 2,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c11",
|
||||
"x": 3,
|
||||
"y": 2,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
}
|
||||
],
|
||||
"walls": [
|
||||
[
|
||||
"c5",
|
||||
"c6"
|
||||
],
|
||||
[
|
||||
"c4",
|
||||
"c5"
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "05",
|
||||
"mode": "walls",
|
||||
"geometry": "square",
|
||||
"difficulty": "进阶",
|
||||
"title": "多墙留下区域通口",
|
||||
"caption": "",
|
||||
"cells": [
|
||||
{
|
||||
"id": "c0",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c1",
|
||||
"x": 1,
|
||||
"y": 0,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c2",
|
||||
"x": 2,
|
||||
"y": 0,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c3",
|
||||
"x": 3,
|
||||
"y": 0,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c4",
|
||||
"x": 0,
|
||||
"y": 1,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c5",
|
||||
"x": 1,
|
||||
"y": 1,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c6",
|
||||
"x": 2,
|
||||
"y": 1,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c7",
|
||||
"x": 3,
|
||||
"y": 1,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c8",
|
||||
"x": 0,
|
||||
"y": 2,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c9",
|
||||
"x": 1,
|
||||
"y": 2,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c10",
|
||||
"x": 2,
|
||||
"y": 2,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c11",
|
||||
"x": 3,
|
||||
"y": 2,
|
||||
"w": 1,
|
||||
"h": 1,
|
||||
"clue": 1
|
||||
},
|
||||
{
|
||||
"id": "c12",
|
||||
"x": 1,
|
||||
"y": 3,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c13",
|
||||
"x": 2,
|
||||
"y": 3,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
}
|
||||
],
|
||||
"walls": [
|
||||
[
|
||||
"c5",
|
||||
"c6"
|
||||
],
|
||||
[
|
||||
"c5",
|
||||
"c9"
|
||||
],
|
||||
[
|
||||
"c4",
|
||||
"c5"
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "06",
|
||||
"mode": "walls",
|
||||
"geometry": "square",
|
||||
"difficulty": "进阶",
|
||||
"title": "先收尾,再绕墙跨区",
|
||||
"caption": "",
|
||||
"cells": [
|
||||
{
|
||||
"id": "c0",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c1",
|
||||
"x": 1,
|
||||
"y": 0,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c2",
|
||||
"x": 2,
|
||||
"y": 0,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c3",
|
||||
"x": 3,
|
||||
"y": 0,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c4",
|
||||
"x": 0,
|
||||
"y": 1,
|
||||
"w": 1,
|
||||
"h": 1,
|
||||
"clue": 9
|
||||
},
|
||||
{
|
||||
"id": "c5",
|
||||
"x": 1,
|
||||
"y": 1,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c6",
|
||||
"x": 2,
|
||||
"y": 1,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c7",
|
||||
"x": 3,
|
||||
"y": 1,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c8",
|
||||
"x": 0,
|
||||
"y": 2,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c9",
|
||||
"x": 1,
|
||||
"y": 2,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c10",
|
||||
"x": 2,
|
||||
"y": 2,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c11",
|
||||
"x": 3,
|
||||
"y": 2,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c12",
|
||||
"x": 0,
|
||||
"y": 3,
|
||||
"w": 1,
|
||||
"h": 1,
|
||||
"clue": 1
|
||||
},
|
||||
{
|
||||
"id": "c13",
|
||||
"x": 1,
|
||||
"y": 3,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c14",
|
||||
"x": 2,
|
||||
"y": 3,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c15",
|
||||
"x": 3,
|
||||
"y": 3,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
}
|
||||
],
|
||||
"walls": [
|
||||
[
|
||||
"c5",
|
||||
"c9"
|
||||
],
|
||||
[
|
||||
"c4",
|
||||
"c5"
|
||||
],
|
||||
[
|
||||
"c6",
|
||||
"c7"
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "07",
|
||||
"mode": "walls",
|
||||
"geometry": "square",
|
||||
"difficulty": "难",
|
||||
"title": "多区域墙壁与步号联动",
|
||||
"caption": "",
|
||||
"cells": [
|
||||
{
|
||||
"id": "c0",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c1",
|
||||
"x": 1,
|
||||
"y": 0,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c2",
|
||||
"x": 2,
|
||||
"y": 0,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c3",
|
||||
"x": 3,
|
||||
"y": 0,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c4",
|
||||
"x": 0,
|
||||
"y": 1,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c5",
|
||||
"x": 1,
|
||||
"y": 1,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c6",
|
||||
"x": 2,
|
||||
"y": 1,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c7",
|
||||
"x": 3,
|
||||
"y": 1,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c8",
|
||||
"x": 0,
|
||||
"y": 2,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c9",
|
||||
"x": 1,
|
||||
"y": 2,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c10",
|
||||
"x": 2,
|
||||
"y": 2,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c11",
|
||||
"x": 3,
|
||||
"y": 2,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c12",
|
||||
"x": 0,
|
||||
"y": 3,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c13",
|
||||
"x": 1,
|
||||
"y": 3,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c14",
|
||||
"x": 2,
|
||||
"y": 3,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c15",
|
||||
"x": 3,
|
||||
"y": 3,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c16",
|
||||
"x": 1,
|
||||
"y": 4,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c17",
|
||||
"x": 2,
|
||||
"y": 4,
|
||||
"w": 1,
|
||||
"h": 1,
|
||||
"clue": 1
|
||||
}
|
||||
],
|
||||
"walls": [
|
||||
[
|
||||
"c4",
|
||||
"c5"
|
||||
],
|
||||
[
|
||||
"c6",
|
||||
"c7"
|
||||
],
|
||||
[
|
||||
"c12",
|
||||
"c13"
|
||||
],
|
||||
[
|
||||
"c10",
|
||||
"c14"
|
||||
]
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "08",
|
||||
"mode": "walls",
|
||||
"geometry": "square",
|
||||
"difficulty": "难",
|
||||
"title": "起点未知:墙与数字共同定路",
|
||||
"caption": "",
|
||||
"cells": [
|
||||
{
|
||||
"id": "c0",
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c1",
|
||||
"x": 1,
|
||||
"y": 0,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c2",
|
||||
"x": 2,
|
||||
"y": 0,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c3",
|
||||
"x": 3,
|
||||
"y": 0,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c4",
|
||||
"x": 0,
|
||||
"y": 1,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c5",
|
||||
"x": 1,
|
||||
"y": 1,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c6",
|
||||
"x": 2,
|
||||
"y": 1,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c7",
|
||||
"x": 3,
|
||||
"y": 1,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c8",
|
||||
"x": 0,
|
||||
"y": 2,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c9",
|
||||
"x": 1,
|
||||
"y": 2,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c10",
|
||||
"x": 2,
|
||||
"y": 2,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c11",
|
||||
"x": 3,
|
||||
"y": 2,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c12",
|
||||
"x": 0,
|
||||
"y": 3,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c13",
|
||||
"x": 1,
|
||||
"y": 3,
|
||||
"w": 1,
|
||||
"h": 1,
|
||||
"clue": 13
|
||||
},
|
||||
{
|
||||
"id": "c14",
|
||||
"x": 2,
|
||||
"y": 3,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c15",
|
||||
"x": 3,
|
||||
"y": 3,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c16",
|
||||
"x": 0,
|
||||
"y": 4,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c17",
|
||||
"x": 1,
|
||||
"y": 4,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
},
|
||||
{
|
||||
"id": "c18",
|
||||
"x": 2,
|
||||
"y": 4,
|
||||
"w": 1,
|
||||
"h": 1
|
||||
}
|
||||
],
|
||||
"walls": [
|
||||
[
|
||||
"c10",
|
||||
"c11"
|
||||
],
|
||||
[
|
||||
"c12",
|
||||
"c13"
|
||||
],
|
||||
[
|
||||
"c10",
|
||||
"c14"
|
||||
],
|
||||
[
|
||||
"c9",
|
||||
"c10"
|
||||
]
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
// Pure rules / geometry / solver. Each mode receives its own standalone copy.
|
||||
export function units(c){return c.shape?c.shape.map(([x,y])=>[c.x+x,c.y+y]):Array.from({length:(c.w||1)*(c.h||1)},(_,i)=>[c.x+i%(c.w||1),c.y+Math.floor(i/(c.w||1))]);}
|
||||
export function graph(level){
|
||||
const cells=level.cells, ids=new Map(cells.map((c,i)=>[c.id,i]));
|
||||
if(ids.size!==cells.length)throw Error('重复格 id');
|
||||
const adj=cells.map(()=>[]), occupancy=new Map();
|
||||
if(level.geometry!=='hex') for(let i=0;i<cells.length;i++)for(const [x,y]of units(cells[i])){const k=x+','+y;if(occupancy.has(k))throw Error('拼块重叠');occupancy.set(k,i);}
|
||||
for(let i=0;i<cells.length;i++)for(let j=i+1;j<cells.length;j++){
|
||||
let connected=false;
|
||||
if(level.geometry==='hex'){let dq=cells[j].q-cells[i].q,dr=cells[j].r-cells[i].r;connected=[[1,0],[-1,0],[0,1],[0,-1],[1,-1],[-1,1]].some(([a,b])=>a===dq&&b===dr);}
|
||||
else connected=units(cells[i]).some(([x,y])=>[[1,0],[-1,0],[0,1],[0,-1]].some(([a,b])=>occupancy.get((x+a)+','+(y+b))===j));
|
||||
if(connected){adj[i].push(j);adj[j].push(i);}
|
||||
}
|
||||
const clues=new Map();for(const c of cells)if(c.clue!==undefined){if(!Number.isInteger(c.clue)||c.clue<1||c.clue>cells.length||clues.has(c.clue))throw Error('数字范围或重复');clues.set(c.clue,ids.get(c.id));}
|
||||
return {cells,ids,adj,clues};
|
||||
}
|
||||
export function constraints(level){
|
||||
const result=[];
|
||||
for(let i=0;i<(level.relations||[]).length;i++)result.push({key:'relation:'+i,kind:'relation',...level.relations[i]});
|
||||
for(let i=0;i<(level.orderChains||[]).length;i++)for(let j=0;j<level.orderChains[i].length-1;j++)result.push({key:'order:'+i+':'+j,kind:'order',from:level.orderChains[i][j],to:level.orderChains[i][j+1]});
|
||||
for(let i=0;i<(level.windows||[]).length;i++)result.push({key:'window:'+i,kind:'window',...level.windows[i]});
|
||||
for(const c of level.cells)if(c.direction)result.push({key:'direction:'+c.id,kind:'direction',cell:c.id,value:c.direction});
|
||||
if(level.mode.includes('alternation'))result.push({key:'alternation',kind:'alternation'});
|
||||
for(let i=0;i<(level.walls||[]).length;i++)result.push({key:'wall:'+i,kind:'wall',edge:level.walls[i]});
|
||||
for(let i=0;i<(level.doors||[]).length;i++)result.push({key:'door:'+i,kind:'door',...level.doors[i]});
|
||||
for(let i=0;i<(level.gates||[]).length;i++)result.push({key:'gate:'+i,kind:'gate',...level.gates[i]});
|
||||
return result;
|
||||
}
|
||||
export function directionAt(level,path,k){
|
||||
if(k===0||k===path.length-1)return null;
|
||||
const [a,b,c]=[path[k-1],path[k],path[k+1]].map(id=>level.cells.find(x=>x.id===id));
|
||||
const side=(x)=>x.x<b.x?'l':x.x>b.x?'r':x.y<b.y?'u':'d';
|
||||
return [side(a),side(c)].sort().join('');
|
||||
}
|
||||
export function doorOpen(door,visitedCount){return Boolean(door.initialOpen)!==Boolean(visitedCount%2);}
|
||||
export const directionNames={lr:'左右直行',du:'上下直行',ru:'上与右拐角',dr:'右与下拐角',dl:'下与左拐角',lu:'左与上拐角'};
|
||||
export function edgeBlocked(level,path,a,b,{omit=null}={}){
|
||||
for(let i=0;i<(level.walls||[]).length;i++)if(omit!=='wall:'+i&&level.walls[i].includes(a)&&level.walls[i].includes(b))return true;
|
||||
for(let i=0;i<(level.doors||[]).length;i++)if(omit!=='door:'+i&&level.doors[i].edge.includes(a)&&level.doors[i].edge.includes(b)&&!doorOpen(level.doors[i],path.length))return true;
|
||||
return false;
|
||||
}
|
||||
export function violations(level,path,{omit=null,complete=path.length===level.cells.length,ignoreClues=false}={}){
|
||||
const positions=new Map(path.map((id,i)=>[id,i+1])),bad=[];
|
||||
if(!ignoreClues)for(const c of level.cells)if(c.clue!==undefined){const at=positions.get(c.id);if(at!==undefined&&at!==c.clue||path.length>=c.clue&&path[c.clue-1]!==c.id)bad.push({key:'clue:'+c.id,cells:[c.id,path[c.clue-1]].filter(Boolean),message:'固定数字步号不符'});}
|
||||
for(const r of constraints(level)){
|
||||
if(r.key===omit)continue;
|
||||
let fail=false,where=[];
|
||||
if(r.kind==='relation'){
|
||||
const a=positions.get(r.from),b=positions.get(r.to);where=[r.from,r.to];
|
||||
fail=b!==undefined&&(a===undefined||b-a!==r.delta)||a!==undefined&&b===undefined&&path.length>=a+r.delta;
|
||||
}else if(r.kind==='order'){where=[r.from,r.to];fail=positions.has(r.to)&&(!positions.has(r.from)||positions.get(r.from)>positions.get(r.to));}
|
||||
else if(r.kind==='window'){where=[r.cell];const p=positions.get(r.cell);fail=p!==undefined?(p<r.min||p>r.max):path.length>=r.max;}
|
||||
else if(r.kind==='direction'){where=[r.cell];const p=positions.get(r.cell);fail=p===1||p!==undefined&&p<path.length&&directionAt(level,path,p-1)!==r.value||complete&&p===path.length;}
|
||||
else if(r.kind==='alternation'){for(let i=1;i<path.length;i++){const a=level.cells.find(c=>c.id===path[i-1]),b=level.cells.find(c=>c.id===path[i]);if(a.category===b.category){fail=true;where.push(a.id,b.id);}}}
|
||||
else if(r.kind==='wall'||r.kind==='door')for(let i=1;i<path.length;i++){if(r.edge.includes(path[i-1])&&r.edge.includes(path[i])&&(r.kind==='wall'||!doorOpen(r,i))){fail=true;where=r.edge;}}
|
||||
else if(r.kind==='gate')for(let i=1;i<path.length;i++){if(r.edge.includes(path[i-1])&&r.edge.includes(path[i])){const s=positions.get(r.switchCell);if(s===undefined||s>i){fail=true;where=r.edge;}}}
|
||||
if(fail)bad.push({key:r.key,cells:where,message:r.kind==='relation'?'相对步差不符':r.kind==='order'?'标记次序不符':r.kind==='window'?'到达窗口不符':r.kind==='direction'?'进出方向不符':r.kind==='wall'?'永久墙不能穿过':r.kind==='door'?'这一步门是关闭的':r.kind==='gate'?'开关尚未打开此门':'蓝橙颜色必须交替'});
|
||||
}
|
||||
return bad;
|
||||
}
|
||||
export function canAppend(level,path,id){
|
||||
const g=graph(level);if(path.includes(id)||!g.ids.has(id))return false;
|
||||
if(!path.length)return !g.clues.has(1)||g.cells[g.clues.get(1)].id===id;
|
||||
const last=path.at(-1);if(edgeBlocked(level,path,last,id))return false;if(!g.adj[g.ids.get(last)].includes(g.ids.get(id)))return false;
|
||||
if(level.mode.includes('alternation')&&g.cells[g.ids.get(last)].category===g.cells[g.ids.get(id)].category)return false;
|
||||
for(const gate of level.gates||[])if(gate.edge.includes(last)&&gate.edge.includes(id)&&!path.includes(gate.switchCell))return false;
|
||||
return true;
|
||||
}
|
||||
export function solve(level,{limit=2,omit=null,ignoreClues=false,prune=true,nodeLimit=Infinity}={}){
|
||||
const g=graph(level),n=g.cells.length,results=[],path=[],seen=new Set();let nodes=0;
|
||||
const active=constraints(level).filter(r=>r.key!==omit),alternating=active.some(r=>r.kind==='alternation');
|
||||
const adj=g.adj.map((a,i)=>a.filter(j=>(!alternating||g.cells[i].category!==g.cells[j].category)&&!active.some(r=>r.kind==='wall'&&r.edge.includes(g.cells[i].id)&&r.edge.includes(g.cells[j].id))));
|
||||
const forced=ignoreClues?new Map():g.clues;
|
||||
function connected(cur){const reached=new Set([cur]),queue=[cur];for(let k=0;k<queue.length;k++)for(const j of adj[queue[k]])if(!seen.has(j)&&!reached.has(j)){reached.add(j);queue.push(j);}return reached.size===n-path.length+1;}
|
||||
function visit(i){if(++nodes>nodeLimit)throw Error('求解节点预算耗尽,不能视为唯一');seen.add(i);path.push(g.cells[i].id);
|
||||
const k=path.length;
|
||||
if(!violations(level,path,{omit,ignoreClues}).length){
|
||||
if(k===n)results.push([...path]);
|
||||
else if(!prune||connected(i)){
|
||||
const f=forced.get(k+1);let next=adj[i].filter(j=>!seen.has(j)&&(f===undefined||j===f));
|
||||
next.sort((a,b)=>adj[a].filter(x=>!seen.has(x)).length-adj[b].filter(x=>!seen.has(x)).length);
|
||||
for(const j of next){if(!ignoreClues&&g.cells[j].clue!==undefined&&g.cells[j].clue!==k+1)continue;
|
||||
let blocked=edgeBlocked(level,path,g.cells[i].id,g.cells[j].id,{omit});for(const r of active)if(r.kind==='gate'&&r.edge.includes(g.cells[i].id)&&r.edge.includes(g.cells[j].id)&&!path.includes(r.switchCell))blocked=true;
|
||||
if(!blocked)visit(j);if(results.length>=limit)break;
|
||||
}
|
||||
}
|
||||
}
|
||||
path.pop();seen.delete(i);
|
||||
}
|
||||
let starts=forced.has(1)?[forced.get(1)]:g.cells.map((_,i)=>i);
|
||||
for(const i of starts){if(!ignoreClues&&g.cells[i].clue!==undefined&&g.cells[i].clue!==1)continue;visit(i);if(results.length>=limit)break;}
|
||||
return results;
|
||||
}
|
||||
export function hint(solution,path){let k=0;while(k<path.length&&path[k]===solution[k])k++;if(k<path.length)return {kind:k?'backtrack':'restart',cell:k?path[k-1]:solution[0]};return k===solution.length?{kind:'none'}:{kind:k?'next':'start',cell:solution[k]};}
|
||||
export function assertStructure(level){
|
||||
const g=graph(level),n=g.cells.length;if(n<3||n>20)throw Error('格数须为3–20');
|
||||
if(level.geometry==='hex'){const keys=new Set();for(const c of g.cells){if(!Number.isInteger(c.q)||!Number.isInteger(c.r))throw Error('六边坐标');const key=c.q+','+c.r;if(keys.has(key))throw Error('六边重叠');keys.add(key);}}
|
||||
else for(const c of g.cells){if(!Number.isInteger(c.x)||!Number.isInteger(c.y))throw Error('坐标');const u=units(c);if(!u.length||new Set(u.map(p=>p.join(','))).size!==u.length)throw Error('异形重复');const seen=new Set([u[0].join(',')]);for(let changed=true;changed;){changed=false;for(const [x,y]of u)if(!seen.has(x+','+y)&&[[1,0],[-1,0],[0,1],[0,-1]].some(([a,b])=>seen.has((x+a)+','+(y+b)))){seen.add(x+','+y);changed=true;}}if(seen.size!==u.length)throw Error('异形不连通');}
|
||||
const reach=new Set([0]),queue=[0];for(let k=0;k<queue.length;k++)for(const j of g.adj[queue[k]])if(!reach.has(j)){reach.add(j);queue.push(j);}if(reach.size!==n)throw Error('盘面不连通');
|
||||
if((level.doors||[]).length>1)throw Error('步进门只允许一道门');
|
||||
const physicalEdges=[...(level.walls||[]),...(level.doors||[]).map(d=>d.edge)].map(e=>[...e].sort().join('|'));if(new Set(physicalEdges).size!==physicalEdges.length)throw Error('墙门共边重复');
|
||||
const pairs=[];
|
||||
for(const r of constraints(level)){
|
||||
for(const id of [r.cell,r.from,r.to,r.switchCell,...(r.edge||[])].filter(Boolean))if(!g.ids.has(id))throw Error('约束引用不存在');
|
||||
if(r.kind==='relation'&&(!Number.isInteger(r.delta)||r.delta<1||r.delta>=n||r.from===r.to))throw Error('步差');
|
||||
if(r.kind==='order')pairs.push([r.from,r.to]);
|
||||
if(r.kind==='window'&&(!Number.isInteger(r.min)||!Number.isInteger(r.max)||r.min<1||r.max>n||r.max-r.min<2||g.cells[g.ids.get(r.cell)].clue!==undefined))throw Error('窗口需允许至少两个同奇偶步号且不与数字重叠');
|
||||
if(r.kind==='direction'&&!Object.keys(directionNames).includes(r.value))throw Error('方向');
|
||||
if((r.kind==='wall'||r.kind==='door')&&(r.edge.length!==2||!g.adj[g.ids.get(r.edge[0])].includes(g.ids.get(r.edge[1]))))throw Error('墙或门不在共边');
|
||||
if(r.kind==='gate'&&(r.edge.length!==2||!g.adj[g.ids.get(r.edge[0])].includes(g.ids.get(r.edge[1]))))throw Error('门不在共边');
|
||||
}
|
||||
if((level.gates||[]).length>3||new Set((level.gates||[]).map(r=>r.switchCell)).size!==(level.gates||[]).length)throw Error('最多三门且开关一对一');
|
||||
if(level.mode.includes('alternation')&&g.cells.some(c=>!['circle','triangle'].includes(c.category)))throw Error('缺少类别');
|
||||
function cycle(v,stack=new Set(),done=new Set()){if(stack.has(v))throw Error('先后链循环');if(done.has(v))return;stack.add(v);for(const [a,b]of pairs)if(a===v)cycle(b,stack,done);stack.delete(v);done.add(v);}for(const [a]of pairs)cycle(a);
|
||||
return g;
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
import {graph,units,solve,violations,canAppend,hint,doorOpen,directionNames} from './rules.mjs';
|
||||
// The build embeds this module together with the local rule file and JSON.
|
||||
const pack=PACK;
|
||||
const $=id=>document.getElementById(id),canvas=$('board'),ctx=canvas.getContext('2d');
|
||||
let level,solution,path=[],index=0,selected='入门',polygons=[],centers=new Map(),unit=1,focus=[],drag=false,lastPoint=null,cleared=false;
|
||||
const memoryKey='variant:'+pack.mode;let completed=[];try{completed=JSON.parse(localStorage.getItem(memoryKey)||'[]');}catch{}
|
||||
const labels=new Map();const metrics={};let started=0,record=null;
|
||||
function setStatus(s){$('status').textContent=s;}
|
||||
function modeMarkers(){labels.clear();let ids=[...(level.relations||[]).flatMap(r=>[r.from,r.to]),...(level.orderChains||[]).flat()];for(const id of ids)if(!labels.has(id))labels.set(id,String.fromCharCode(65+labels.size));}
|
||||
function makeRecord(){return {mode:pack.mode,level:level.id,difficulty:level.difficulty,title:level.title,startedAt:new Date().toISOString(),elapsedSeconds:0,firstError:null,backtracks:0,restarts:0,hints:0,completed:false,reasoning:''};}
|
||||
function start(i){index=i;level=pack.levels[i];solution=solve(level)[0];if(!solution)throw Error('没有合法路线');path=[];focus=[];cleared=false;started=performance.now();record=makeRecord();$('reasoning').value='';modeMarkers();$('goal').textContent=level.title;$('caption').textContent=level.caption||'先观察,再画;错了可以退回。';$('title').textContent=pack.title;$('rule-text').textContent=pack.rule;setStatus('从数字 1 开始;没有 1 时,可尝试任意格。');renderConstraints();renderSelectors();draw();}
|
||||
function renderSelectors(){
|
||||
$('difficulties').replaceChildren();for(const d of ['入门','普通','进阶','难']){const b=document.createElement('button');b.textContent=d;b.className=d===selected?'active':'';b.onclick=()=>{selected=d;start(pack.levels.findIndex(l=>l.difficulty===d));};$('difficulties').append(b);}
|
||||
$('levels').replaceChildren();for(let i=0;i<pack.levels.length;i++){const l=pack.levels[i];if(l.difficulty!==selected)continue;const b=document.createElement('button');b.textContent=`第 ${i%2+1} 关${completed.includes(l.id)?' ✓':''}`;b.className=i===index?'active':'';b.onclick=()=>start(i);$('levels').append(b);}
|
||||
$('position').textContent=`${level.difficulty} · ${index%2+1}/2`;
|
||||
}
|
||||
function renderConstraints(){const list=$('constraints');list.replaceChildren();
|
||||
const add=(text,ids)=>{const b=document.createElement('button');b.className='constraint';b.textContent=text;b.onclick=()=>{focus=ids;draw();};list.append(b);};
|
||||
for(const r of level.relations||[])add(`${labels.get(r.from)} → ${labels.get(r.to)} +${r.delta}`,[r.from,r.to]);
|
||||
for(const chain of level.orderChains||[])add(chain.map(id=>labels.get(id)).join(' < '),chain);
|
||||
for(const w of level.windows||[])add(`窗口 ${w.min}–${w.max}`,[w.cell]);
|
||||
for(const c of level.cells)if(c.direction)add(directionNames[c.direction]+' · 可反向',[c.id]);
|
||||
if(level.mode.includes('alternation'))add('🔵 蓝 → 🟠 橙 → 🔵 蓝 · 每步换颜色',[]);
|
||||
for(let i=0;i<(level.walls||[]).length;i++)add('黑黄墙 · 永久封闭',level.walls[i]);
|
||||
for(const d of level.doors||[])add(doorOpen(d,path.length)?'门开 · 再落一格就关':'门关 · 再落一格就开',d.edge);
|
||||
for(let i=0;i<(level.gates||[]).length;i++)add(`开关 ${i+1} → 门 ${i+1}`,[level.gates[i].switchCell,...level.gates[i].edge]);
|
||||
}
|
||||
function localGeometry(){
|
||||
const raw=[],center=new Map();for(const c of level.cells){if(level.geometry==='hex'){
|
||||
// Rotate the axial strip into portrait orientation; adjacency remains axial.
|
||||
const x=1.5*c.r,y=Math.sqrt(3)*(c.q+c.r/2);center.set(c.id,[x,y]);let p=[];for(let a=0;a<6;a++){const angle=a*Math.PI/3;p.push([x+Math.cos(angle),y+Math.sin(angle)]);}raw.push({id:c.id,p});
|
||||
}else{const u=units(c);center.set(c.id,[u.reduce((s,p)=>s+p[0]+.5,0)/u.length,u.reduce((s,p)=>s+p[1]+.5,0)/u.length]);for(const [x,y]of u)raw.push({id:c.id,p:[[x,y],[x+1,y],[x+1,y+1],[x,y+1]]});}}
|
||||
return {raw,center};
|
||||
}
|
||||
function draw(){if(!level)return;const width=canvas.clientWidth,height=canvas.clientHeight,dpr=window.devicePixelRatio||1;canvas.width=Math.round(width*dpr);canvas.height=Math.round(height*dpr);ctx.setTransform(dpr,0,0,dpr,0,0);ctx.clearRect(0,0,width,height);
|
||||
const {raw,center}=localGeometry(),all=raw.flatMap(r=>r.p),xmin=Math.min(...all.map(p=>p[0])),xmax=Math.max(...all.map(p=>p[0])),ymin=Math.min(...all.map(p=>p[1])),ymax=Math.max(...all.map(p=>p[1]));unit=Math.min((width-28)/(xmax-xmin),(height-24)/(ymax-ymin));const ox=(width-unit*(xmax-xmin))/2-unit*xmin,oy=(height-unit*(ymax-ymin))/2-unit*ymin;
|
||||
const tr=([x,y])=>[ox+x*unit,oy+y*unit];polygons=raw.map(r=>({...r,p:r.p.map(tr)}));centers=new Map([...center].map(([id,p])=>[id,tr(p)]));
|
||||
const bad=violations(level,path),badIds=new Set(bad.flatMap(b=>b.cells));
|
||||
for(const shape of polygons){const c=level.cells.find(c=>c.id===shape.id),visited=path.includes(c.id);ctx.beginPath();shape.p.forEach(([x,y],i)=>i?ctx.lineTo(x,y):ctx.moveTo(x,y));ctx.closePath();ctx.fillStyle=c.category==='circle'?'#64acf3':c.category==='triangle'?'#ffae55':badIds.has(c.id)?'#ffe0dc':visited?'#ddd8ff':'#f0f0f6';ctx.fill();}
|
||||
// Draw only external unit edges, preserving the outline of an entire large block.
|
||||
const edgeCounts=new Map();for(const shape of polygons)for(let i=0;i<shape.p.length;i++){let a=shape.p[i],b=shape.p[(i+1)%shape.p.length];let key=shape.id+':'+[a.map(v=>v.toFixed(3)).join(','),b.map(v=>v.toFixed(3)).join(',')].sort().join('|');edgeCounts.set(key,(edgeCounts.get(key)||0)+1);}
|
||||
for(const shape of polygons)for(let i=0;i<shape.p.length;i++){const a=shape.p[i],b=shape.p[(i+1)%shape.p.length],key=shape.id+':'+[a.map(v=>v.toFixed(3)).join(','),b.map(v=>v.toFixed(3)).join(',')].sort().join('|');if(edgeCounts.get(key)>1)continue;ctx.beginPath();ctx.moveTo(...a);ctx.lineTo(...b);ctx.strokeStyle=focus.includes(shape.id)?'#f59c00':badIds.has(shape.id)?'#c74537':path.includes(shape.id)?'#7762db':'#b4b6cb';ctx.lineWidth=focus.includes(shape.id)?4:2;ctx.stroke();}
|
||||
if(path.length){ctx.beginPath();path.forEach((id,i)=>{const p=centers.get(id);i?ctx.lineTo(...p):ctx.moveTo(...p);});ctx.lineWidth=5;ctx.lineCap='round';ctx.lineJoin='round';ctx.strokeStyle='#7562db';ctx.globalAlpha=.32;ctx.stroke();ctx.globalAlpha=1;}
|
||||
for(const edge of level.walls||[])drawBarrier(edge,'wall');
|
||||
for(const d of level.doors||[])drawBarrier(d.edge,doorOpen(d,path.length)?'open':'closed');
|
||||
for(let i=0;i<(level.gates||[]).length;i++){const gate=level.gates[i],a=centers.get(gate.edge[0]),b=centers.get(gate.edge[1]),mx=(a[0]+b[0])/2,my=(a[1]+b[1])/2,dx=b[0]-a[0],dy=b[1]-a[1],len=Math.hypot(dx,dy),open=path.includes(gate.switchCell);ctx.save();ctx.translate(mx,my);ctx.rotate(Math.atan2(dy,dx));ctx.beginPath();ctx.moveTo(0,-unit*.34);ctx.lineTo(0,unit*.34);ctx.lineWidth=7;ctx.strokeStyle=open?'#349375':'#d98123';if(open)ctx.setLineDash([3,5]);ctx.stroke();ctx.restore();ctx.fillStyle=open?'#25745c':'#8c4917';ctx.font='bold 12px system-ui';ctx.textAlign='center';ctx.fillText(String(i+1),mx+9,my-8);}
|
||||
for(const c of level.cells){const [x,y]=centers.get(c.id),step=path.indexOf(c.id)+1;const font=Math.max(14,Math.min(24,unit*.34));let symbol=labels.get(c.id)||'';const w=(level.windows||[]).find(w=>w.cell===c.id);if(w)symbol=`${w.min}–${w.max}`;if(c.direction)symbol='';if(c.category)symbol=c.category==='circle'?'○':'△';const gateIndex=(level.gates||[]).findIndex(g=>g.switchCell===c.id);if(gateIndex!==-1)symbol=`开${gateIndex+1}`;
|
||||
if(c.direction)drawChannel(c.direction,x,y-(step?font*.72:0),Math.min(unit*.28,step?font*.4:20));
|
||||
ctx.textAlign='center';ctx.textBaseline='middle';ctx.fillStyle=badIds.has(c.id)?'#a33127':'#30304e';ctx.font=`700 ${font}px system-ui`;if(step){ctx.fillText(String(step),x,y+ (symbol?5:0));if(symbol){ctx.font=`600 ${Math.max(11,font*.65)}px system-ui`;ctx.fillText(symbol,x,y-font*.65);}}else if(symbol)ctx.fillText(symbol,x,y);
|
||||
if(c.clue!==undefined){if(!step&&!symbol)ctx.fillText(String(c.clue),x,y);else{ctx.font=`700 ${Math.max(11,font*.65)}px system-ui`;ctx.fillText('需'+c.clue,x,y+font*.8);}}
|
||||
}
|
||||
$('remaining').textContent=cleared?'完成 ✓':`剩余 ${level.cells.length-path.length} 格`;
|
||||
if(level.doors?.length)renderConstraints();
|
||||
if(bad.length)setStatus(bad[0].message+',可以点已走格退回。');
|
||||
$('undo').disabled=!path.length;$('next').hidden=!cleared||index===7;
|
||||
}
|
||||
function drawChannel(kind,x,y,r){const vector={l:[-1,0],r:[1,0],u:[0,-1],d:[0,1]};const [a,b]=kind.split('').map(k=>vector[k]);ctx.beginPath();ctx.moveTo(x+a[0]*r,y+a[1]*r);ctx.lineTo(x,y);ctx.lineTo(x+b[0]*r,y+b[1]*r);ctx.lineCap='round';ctx.lineJoin='round';ctx.lineWidth=9;ctx.strokeStyle='#c1daf7';ctx.stroke();ctx.lineWidth=4;ctx.strokeStyle='#15497b';ctx.stroke();}
|
||||
function drawBarrier(edge,kind){const left=polygons.filter(p=>p.id===edge[0]),right=polygons.filter(p=>p.id===edge[1]);let common=null;for(const a of left)for(const b of right)for(let i=0;i<a.p.length;i++)for(let j=0;j<b.p.length;j++){const p=a.p[i],q=a.p[(i+1)%a.p.length],r=b.p[j],t=b.p[(j+1)%b.p.length];if(Math.hypot(p[0]-t[0],p[1]-t[1])<.01&&Math.hypot(q[0]-r[0],q[1]-r[1])<.01)common=[p,q];}if(!common)return;const [a,b]=common;const point=f=>[a[0]+(b[0]-a[0])*f,a[1]+(b[1]-a[1])*f];ctx.lineCap='butt';ctx.lineWidth=9;ctx.strokeStyle=kind==='open'?'#23895f':kind==='wall'?'#272638':'#aa4d25';ctx.beginPath();if(kind==='open'){ctx.moveTo(...point(.05));ctx.lineTo(...point(.26));ctx.moveTo(...point(.74));ctx.lineTo(...point(.95));}else{ctx.moveTo(...point(.05));ctx.lineTo(...point(.95));}ctx.stroke();if(kind==='wall'){ctx.lineWidth=4;ctx.strokeStyle='#ffc542';ctx.setLineDash([5,4]);ctx.beginPath();ctx.moveTo(...point(.05));ctx.lineTo(...point(.95));ctx.stroke();ctx.setLineDash([]);}if(kind!=='wall'){const [x,y]=point(.5);ctx.font='700 11px system-ui';ctx.textAlign='center';ctx.fillStyle=kind==='open'?'#12623f':'#993b1e';ctx.fillText(kind==='open'?'开':'关',x+10,y-8);}}
|
||||
function inside(x,y,p){let hit=false;for(let i=0,j=p.length-1;i<p.length;j=i++){const [a,b]=p[i],[c,d]=p[j];if((b>y)!==(d>y)&&x<(c-a)*(y-b)/(d-b)+a)hit=!hit;}return hit;}
|
||||
function hit(x,y){return polygons.find(s=>inside(x,y,s.p))?.id;}
|
||||
function markError(id,message){if(!record.firstError)record.firstError={step:path.length+1,cell:id,message};setStatus(message);}
|
||||
function advance(id){if(!id||cleared)return;const at=path.indexOf(id);if(at!==-1){if(at<path.length-1){record.backtracks++;path=path.slice(0,at+1);focus=[];setStatus('已回退,继续观察剩余格。');draw();}return;}
|
||||
if(!canAppend(level,path,id)){const g=graph(level),adjacent=path.length&&g.adj[g.ids.get(path.at(-1))].includes(g.ids.get(id));if(adjacent||!path.length){markError(id,path.length?(level.walls?.some(e=>e.includes(path.at(-1))&&e.includes(id))?'这是永久墙,不能穿过。':level.doors?.some(d=>d.edge.includes(path.at(-1))&&d.edge.includes(id))?'门现在关闭;绕行落格后会切换。':'同色格不能连续经过,请换另一种颜色。'):'请从数字 1 开始。');}return;}
|
||||
if(!path.length)started=performance.now();path.push(id);focus=[];const bad=violations(level,path);if(bad.length)markError(id,bad[0].message);else setStatus('可松手续画;点已走格可回退。');if(path.length===level.cells.length&&!bad.length){cleared=true;record.completed=true;record.elapsedSeconds=Math.round((performance.now()-started)/1000);if(!completed.includes(level.id)){completed.push(level.id);try{localStorage.setItem(memoryKey,JSON.stringify(completed));}catch{}}setStatus('完成!可以进入下一关,或记录你的推理。');renderSelectors();}draw();}
|
||||
function point(e){const r=canvas.getBoundingClientRect();return [e.clientX-r.left,e.clientY-r.top];}
|
||||
canvas.addEventListener('pointerdown',e=>{e.preventDefault();drag=true;canvas.setPointerCapture(e.pointerId);lastPoint=point(e);advance(hit(...lastPoint));});
|
||||
canvas.addEventListener('pointermove',e=>{if(!drag)return;e.preventDefault();const p=point(e),a=lastPoint||p,d=Math.hypot(p[0]-a[0],p[1]-a[1]),steps=Math.ceil(d/Math.max(3,unit*.1));for(let i=1;i<=steps;i++)advance(hit(a[0]+(p[0]-a[0])*i/steps,a[1]+(p[1]-a[1])*i/steps));lastPoint=p;});
|
||||
function end(){drag=false;lastPoint=null;}canvas.addEventListener('pointerup',end);canvas.addEventListener('pointercancel',end);
|
||||
$('undo').onclick=()=>{if(path.length){path.pop();record.backtracks++;record.completed=false;cleared=false;focus=[];setStatus('已撤销一步。');draw();}};
|
||||
$('restart').onclick=()=>{path=[];cleared=false;focus=[];record.restarts++;record.completed=false;started=performance.now();setStatus('已重开。');draw();};
|
||||
$('hint').onclick=()=>{record.hints++;const h=hint(solution,path);focus=h.kind==='none'?[]:[h.cell];setStatus(h.kind==='backtrack'?'请退回黄色边框格,再继续。':h.kind==='restart'?'起点需要调整,请重开并从黄色边框格开始。':h.kind==='none'?'已经完成。':'下一步在黄色边框格;提示不会自动画路。');draw();};
|
||||
$('next').onclick=()=>{selected=pack.levels[index+1].difficulty;start(index+1);};
|
||||
$('export').onclick=()=>{record.elapsedSeconds=record.completed?record.elapsedSeconds:Math.round((performance.now()-started)/1000);record.reasoning=$('reasoning').value;const blob=new Blob([JSON.stringify(record,null,2)],{type:'application/json'}),a=document.createElement('a');a.href=URL.createObjectURL(blob);a.download=pack.mode+'-'+level.id+'-试玩记录.json';a.click();setTimeout(()=>URL.revokeObjectURL(a.href),1000);};
|
||||
window.addEventListener('resize',draw);start(0);
|
||||
// Read-only snapshot used for interaction verification; never supplies an answer.
|
||||
window.variantSnapshot=()=>({mode:pack.mode,level:level.id,path:[...path],violations:violations(level,path),cleared,centers:Object.fromEntries(centers),unit,openedGates:(level.gates||[]).map(g=>path.includes(g.switchCell)),doors:(level.doors||[]).map(d=>doorOpen(d,path.length))});
|
||||
|
||||
|
||||