Re: 改下哥尼斯堡網頁程式
konigsberg20260414faild7824
當AI發現它已經必敗時,仍應作最頑強抵抗,而不是直接送死。
https://ejsoon.vip/wp-content/uploads/2 ... d7824.html
當AI發現它已經必敗時,仍應作最頑強抵抗,而不是直接送死。
https://ejsoon.vip/wp-content/uploads/2 ... d7824.html
- 附件
-
konigsberg20260414faild7824.7z- (16.11 KiB) 已下载 62 次
https://ejsoon.vip/
弈趣極光:享受思維樂趣
弈趣極光:享受思維樂趣
Re: 改下哥尼斯堡網頁程式
被「專家」全屏擊殺:

代码: 全选
[[3,6],[-5,3,0,1,4,8],[8,6,0,3,1,0,4,1,8,4],[-5,6,9,5,8,7],[8,7,0,3,1,0,4,1,8,4,9,6,5,9,8,5,7,8],[-5,8,5,4,1],[1,7,0,3,1,0,1,4,8,4,9,6,5,9,5,8,7,8,4,5],[-5,7,8,4,5,1,2],[1,2,0,3,1,0,1,4,4,8,9,6,5,9,5,8,8,7,5,4,1,5,2,1],[-5,1,5,9,8,7],[7,2,0,3,1,0,1,4,4,8,9,6,9,5,5,8,7,8,5,4,5,1,2,1,8,9],[-5,2,5,4,0,3,7,8,9],[7,9,3,0,1,0,1,4,4,8,9,6,9,5,5,8,8,7,4,5,5,1,2,1,9,8,2,5,4,0,3,7],[-5,7,4,5,1],[1,9,3,0,1,0,1,4,4,8,9,6,9,5,5,8,8,7,5,4,1,5,2,1,9,8,2,5,4,0,3,7,7,4],[-5,9,6,2],[1,2,3,0,1,0,1,4,4,8,6,9,9,5,5,8,8,7,5,4,1,5,2,1,9,8,2,5,4,0,3,7,7,4,6,2],[-5,1,5,6,9],[9,2,3,0,1,0,1,4,4,8,9,6,9,5,5,8,8,7,5,4,5,1,2,1,9,8,2,5,4,0,3,7,7,4,6,2,5,6],[-5,2,1,4,8,7],[9,7,3,0,1,0,4,1,8,4,9,6,9,5,5,8,7,8,5,4,5,1,1,2,9,8,2,5,4,0,3,7,7,4,6,2,5,6],[-5,9,6,2,5,4,3,0],[0,7,0,3,1,0,4,1,8,4,6,9,9,5,5,8,7,8,4,5,5,1,1,2,9,8,2,5,4,0,3,7,7,4,6,2,5,6,4,3],[-1,7,4,7,8,4,0,4,1,4,3,4,5,8,4,0,3,1,0,1,2,3,7,5,8,5,6,5,1,2,5,6,2,6,9,9,5,9,8]]代码: 全选
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg id="konigsberg" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="720" height="480" viewBox="0 0 720 480" style="background: lightblue; height: 100%; width: 100%;"><g id="kongnisbersvg">
<g class="appendarea"><circle cx="180" cy="48" r="24" fill="#fff" stroke="#333" stroke-width="2" i="0"/><circle cx="360" cy="48" r="24" fill="#fff" stroke="#333" stroke-width="2" i="1"/><circle cx="540" cy="48" r="24" fill="#fff" stroke="#333" stroke-width="2" i="2"/><circle cx="90" cy="203.88457268119896" r="24" fill="#fff" stroke="#333" stroke-width="2" i="3"/><circle cx="270" cy="203.88457268119896" r="24" fill="#fff" stroke="#333" stroke-width="2" i="4"/><circle cx="450" cy="203.88457268119896" r="24" fill="#fff" stroke="#333" stroke-width="2" i="5"/><circle cx="630" cy="203.88457268119896" r="24" fill="#fff" stroke="#333" stroke-width="2" i="6"/><circle cx="180" cy="359.7691453623979" r="24" fill="#fff" stroke="#333" stroke-width="2" i="7"/><circle cx="360" cy="359.7691453623979" r="24" fill="#fff" stroke="#333" stroke-width="2" i="8"/><circle cx="540" cy="359.7691453623979" r="24" fill="#fff" stroke="#333" stroke-width="2" i="9"/><path class="arrowbrg" d="M73,125.94228634059948 v -12 h 100 v -12 l 24 24 l -24 24 v -12 h -100 Z" fill="#C19A6B" stroke="none" stroke-width="2" rotatedeg="480" style="transform: rotate(480deg); transform-origin: 135px 125.942px 0px;"/><path class="arrowbrg" d="M208,48 v -12 h 100 v -12 l 24 24 l -24 24 v -12 h -100 Z" fill="#C19A6B" stroke="none" stroke-width="2" rotatedeg="180" style="transform: rotate(180deg); transform-origin: 270px 48px 0px;"/><path class="arrowbrg" d="M253,125.94228634059948 v -12 h 100 v -12 l 24 24 l -24 24 v -12 h -100 Z" fill="#C19A6B" stroke="none" stroke-width="2" rotatedeg="660" style="transform: rotate(660deg); transform-origin: 315px 125.942px 0px;"/><path class="arrowbrg" d="M253,281.82685902179844 v -12 h 100 v -12 l 24 24 l -24 24 v -12 h -100 Z" fill="#C19A6B" stroke="none" stroke-width="2" rotatedeg="600" style="transform: rotate(600deg); transform-origin: 315px 281.827px 0px;"/><path class="arrowbrg" d="M523,281.82685902179844 v -12 h 100 v -12 l 24 24 l -24 24 v -12 h -100 Z" fill="#C19A6B" stroke="none" stroke-width="2" rotatedeg="840" style="transform: rotate(840deg); transform-origin: 585px 281.827px 0px;"/><path class="arrowbrg" d="M433,281.82685902179844 v -12 h 100 v -12 l 24 24 l -24 24 v -12 h -100 Z" fill="#C19A6B" stroke="none" stroke-width="2" rotatedeg="240" style="transform: rotate(240deg); transform-origin: 495px 281.827px 0px;"/><path class="arrowbrg" d="M343,281.82685902179844 v -12 h 100 v -12 l 24 24 l -24 24 v -12 h -100 Z" fill="#C19A6B" stroke="none" stroke-width="2" rotatedeg="480" style="transform: rotate(480deg); transform-origin: 405px 281.827px 0px;"/><path class="arrowbrg" d="M208,359.7691453623979 v -12 h 100 v -12 l 24 24 l -24 24 v -12 h -100 Z" fill="#C19A6B" stroke="none" stroke-width="2" rotatedeg="1080" style="transform: rotate(1080deg); transform-origin: 270px 359.769px 0px;"/><path class="arrowbrg" d="M298,203.88457268119896 v -12 h 100 v -12 l 24 24 l -24 24 v -12 h -100 Z" fill="#C19A6B" stroke="none" stroke-width="2" rotatedeg="1080" style="transform: rotate(1080deg); transform-origin: 360px 203.885px 0px;"/><path class="arrowbrg" d="M343,125.94228634059948 v -12 h 100 v -12 l 24 24 l -24 24 v -12 h -100 Z" fill="#C19A6B" stroke="none" stroke-width="2" rotatedeg="600" style="transform: rotate(600deg); transform-origin: 405px 125.942px 0px;"/><path class="arrowbrg" d="M388,48 v -12 h 100 v -12 l 24 24 l -24 24 v -12 h -100 Z" fill="#C19A6B" stroke="none" stroke-width="2" rotatedeg="360" style="transform: rotate(360deg); transform-origin: 450px 48px 0px;"/><path class="arrowbrg" d="M388,359.7691453623979 v -12 h 100 v -12 l 24 24 l -24 24 v -12 h -100 Z" fill="#C19A6B" stroke="none" stroke-width="2" rotatedeg="540" style="transform: rotate(540deg); transform-origin: 450px 359.769px 0px;"/><path class="arrowbrg" d="M433,125.94228634059948 v -12 h 100 v -12 l 24 24 l -24 24 v -12 h -100 Z" fill="#708090" stroke="none" stroke-width="2" rotatedeg="120" style="transform: rotate(120deg); transform-origin: 495px 125.942px 0px;"/><path class="arrowbrg" d="M163,125.94228634059948 v -12 h 100 v -12 l 24 24 l -24 24 v -12 h -100 Z" fill="#708090" stroke="none" stroke-width="2" rotatedeg="-120" style="transform: rotate(-120deg); transform-origin: 225px 125.942px 0px;"/><path class="arrowbrg" d="M73,281.82685902179844 v -12 h 100 v -12 l 24 24 l -24 24 v -12 h -100 Z" fill="#708090" stroke="none" stroke-width="2" rotatedeg="60" style="transform: rotate(60deg); transform-origin: 135px 281.827px 0px;"/><path class="arrowbrg" d="M163,281.82685902179844 v -12 h 100 v -12 l 24 24 l -24 24 v -12 h -100 Z" fill="#708090" stroke="none" stroke-width="2" rotatedeg="-60" style="transform: rotate(-60deg); transform-origin: 225px 281.827px 0px;"/><path class="arrowbrg" d="M523,125.94228634059948 v -12 h 100 v -12 l 24 24 l -24 24 v -12 h -100 Z" fill="#708090" stroke="none" stroke-width="2" rotatedeg="-120" style="transform: rotate(-120deg); transform-origin: 585px 125.942px 0px;"/><path class="arrowbrg" d="M478,203.88457268119896 v -12 h 100 v -12 l 24 24 l -24 24 v -12 h -100 Z" fill="#708090" stroke="none" stroke-width="2" rotatedeg="0" style="transform: rotate(0deg); transform-origin: 540px 203.885px 0px;"/><path class="arrowbrg" d="M118,203.88457268119896 v -12 h 100 v -12 l 24 24 l -24 24 v -12 h -100 Z" fill="#708090" stroke="none" stroke-width="2" rotatedeg="180" style="transform: rotate(180deg); transform-origin: 180px 203.885px 0px;"/></g>
<g class="bottomarea"><circle cx="180" cy="48" r="24" fill="#33d" stroke="none" stroke-width="4" i="0" stroke-dasharray="7 7" class="" style="transform: translate(0px);"/></g>
<g class="middlearea">
<line class="redline" x1="180" y1="359.7691453623979" x2="270" y2="203.88457268119896" stroke="#e77" stroke-width="7" stroke-linecap="round"/><line class="redline" x1="180" y1="359.7691453623979" x2="360" y2="359.7691453623979" stroke="#e77" stroke-width="7" stroke-linecap="round"/><line class="redline" x1="270" y1="203.88457268119896" x2="180" y2="48" stroke="#e77" stroke-width="7" stroke-linecap="round"/><line class="redline" x1="270" y1="203.88457268119896" x2="360" y2="48" stroke="#e77" stroke-width="7" stroke-linecap="round"/><line class="redline" x1="270" y1="203.88457268119896" x2="90" y2="203.88457268119896" stroke="#e77" stroke-width="7" stroke-linecap="round"/><line class="redline" x1="270" y1="203.88457268119896" x2="450" y2="203.88457268119896" stroke="#e77" stroke-width="7" stroke-linecap="round"/><line class="redline" x1="360" y1="359.7691453623979" x2="270" y2="203.88457268119896" stroke="#e77" stroke-width="7" stroke-linecap="round"/><line class="redline" x1="180" y1="48" x2="90" y2="203.88457268119896" stroke="#e77" stroke-width="7" stroke-linecap="round"/><line class="redline" x1="360" y1="48" x2="180" y2="48" stroke="#e77" stroke-width="7" stroke-linecap="round"/><line class="redline" x1="360" y1="48" x2="540" y2="48" stroke="#e77" stroke-width="7" stroke-linecap="round"/><line class="redline" x1="90" y1="203.88457268119896" x2="180" y2="359.7691453623979" stroke="#e77" stroke-width="7" stroke-linecap="round"/><line class="redline" x1="450" y1="203.88457268119896" x2="360" y2="359.7691453623979" stroke="#e77" stroke-width="7" stroke-linecap="round"/><line class="redline" x1="450" y1="203.88457268119896" x2="630" y2="203.88457268119896" stroke="#e77" stroke-width="7" stroke-linecap="round"/><line class="redline" x1="450" y1="203.88457268119896" x2="360" y2="48" stroke="#e77" stroke-width="7" stroke-linecap="round"/><line class="redline" x1="540" y1="48" x2="450" y2="203.88457268119896" stroke="#e77" stroke-width="7" stroke-linecap="round"/><line class="redline" x1="630" y1="203.88457268119896" x2="540" y2="48" stroke="#e77" stroke-width="7" stroke-linecap="round"/><line class="redline" x1="630" y1="203.88457268119896" x2="540" y2="359.7691453623979" stroke="#e77" stroke-width="7" stroke-linecap="round"/><line class="redline" x1="540" y1="359.7691453623979" x2="450" y2="203.88457268119896" stroke="#e77" stroke-width="7" stroke-linecap="round"/><line class="redline" x1="540" y1="359.7691453623979" x2="360" y2="359.7691453623979" stroke="#e77" stroke-width="7" stroke-linecap="round"/></g>
<g class="toparea"><circle cx="180" cy="359.7691453623979" r="24" fill="#3d3" stroke="none" stroke-width="4" i="7" stroke-dasharray="7 7" class="" style="transform: translate(0px);"/></g>
<use>
<animateMotion dur="12s" fill="freeze" additive="sum" id="moveinroute" rotate="auto">
<mpath xlink:href="#movingroute"/>
</animateMotion>
</use>
<g id="g12155">
<path d="M 48 420 h 72 v 40 h -72 Z" fill="none" stroke="#fff" stroke-width="2" id="path22"/>
<path d="M 96 420 h 24 v 40 h -48 Z" fill="#3d3" stroke="#fff" stroke-width="2" id="path26" class=""/>
</g>
<g id="g8717" transform="translate(38.455111,0.32714844)" class="">
<circle cx="379.73492" cy="439.67285" r="16" fill="#b0dceb" stroke="#ffffff" stroke-width="2" id="circle5497"/>
<path style="fill:#078f00;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" d="m 373.27064,427.6435 19.50493,12.27039 -19.58086,11.99501 z" id="path5939"/>
</g>
<g id="g11048" transform="translate(0,-2.7672119)" class="">
<rect style="fill:#b0dceb;fill-opacity:1;stroke:#fff;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" id="rect7925" width="46.221607" height="27.315125" x="501.40842" y="429.10965"/>
<path style="fill:none;stroke:#490f92;stroke-width:3.6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="m 510.76874,434.58056 v 16.35487" id="path9124"/>
<path style="fill:none;stroke:#490f92;stroke-width:3.6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="m 526.0211,436.6151 -7.81082,6.64035 7.61586,6.43247" id="path9885"/>
<path style="fill:none;stroke:#490f92;stroke-width:3.6;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="m 539.43881,436.6151 -7.81082,6.64035 7.61586,6.43247" id="path10346"/>
</g>
<rect style="fill:#b0dceb;fill-opacity:1;stroke:#490f92;stroke-width:3.6;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" id="rect11400" width="21.318359" height="21.318359" x="576.03088" y="429.34082"/>
</g></svg>https://ejsoon.vip/
弈趣極光:享受思維樂趣
弈趣極光:享受思維樂趣
Re: 改下哥尼斯堡網頁程式
konigsberg20260414topman7825
更改men on top的顯示邏輯。
https://ejsoon.vip/wp-content/uploads/2 ... n7825.html
更改men on top的顯示邏輯。
https://ejsoon.vip/wp-content/uploads/2 ... n7825.html
- 附件
-
konigsberg20260414topman7825.7z- (16.04 KiB) 已下载 60 次
https://ejsoon.vip/
弈趣極光:享受思維樂趣
弈趣極光:享受思維樂趣
Re: 改下哥尼斯堡網頁程式
konigsberg20260414historytopman7826
history前後翻的時候,top man也在轉。
https://ejsoon.vip/wp-content/uploads/2 ... n7826.html
history前後翻的時候,top man也在轉。
https://ejsoon.vip/wp-content/uploads/2 ... n7826.html
- 附件
-
konigsberg20260414historytopman7826.7z- (16.04 KiB) 已下载 58 次
https://ejsoon.vip/
弈趣極光:享受思維樂趣
弈趣極光:享受思維樂趣
Re: 改下哥尼斯堡網頁程式
改進:
bottom_men初始的stroke-width改為4。
當一方因為困斃(-2)或沒放新木橋(-3)而輸時,它的bottom_men應該要加stroke=#e77。
當兩方走到和局(-4)時,兩方的bottom_men都要改stroke=#e77。
當點擊btn_history_prev和btn_history_next時,走到-2 、-3或-4時,也要改變當前bottom_men的stroke。
當在history中前後翻過之後,點擊play,要先檢查當前盤面是否已經終局(-1、-2、-3、-4),如終局則不再能繼續走棋,而是顯示結局。
只需給出所要修改的地方。
bottom_men初始的stroke-width改為4。
當一方因為困斃(-2)或沒放新木橋(-3)而輸時,它的bottom_men應該要加stroke=#e77。
當兩方走到和局(-4)時,兩方的bottom_men都要改stroke=#e77。
當點擊btn_history_prev和btn_history_next時,走到-2 、-3或-4時,也要改變當前bottom_men的stroke。
當在history中前後翻過之後,點擊play,要先檢查當前盤面是否已經終局(-1、-2、-3、-4),如終局則不再能繼續走棋,而是顯示結局。
只需給出所要修改的地方。
https://ejsoon.vip/
弈趣極光:享受思維樂趣
弈趣極光:享受思維樂趣
Re: 改下哥尼斯堡網頁程式
gemini pro:
代码: 全选
這裡為您整理出對應這 5 項改進,程式碼中**需要修改或新增的 4 個區塊**:
### 1. `addDots()` 函式內
在建立 `man_bottom` 的屬性設定時,加上 `stroke-width`:
```javascript
if (i == 3 || i == 6) {
let man_bottom = dot.cloneNode(true);
let manfill = i == 3 ? "#33d" : "#3d3";
man_bottom.setAttribute("fill", manfill);
man_bottom.setAttribute("stroke", "none");
man_bottom.setAttribute("stroke-width", "4"); // 💡 新增這行
man_bottom.setAttribute("i", i);
```
### 2. `judgeResult()` 函式內 (有兩處需要加 stroke)
**第一處:和局 (-4)**
```javascript
if (game_history.indexOf(current_history_str) == -1) {
h_status = -5;
game_status = game_status == 4 ? 1 : 3
} else {
h_status = -4;
game_status = 7;
detail_div.innerHTML = "Draw";
btn_play.classList.remove("hide");
// 💡 新增:和局雙方加上紅色邊框
men_bottom[0].setAttribute("stroke", "#e77");
men_bottom[1].setAttribute("stroke", "#e77");
}
```
**第二處:困斃 (-2) 或 沒放橋 (-3)**
```javascript
} else {
game_status = 7;
let current_man_str = current_man ? "Green" : "Blue";
let lose_reason;
if (route_tmp.length <= 1) {
lose_reason = "he does not take any steps.";
lose_num = -2;
} else {
lose_reason = "no new wooden bridge was set up.";
lose_num = -3;
}
game_history.push(JSON.stringify([lose_num].concat(route_tmp)));
detail_div.innerHTML = current_man_str + " man loses, because " + lose_reason;
btn_play.classList.remove("hide");
// 💡 新增:困斃或沒放橋,當前方加上紅色邊框
men_bottom[current_man].setAttribute("stroke", "#e77");
}
```
### 3. `historyCommen()` 函式內
在還原歷史盤面時,需先清空 stroke,並根據讀取到的狀態碼還原 stroke:
**第一處:清空 stroke (在設定 men_top 座標之後)**
```javascript
men_top[1].setAttribute("cx", dots[current_board[1]].getAttribute("cx"));
men_top[1].setAttribute("cy", dots[current_board[1]].getAttribute("cy"));
// 💡 新增:先重置雙方的 stroke
men_bottom[0].setAttribute("stroke", "none");
men_bottom[1].setAttribute("stroke", "none");
// animation motion reset
```
**第二處:還原狀態 stroke (在函式末段解析 history_route_tmp 處)**
```javascript
if (game_history.length > game_hp * 2 + 1) {
let history_route_tmp = JSON.parse(game_history[game_hp * 2 + 1]);
if (history_route_tmp[0] < -1) {
// 💡 新增:根據歷史狀態恢復對應的紅色邊框
if (history_route_tmp[0] == -4) {
men_bottom[0].setAttribute("stroke", "#e77");
men_bottom[1].setAttribute("stroke", "#e77");
} else if (history_route_tmp[0] == -2 || history_route_tmp[0] == -3) {
men_bottom[current_man].setAttribute("stroke", "#e77");
}
route.setAttribute("d", "M" +
```
### 4. `btn_play.onclick` 函式內
修改 `else if (game_status == 8)` 區塊,加入終局判斷與結局顯示:
```javascript
} else if (game_status == 8) {
this.classList.add("hide");
btn_history_next.classList.add("hide");
// 💡 新增:檢查當前歷史節點是否為終局 (-1, -2, -3, -4)
let is_terminal = false;
let status_code = 0;
if (game_history.length > game_hp * 2 + 1) {
let history_route_tmp = JSON.parse(game_history[game_hp * 2 + 1]);
status_code = history_route_tmp[0];
if (status_code < 0) {
is_terminal = true;
}
}
if (is_terminal) {
game_history.splice(game_hp * 2 + 2); // 保留至當前終局,捨棄後續多餘紀錄
game_status = 7;
// 💡 新增:恢復顯示結局文字
if (status_code == -4) {
detail_div.innerHTML = "Draw";
} else if (status_code == -2 || status_code == -3) {
let current_man_str = current_man ? "Green" : "Blue";
let lose_reason = status_code == -2 ? "he does not take any steps." : "no new wooden bridge was set up.";
detail_div.innerHTML = current_man_str + " man loses, because " + lose_reason;
} else if (status_code == -1) {
let loseman = current_man ? "Blue" : "Green";
detail_div.innerHTML = loseman + " man is lose, because of shooting!";
}
this.classList.remove("hide"); // 顯示 play 按鈕以便重開新局
} else {
route.classList.add("hide");
game_history.splice(game_hp * 2 + 1);
game_status = game_hp & 1 ? 3 : 1;
current_man = game_hp & 1;
displayGame();
}
} else {
```https://ejsoon.vip/
弈趣極光:享受思維樂趣
弈趣極光:享受思維樂趣
Re: 改下哥尼斯堡網頁程式
konigsberg20260414drawfaild791
困斃、沒放新木橋、和棋,都加上了紅圈。
https://ejsoon.vip/wp-content/uploads/2 ... ld791.html
困斃、沒放新木橋、和棋,都加上了紅圈。
https://ejsoon.vip/wp-content/uploads/2 ... ld791.html
- 附件
-
konigsberg20260414drawfaild791.7z- (16.21 KiB) 已下载 61 次
https://ejsoon.vip/
弈趣極光:享受思維樂趣
弈趣極光:享受思維樂趣
Re: 改下哥尼斯堡網頁程式
強AI和局:
代码: 全选
[[3,6],[-5,3,4,0,1,2,5],[5,6,4,3,0,4,1,0,2,1,5,2],[-5,6,5,1,0],[5,0,4,3,0,4,0,1,2,1,5,2,5,6,1,5],[-5,5,8,4,7],[7,0,4,3,0,4,0,1,2,1,5,2,5,6,1,5,8,5,4,8,7,4],[-5,0,4,5,6],[7,6,4,3,4,0,0,1,2,1,5,2,6,5,1,5,8,5,4,8,7,4,5,4],[-5,7,8,9,6,5,4,0],[0,6,4,3,0,4,0,1,2,1,5,2,5,6,1,5,8,5,4,8,7,4,4,5,8,7,8,9,9,6],[-5,6,2,1,4,8],[0,8,4,3,0,4,0,1,1,2,5,2,5,6,1,5,8,5,8,4,7,4,4,5,8,7,8,9,9,6,6,2,1,4],[-5,0,1],[1,8,4,3,0,4,1,0,1,2,5,2,5,6,1,5,8,5,8,4,7,4,4,5,8,7,8,9,9,6,6,2,1,4],[-5,8,7,3,0,4,5,6],[1,6,4,3,4,0,1,0,1,2,5,2,6,5,1,5,8,5,8,4,7,4,5,4,7,8,8,9,9,6,6,2,1,4,7,3,3,0],[-5,1,5,4,3],[3,6,3,4,4,0,1,0,1,2,5,2,6,5,5,1,8,5,8,4,7,4,4,5,7,8,8,9,9,6,6,2,1,4,7,3,3,0],[-5,6,5,1],[3,1,3,4,4,0,1,0,1,2,5,2,5,6,1,5,8,5,8,4,7,4,4,5,7,8,8,9,9,6,6,2,1,4,7,3,3,0],[-5,3,4,5,6],[6,1,4,3,4,0,1,0,1,2,5,2,6,5,1,5,8,5,8,4,7,4,5,4,7,8,8,9,9,6,6,2,1,4,7,3,3,0],[-5,1,5,4,3],[6,3,3,4,4,0,1,0,1,2,5,2,6,5,5,1,8,5,8,4,7,4,4,5,7,8,8,9,9,6,6,2,1,4,7,3,3,0],[-5,6,5,1],[1,3,3,4,4,0,1,0,1,2,5,2,5,6,1,5,8,5,8,4,7,4,4,5,7,8,8,9,9,6,6,2,1,4,7,3,3,0],[-4,3,4,5,6],[1,6,4,3,4,0,1,0,1,2,5,2,6,5,1,5,8,5,8,4,7,4,5,4,7,8,8,9,9,6,6,2,1,4,7,3,3,0]]https://ejsoon.vip/
弈趣極光:享受思維樂趣
弈趣極光:享受思維樂趣
Re: 改下哥尼斯堡網頁程式
哥尼斯堡的動畫還不是一般的難做:
代码: 全选
為本程式製作「導出svg動畫」功能。
在頁面加載後,把「生成svg動畫」按鈕絕對定位到#fullscreen下方7px以及離屏幕右邊7px的地方。當屏寬發生變化時,其右邊7px的值跟#fullscreen一起改變。這個按鈕應是一個獨立的svg圖標。
當點擊這個按鈕時,作以下操作:
一,拿到game_history走到最後一步時的svg#konigsberg的clone,把它的id改為konigsberganimate(以下簡稱ka)。
二,把ka中.toparea往後的所有元素去掉,把「.arrowbrg.hide」去掉,再把「所有的.arrowbrg」、「.bottomarea內的兩個元素」、「.middlearea內的所有元素」、「.toparea內的兩個元素」都加上visibility=hidden,並去掉style="..."和class="..."。
下面將把svg#konigsberg的「.bottomarea內的兩個元素」稱作menb0和menb1(合稱menb01),svg#konigsberg的「.toparea內的兩個元素」稱作ment0和ment1(合稱ment01),ka內的「.bottomarea內的兩個元素」稱作kamenb0和kamenb1(合稱kamenb01),ka內的「.toparea內的兩個元素」稱作kament0和kament1(合稱kament01)。
svg#konigsberg內的#movingroute稱作「route」,ka的#movingroute稱作karoute。
三,為kament01內部清空後加上「<animate attributeName="stroke-dashoffset" values="0;-24000" repeatCount="indefinite" dur="777s"></animate>」。
四,動畫開始時,把kamenb01的stroke都設為none,再把game_history首步(即game_hp=0)時的menb01的cx和cy的值賦給kamenb01,之後為kamenb0加上「<set attributeName="visibility" to="visible" begin="1s;kaend.end+1s" id="kastart" dur="1s">」,為kamenb1加上「<set attributeName="visibility" to="visible" begin="kastart.begin" end="kaj1.begin">」。
五,下面為每一步棋加上動畫,每一步棋包括「激活、規劃、放橋、移動、轉橋、判定」。用x=game_hp&1來確定當前是輪到men0還是men1。
5.1 激活
為kament0加上「<set attributeName="visibility" id="kaj0" to="visible" begin="kastart.end" end="kad0.end">」。
5.2 規劃
把當前(game_hp=0)的route的屬性d的值用set賦給karoute:「<set attributeName="d" id="kap0" to="取到的值" begin="kaj0.end">」,之後將其顯示:「<set attributeName="visibility" to="visible" begin="kap0.begin" end="kam0.begin">」。
5.3 放橋
橋指的是appendarea中的class="arrowbrg"的元素。在game_history中會保存移動結束之後的橋的指向。如果route經過了木橋(前12個橋),則這些橋的初始方向是反向的。設置它們的初始transform屬性。
例如當一個棋手走完[-5,3,0,1,4,7,8,9],後面接上行走完之後的盤面描述[9,6,0,3,1,0,4,1,7,4,8,7,9,8],其中9和6是men0和men1的所在位置,後面每兩個數字都是橋的指向,比如「0,3」是0指向3。而route如果從3走過0,則當前要放的橋的方向是3指向0(這樣才允許棋手經過)。
這時將要設第一個class="arrowbrg"的橋的屬性transform="rotate(300 135,125.942)",120是0指向3的初始角度,如果3指向0則加180度。後面的135,125.942是從最後一個game_history中,svg#konigsberg中對應順序的class="arrowbrg"的style中的transform-origin: 135px 125.942px 0px;拿到的。
本盤面描述中沒有的,下一步描述才有的橋,在本次行走都要新增。
舉個例子:[[3,6],[-5,3,0],[0,6,0,3],[-5,6,5,4,0,3],[0,3,3,0,5,6,4,5,0,4]],第一步的盤面描述是[3,6],是兩個棋子的初始位置,第二步盤面是[0,6,0,3],則0,6是當前棋子位置,「0,3」是新增的橋。第三步中「0,3」是棋子位置,「3,0,5,6,4,5,0,4」是橋的位置,其中「3,0」並不是新增的橋,「5,6」、「4,5」、「0,4」都是新增的橋。橋的新增順序跟class="arrowbrg"的index順序一致。
新增的橋要加上「<set attributeName="stroke" to="#333" begin="kap0.begin" end="kad0.begin">」和「<set attributeName="visibility" to="visible" begin="kap0.begin+0.36s" end="kaend.begin+5s">」。
5.4 移動
將kament0加上<animateMotion dur="3s" repeatCount="indefinite"> <mpath href="#ute" /> </animateMotion>
https://ejsoon.vip/
弈趣極光:享受思維樂趣
弈趣極光:享受思維樂趣
Re: 改下哥尼斯堡網頁程式
為本程式製作「導出svg動畫」功能(只需要給出所要修改的地方):
在頁面加載後,新增「生成svg動畫」按鈕並把它絕對定位到#fullscreen下方7px以及離屏幕右邊7px的地方。當屏寬發生變化時,其右邊7px的值跟#fullscreen一起改變。這個按鈕應是一個獨立的svg圖標。
當點擊這個按鈕時,程式拿到game_history走到最後一步時的svg#konigsberg的clone,按下面步驟對這個clone進行改動。
1.把這個clone的id改為konigsberganimate。
2.把.toparea往後的所有元素去掉,把「.arrowbrg.hide」去掉。
3.下面將把「.bottomarea內的兩個元素」稱作bmen0和bmen1(合稱bmen),「.toparea內的兩個元素」稱作tmen0和tmen1(合稱tmen)。
4.去掉bmen、tmen的屬性:class、style、i。
5.把所有的.arrowbrg的style中的transform-origin按順序記到一個陣列變量中,然後去掉它們的rotatedeg、style屬性。
6.如果.arrowbrg的數量大於12,那麼超過12的將把fill改為#708090。
7.把所有的<circle/>的cx、cy,和所有的<line/>的x1、x2、y1、y2屬性的值都只保留小數點後兩位。
8.把.middlearea內的#movingroute移到它的外面,置於.middlearea的下方。
9.為#movingroute、tmen、所有的.arrowbrg添加屬性visibility=hidden。
10.為#konigsberganimate添加屬性opacity=0。
11.把tmen的cx和cy都改為0,bmen的stroke改為none。
12.取到game_history的第一個值,取其前兩個值(比如[3,6])。再通過i=x屬性拿到對應的.appendarea中的circle的cx、cy,之後為bmen0和bmen1的cx、cy賦值。(比如circle的cx=90,cy=203.88,則為bmen0的cx和cy賦對應的值)
13.為#konigsberganimate添加元素「<animate id="kastart" begin="0s;kaend.end" attributeName="opacity" values="0;0;1" fill="freeze" dur="2s"></animate>」。
14.game_history的第偶數個值,它應為-5、-4、-3、-2或-1開頭的陣列,稱為「行動陣列」。從第1個行動陣列是men0的行動,第2個是men1,依此類推。下面將把當前行動者稱作menx。第奇數個值是「描述陣列」,描述前一個行動後的結果。以「-1、-2、-3」開頭的行動陣列往後將沒有描述陣列。
例如game_history=[[3,6],[-5,3,0],[0,6,0,3],[-5,6,2],[0,2,0,3,2,6],[-5,0,1],[1,2,0,3,2,6,1,0]],則[-5,3,0]、[-5,6,2]、[-5,0,1]是行動陣列,其餘是描述陣列。[-5,3,0]、[-5,0,1]是men0的行動,[-5,6,2]是men1的行動。
15.為bmenx添加元素「<set attributeName="visibility" id="kajn" to="visible" begin="(kastart或kadn-1).end+1s"/>」。kajn中的n是指0開始的整數,對應行動陣列的index。如果n=0,begin="kastart.end+1s",如果n>0,則begin="kad(n-1).end+1s"。
在前面的例子中,[-5,3,0]則為n=0的情況,[-5,6,2]則是n=1。
16.如果行動陣列的開頭是-5、-4或-3,則為#movingroute加上「<set attributeName="d" id="kapn" to="route" begin="kajn.begin+1s" end="kamn.begin"/>」,route的值為行動陣列所對應的.appendarea中的circle的cx、cy,用「M cx,cy L cx,cy L cx,cy ...」拼接而成。
17.在完成上個步驟之後,要加上當前行動所需的新橋。橋指的是.arrowbrg元素。
確認新加的橋的方法是,當前行動陣列所經過的地方,上個描述陣列沒有,則此處將加新橋。例如game_history=[[3,6],[-5,3,0],[0,6,0,3],[-5,6,2],[0,2,0,3,2,6],[-5,0,1],[1,2,0,3,2,6,1,0]],則當行動為[-5,3,0],即藍方從3走到0,而前面沒有「3,0」這個橋,則它將是第一個新加的橋。
在描述陣列中,前面兩個數字分別是men0和men1的位置,後面每兩個數字都是描述橋的指向,按其加入的順序存放。
為新橋加入初始屬性transform="rotate(deg)"。deg的規則是:「0,1、1,2、3,4、4,5、5,6、7,8、8,9」是「0」,「0,3、1,4、2,5、4,7、5,8、6,9」是「120」,「0,4、1,5、2,6、3,7、4,8、5,9」是「60」,如果反向則加上「180」。
為新橋加上兩個元素:「<set attributeName="visibility" to="visible" begin="kapn.begin+0.36s"/>」和「<set attributeName="stroke" to="#333" begin="kapn.begin+0.36s"/>」。
18.在完成上個步驟之後,為#movingroute和bmenx加上「<set attributeName="visibility" to="hidden" begin="kamn.begin"/>」,為tmenx加上「<set attributeName="visibility" to="visable" begin="kamn.begin"/>」和「<animateMotion id="kamn" dur="rs" fill="freeze" path="route"/>」,其中route就是前面得到的,dur="rs"中的r指的是行動陣列所走過的點的數量,例如[-5,3,0]則r=1。
19.在完成上個步驟之後,為tmenx加上「<set attributeName="visibility" to="hidden" begin="kamn.end"/>」,為bmenx加上「<set attributeName="visibility" to="visable" begin="kamn.end"/>」。
為經過的木橋加上「<animateTransform attributeName="transform" attributeType="XML" type="rotate" from="原角度 origin" to="加了180度 origin" dur="1s" fill="freeze"/>」。
在找所經過的是第幾個橋時,由於-3沒有後面的描述陣列,因此-3就從前面的描述陣列找橋。除此之外,-4和-5都從後面的描述陣列找橋。
例如[-5,6,2],則經過的橋是6,2,再通過「6,2或2,6」找到後面的描述陣列中處於第2個,則它將對應.arrowbrg的第2個。最終在第2個.arrowbrg的內部加上了「<animateTransform attributeName="transform" attributeType="XML" type="rotate" from="240 585,125.942" to="420 585,125.942" dur="1s" fill="freeze"/>」。
20.在完成上個步驟後,在所有的新橋內加上「<set attributeName="stroke" to="none" begin="kamn.end+1.2s"/>」。
如果行動是-3,則在bmenx內加上「<set id="kadn" attributeName="stroke" to="#e77" begin="kamn.end+1.2s"/>」。
如果行動是-4,則在bmen內都加上「<set id="kadn" attributeName="stroke" to="#e77" begin="kamn.end+1.2s"/>」。
如果行動是-5,則在bmenx內加上「<set id="kadn" attributeName="stroke" to="none" begin="kamn.end+1.2s"/>」。
21.如果當前行動代號是-2,則在bmenx內加上「<set id="kadn" attributeName="stroke" to="#e77" begin="kajn.begin+1.2s"/>」。
22.如果當前行動代號是-1,則在.middlearea內加上「<set id="kadn" attributeName="visibility" to="visable" begin="kajn.begin+1.2s"/>」。
23.如果當前是最後一個行動陣列,則在#konigsberganimate內部的最後加上「<animate id="kaend" begin="kadn.end" attributeName="opacity" values="1;1;1;1;0" fill="freeze" dur="4s"></animate>」。
24.直接下載改動的結果,在左上角臨時顯示3s所下載的檔案名稱及其大小(byte)。檔案名稱為konigsber_animate_yyyymmdd_hhiiss.svg。
在頁面加載後,新增「生成svg動畫」按鈕並把它絕對定位到#fullscreen下方7px以及離屏幕右邊7px的地方。當屏寬發生變化時,其右邊7px的值跟#fullscreen一起改變。這個按鈕應是一個獨立的svg圖標。
當點擊這個按鈕時,程式拿到game_history走到最後一步時的svg#konigsberg的clone,按下面步驟對這個clone進行改動。
1.把這個clone的id改為konigsberganimate。
2.把.toparea往後的所有元素去掉,把「.arrowbrg.hide」去掉。
3.下面將把「.bottomarea內的兩個元素」稱作bmen0和bmen1(合稱bmen),「.toparea內的兩個元素」稱作tmen0和tmen1(合稱tmen)。
4.去掉bmen、tmen的屬性:class、style、i。
5.把所有的.arrowbrg的style中的transform-origin按順序記到一個陣列變量中,然後去掉它們的rotatedeg、style屬性。
6.如果.arrowbrg的數量大於12,那麼超過12的將把fill改為#708090。
7.把所有的<circle/>的cx、cy,和所有的<line/>的x1、x2、y1、y2屬性的值都只保留小數點後兩位。
8.把.middlearea內的#movingroute移到它的外面,置於.middlearea的下方。
9.為#movingroute、tmen、所有的.arrowbrg添加屬性visibility=hidden。
10.為#konigsberganimate添加屬性opacity=0。
11.把tmen的cx和cy都改為0,bmen的stroke改為none。
12.取到game_history的第一個值,取其前兩個值(比如[3,6])。再通過i=x屬性拿到對應的.appendarea中的circle的cx、cy,之後為bmen0和bmen1的cx、cy賦值。(比如circle的cx=90,cy=203.88,則為bmen0的cx和cy賦對應的值)
13.為#konigsberganimate添加元素「<animate id="kastart" begin="0s;kaend.end" attributeName="opacity" values="0;0;1" fill="freeze" dur="2s"></animate>」。
14.game_history的第偶數個值,它應為-5、-4、-3、-2或-1開頭的陣列,稱為「行動陣列」。從第1個行動陣列是men0的行動,第2個是men1,依此類推。下面將把當前行動者稱作menx。第奇數個值是「描述陣列」,描述前一個行動後的結果。以「-1、-2、-3」開頭的行動陣列往後將沒有描述陣列。
例如game_history=[[3,6],[-5,3,0],[0,6,0,3],[-5,6,2],[0,2,0,3,2,6],[-5,0,1],[1,2,0,3,2,6,1,0]],則[-5,3,0]、[-5,6,2]、[-5,0,1]是行動陣列,其餘是描述陣列。[-5,3,0]、[-5,0,1]是men0的行動,[-5,6,2]是men1的行動。
15.為bmenx添加元素「<set attributeName="visibility" id="kajn" to="visible" begin="(kastart或kadn-1).end+1s"/>」。kajn中的n是指0開始的整數,對應行動陣列的index。如果n=0,begin="kastart.end+1s",如果n>0,則begin="kad(n-1).end+1s"。
在前面的例子中,[-5,3,0]則為n=0的情況,[-5,6,2]則是n=1。
16.如果行動陣列的開頭是-5、-4或-3,則為#movingroute加上「<set attributeName="d" id="kapn" to="route" begin="kajn.begin+1s" end="kamn.begin"/>」,route的值為行動陣列所對應的.appendarea中的circle的cx、cy,用「M cx,cy L cx,cy L cx,cy ...」拼接而成。
17.在完成上個步驟之後,要加上當前行動所需的新橋。橋指的是.arrowbrg元素。
確認新加的橋的方法是,當前行動陣列所經過的地方,上個描述陣列沒有,則此處將加新橋。例如game_history=[[3,6],[-5,3,0],[0,6,0,3],[-5,6,2],[0,2,0,3,2,6],[-5,0,1],[1,2,0,3,2,6,1,0]],則當行動為[-5,3,0],即藍方從3走到0,而前面沒有「3,0」這個橋,則它將是第一個新加的橋。
在描述陣列中,前面兩個數字分別是men0和men1的位置,後面每兩個數字都是描述橋的指向,按其加入的順序存放。
為新橋加入初始屬性transform="rotate(deg)"。deg的規則是:「0,1、1,2、3,4、4,5、5,6、7,8、8,9」是「0」,「0,3、1,4、2,5、4,7、5,8、6,9」是「120」,「0,4、1,5、2,6、3,7、4,8、5,9」是「60」,如果反向則加上「180」。
為新橋加上兩個元素:「<set attributeName="visibility" to="visible" begin="kapn.begin+0.36s"/>」和「<set attributeName="stroke" to="#333" begin="kapn.begin+0.36s"/>」。
18.在完成上個步驟之後,為#movingroute和bmenx加上「<set attributeName="visibility" to="hidden" begin="kamn.begin"/>」,為tmenx加上「<set attributeName="visibility" to="visable" begin="kamn.begin"/>」和「<animateMotion id="kamn" dur="rs" fill="freeze" path="route"/>」,其中route就是前面得到的,dur="rs"中的r指的是行動陣列所走過的點的數量,例如[-5,3,0]則r=1。
19.在完成上個步驟之後,為tmenx加上「<set attributeName="visibility" to="hidden" begin="kamn.end"/>」,為bmenx加上「<set attributeName="visibility" to="visable" begin="kamn.end"/>」。
為經過的木橋加上「<animateTransform attributeName="transform" attributeType="XML" type="rotate" from="原角度 origin" to="加了180度 origin" dur="1s" fill="freeze"/>」。
在找所經過的是第幾個橋時,由於-3沒有後面的描述陣列,因此-3就從前面的描述陣列找橋。除此之外,-4和-5都從後面的描述陣列找橋。
例如[-5,6,2],則經過的橋是6,2,再通過「6,2或2,6」找到後面的描述陣列中處於第2個,則它將對應.arrowbrg的第2個。最終在第2個.arrowbrg的內部加上了「<animateTransform attributeName="transform" attributeType="XML" type="rotate" from="240 585,125.942" to="420 585,125.942" dur="1s" fill="freeze"/>」。
20.在完成上個步驟後,在所有的新橋內加上「<set attributeName="stroke" to="none" begin="kamn.end+1.2s"/>」。
如果行動是-3,則在bmenx內加上「<set id="kadn" attributeName="stroke" to="#e77" begin="kamn.end+1.2s"/>」。
如果行動是-4,則在bmen內都加上「<set id="kadn" attributeName="stroke" to="#e77" begin="kamn.end+1.2s"/>」。
如果行動是-5,則在bmenx內加上「<set id="kadn" attributeName="stroke" to="none" begin="kamn.end+1.2s"/>」。
21.如果當前行動代號是-2,則在bmenx內加上「<set id="kadn" attributeName="stroke" to="#e77" begin="kajn.begin+1.2s"/>」。
22.如果當前行動代號是-1,則在.middlearea內加上「<set id="kadn" attributeName="visibility" to="visable" begin="kajn.begin+1.2s"/>」。
23.如果當前是最後一個行動陣列,則在#konigsberganimate內部的最後加上「<animate id="kaend" begin="kadn.end" attributeName="opacity" values="1;1;1;1;0" fill="freeze" dur="4s"></animate>」。
24.直接下載改動的結果,在左上角臨時顯示3s所下載的檔案名稱及其大小(byte)。檔案名稱為konigsber_animate_yyyymmdd_hhiiss.svg。
https://ejsoon.vip/
弈趣極光:享受思維樂趣
弈趣極光:享受思維樂趣
Re: 改下哥尼斯堡網頁程式
感謝gemini,最終還是吃了。
gemini pro:
gemini pro:
代码: 全选
以下是為你的程式新增「導出 SVG 動畫」功能所需修改的地方。
### 1. 新增 HTML 元素
在 `<div id="fullscreen"></div>` 的下方插入按鈕的 HTML 程式碼:
```html
<div id="fullscreen"></div>
<div id="exportsvg" style="position: absolute; z-index: 7; top: calc(7px + 7% + 7px); right: 7px; width: 7%; height: 7%; background: #4CAF50; cursor: pointer; display: flex; align-items: center; justify-content: center; border-radius: 4px;" title="導出SVG動畫">
<svg viewBox="0 0 24 24" fill="white" width="60%" height="60%">
<path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"/>
</svg>
</div>
<svg id="konigsberg" ...
```
### 2. 獲取 DOM 節點
在 JavaScript 宣告區段中(大約在獲取 `fullscreenbtn` 變數的下方),新增對該按鈕的宣告:
```javascript
const fullscreenbtn = document.getElementById("fullscreen");
const exportsvgbtn = document.getElementById("exportsvg"); // 新增這行
```
### 3. 修改視窗縮放的動態定位邏輯
找到 `winresize()` 函式並為其補充按鈕的位置變化邏輯:
```javascript
function winresize() {
if (document.fullscreen) {
if (window.innerHeight > window.innerWidth) {
tiling_inner.classList.add("rotate90");
tiling_inner.style.setProperty("padding-top", "100%");
let fb_r = (window.innerWidth - window.innerHeight) / window.innerWidth;
fullscreenbtn.style.right = (fb_r * 100 + 7) + "%";
exportsvgbtn.style.right = (fb_r * 100 + 7) + "%"; // 新增這行
konigsberg.style.width = window.innerHeight + "px";
konigsberg.style.height = window.innerWidth + "px";
} else {
konigsberg.style.width = window.innerWidth + "px";
konigsberg.style.height = window.innerHeight + "px";
}
} else {
konigsberg.style.height = "100%";
konigsberg.style.width = "100%";
tiling_inner.classList.remove("rotate90");
fullscreenbtn.style.right = "7px";
exportsvgbtn.style.right = "7px"; // 新增這行
if (window.innerWidth / window.innerHeight > 1.5) {
tiling_inner.style.setProperty("padding-top", `${window.innerHeight / window.innerWidth * 100 + '%'}`);
} else {
tiling_inner.style.setProperty("padding-top", "66.7%");
}
}
}
```
### 4. 實作動畫生成腳本
在 JavaScript 最底部(`document.addEventListener('keydown', ...)` 下方,或者指令碼結束前),貼上以下按鈕點擊執行的功能:
```javascript
// 導出 SVG 動畫功能
exportsvgbtn.onclick = function() {
if (!game_history || game_history.length === 0) return;
// 1. 克隆並改 ID
let clone = konigsberg.cloneNode(true);
clone.id = "konigsberganimate";
// 2. 去掉 toparea 往後的所有元素,及 .arrowbrg.hide
let toparea = clone.querySelector('.toparea');
while (toparea.nextElementSibling) {
toparea.nextElementSibling.remove();
}
clone.querySelectorAll('.arrowbrg.hide').forEach(el => el.remove());
// 3. 獲取上下方的元素陣列
let bmen0 = clone.querySelector('.bottomarea').children[0];
let bmen1 = clone.querySelector('.bottomarea').children[1];
let tmen0 = clone.querySelector('.toparea').children[0];
let tmen1 = clone.querySelector('.toparea').children[1];
let bmen = [bmen0, bmen1];
let tmen = [tmen0, tmen1];
// 4. 移除屬性
bmen.forEach(el => { el.removeAttribute('class'); el.removeAttribute('style'); el.removeAttribute('i'); });
tmen.forEach(el => { el.removeAttribute('class'); el.removeAttribute('style'); el.removeAttribute('i'); });
// 5 & 6. 處理 .arrowbrg
let arrowbrgs = Array.from(clone.querySelectorAll('.arrowbrg'));
let origins = [];
arrowbrgs.forEach((ab, idx) => {
origins.push(ab.style.transformOrigin || "0px 0px");
ab.removeAttribute('rotatedeg');
ab.removeAttribute('style');
if (idx >= 12) ab.setAttribute('fill', '#708090');
});
// 7. 保留數值小數點後兩位
clone.querySelectorAll('circle').forEach(el => {
el.setAttribute('cx', parseFloat(el.getAttribute('cx')).toFixed(2));
el.setAttribute('cy', parseFloat(el.getAttribute('cy')).toFixed(2));
});
clone.querySelectorAll('line').forEach(el => {
el.setAttribute('x1', parseFloat(el.getAttribute('x1')).toFixed(2));
el.setAttribute('y1', parseFloat(el.getAttribute('y1')).toFixed(2));
el.setAttribute('x2', parseFloat(el.getAttribute('x2')).toFixed(2));
el.setAttribute('y2', parseFloat(el.getAttribute('y2')).toFixed(2));
});
// 8. 移動 #movingroute
let movingroute = clone.querySelector('#movingroute');
clone.querySelector('.middlearea').after(movingroute);
// 9. 添加 visibility=hidden
movingroute.setAttribute('visibility', 'hidden');
tmen.forEach(el => el.setAttribute('visibility', 'hidden'));
arrowbrgs.forEach(el => el.setAttribute('visibility', 'hidden'));
// 10. opacity=0
clone.setAttribute('opacity', '0');
// 11. tmen 歸零,bmen 去掉描邊
tmen.forEach(el => { el.setAttribute('cx', '0'); el.setAttribute('cy', '0'); });
bmen.forEach(el => el.setAttribute('stroke', 'none'));
// 12. 賦初始位置值
let history = game_history.map(h => JSON.parse(h));
let init_state = history[0];
bmen0.setAttribute('cx', clone.querySelector(`circle[i="${init_state[0]}"]`).getAttribute('cx'));
bmen0.setAttribute('cy', clone.querySelector(`circle[i="${init_state[0]}"]`).getAttribute('cy'));
bmen1.setAttribute('cx', clone.querySelector(`circle[i="${init_state[1]}"]`).getAttribute('cx'));
bmen1.setAttribute('cy', clone.querySelector(`circle[i="${init_state[1]}"]`).getAttribute('cy'));
// 13. Kastart
let kastart = document.createElementNS('http://www.w3.org/2000/svg', 'animate');
kastart.setAttribute('id', 'kastart');
kastart.setAttribute('begin', '0s;kaend.end');
kastart.setAttribute('attributeName', 'opacity');
kastart.setAttribute('values', '0;0;1');
kastart.setAttribute('fill', 'freeze');
kastart.setAttribute('dur', '2s');
clone.appendChild(kastart);
// 14. 解析與編譯動畫邏輯
function getDeg(start, end) {
let p0 = ["0,1", "1,2", "3,4", "4,5", "5,6", "7,8", "8,9"];
let p120 = ["0,3", "1,4", "2,5", "4,7", "5,8", "6,9"];
let p60 = ["0,4", "1,5", "2,6", "3,7", "4,8", "5,9"];
let k = `${start},${end}`, rk = `${end},${start}`;
if (p0.includes(k)) return "0"; if (p0.includes(rk)) return "180";
if (p120.includes(k)) return "120"; if (p120.includes(rk)) return "300";
if (p60.includes(k)) return "60"; if (p60.includes(rk)) return "240";
return "0";
}
let n = 0;
let last_describe = [];
let bridges_so_far = [];
for (let i = 1; i < history.length; i++) {
let arr = history[i];
if (arr[0] < 0) { // 行動陣列
let code = arr[0];
let menx = n % 2 === 0 ? bmen0 : bmen1;
let tmenx = n % 2 === 0 ? tmen0 : tmen1;
let beginTime = n === 0 ? 'kastart.end+1s' : `kad${n - 1}.end+1s`;
// 15
let setVis = document.createElementNS('http://www.w3.org/2000/svg', 'set');
setVis.setAttribute('attributeName', 'visibility');
setVis.setAttribute('id', `kaj${n}`);
setVis.setAttribute('to', 'visible');
setVis.setAttribute('begin', beginTime);
menx.appendChild(setVis);
if (code >= -5 && code <= -3) {
let routeDots = arr.slice(1);
let pathData = "M " + routeDots.map(d => {
let c = clone.querySelector(`circle[i="${d}"]`);
return `${c.getAttribute('cx')},${c.getAttribute('cy')}`;
}).join(" L ");
// 16
let kapn = document.createElementNS('http://www.w3.org/2000/svg', 'set');
kapn.setAttribute('attributeName', 'd');
kapn.setAttribute('id', `kap${n}`);
kapn.setAttribute('to', pathData);
kapn.setAttribute('begin', `kaj${n}.begin+1s`);
kapn.setAttribute('end', `kam${n}.begin`);
movingroute.appendChild(kapn);
// 17
let old_bridges = [];
if (last_describe && last_describe.length > 2) {
for (let b = 2; b < last_describe.length; b += 2) {
old_bridges.push(`${last_describe[b]},${last_describe[b + 1]}`);
old_bridges.push(`${last_describe[b + 1]},${last_describe[b]}`);
}
}
for (let b = 0; b < routeDots.length - 1; b++) {
let s = routeDots[b], e = routeDots[b + 1];
if (!old_bridges.includes(`${s},${e}`)) {
let deg = getDeg(s, e);
let abIdx = bridges_so_far.length;
if (abIdx < arrowbrgs.length) {
let ab = arrowbrgs[abIdx];
bridges_so_far.push([s, e]);
let ori = origins[abIdx].replace(/px/g, '').trim().replace(/\s+/, ',');
ab.setAttribute('transform', `rotate(${deg} ${ori})`);
let abVis = document.createElementNS('http://www.w3.org/2000/svg', 'set');
abVis.setAttribute('attributeName', 'visibility');
abVis.setAttribute('to', 'visible');
abVis.setAttribute('begin', `kap${n}.begin+0.36s`);
ab.appendChild(abVis);
let abStr = document.createElementNS('http://www.w3.org/2000/svg', 'set');
abStr.setAttribute('attributeName', 'stroke');
abStr.setAttribute('to', '#333');
abStr.setAttribute('begin', `kap${n}.begin+0.36s`);
ab.appendChild(abStr);
// 20 - 新橋還原 stroke
let abStrN = document.createElementNS('http://www.w3.org/2000/svg', 'set');
abStrN.setAttribute('attributeName', 'stroke');
abStrN.setAttribute('to', 'none');
abStrN.setAttribute('begin', `kam${n}.end+1.2s`);
ab.appendChild(abStrN);
}
}
}
// 18
let hideMr = document.createElementNS('http://www.w3.org/2000/svg', 'set');
hideMr.setAttribute('attributeName', 'visibility');
hideMr.setAttribute('to', 'hidden');
hideMr.setAttribute('begin', `kam${n}.begin`);
movingroute.appendChild(hideMr);
let hideBmx = document.createElementNS('http://www.w3.org/2000/svg', 'set');
hideBmx.setAttribute('attributeName', 'visibility');
hideBmx.setAttribute('to', 'hidden');
hideBmx.setAttribute('begin', `kam${n}.begin`);
menx.appendChild(hideBmx);
let showTmx = document.createElementNS('http://www.w3.org/2000/svg', 'set');
showTmx.setAttribute('attributeName', 'visibility');
showTmx.setAttribute('to', 'visible');
showTmx.setAttribute('begin', `kam${n}.begin`);
tmenx.appendChild(showTmx);
let am = document.createElementNS('http://www.w3.org/2000/svg', 'animateMotion');
am.setAttribute('id', `kam${n}`);
am.setAttribute('dur', `${routeDots.length - 1}s`);
am.setAttribute('fill', 'freeze');
am.setAttribute('path', pathData);
tmenx.appendChild(am);
// 19
let hideTmx2 = document.createElementNS('http://www.w3.org/2000/svg', 'set');
hideTmx2.setAttribute('attributeName', 'visibility');
hideTmx2.setAttribute('to', 'hidden');
hideTmx2.setAttribute('begin', `kam${n}.end`);
tmenx.appendChild(hideTmx2);
let showBmx2 = document.createElementNS('http://www.w3.org/2000/svg', 'set');
showBmx2.setAttribute('attributeName', 'visibility');
showBmx2.setAttribute('to', 'visible');
showBmx2.setAttribute('begin', `kam${n}.end`);
menx.appendChild(showBmx2);
// 維持位移目標,不回彈
let endDot = routeDots[routeDots.length - 1];
let endC = clone.querySelector(`circle[i="${endDot}"]`);
let setCX = document.createElementNS('http://www.w3.org/2000/svg', 'set');
setCX.setAttribute('attributeName', 'cx');
setCX.setAttribute('to', endC.getAttribute('cx'));
setCX.setAttribute('begin', `kam${n}.end`);
menx.appendChild(setCX);
let setCY = document.createElementNS('http://www.w3.org/2000/svg', 'set');
setCY.setAttribute('attributeName', 'cy');
setCY.setAttribute('to', endC.getAttribute('cy'));
setCY.setAttribute('begin', `kam${n}.end`);
menx.appendChild(setCY);
// 過橋旋轉
let target_describe = code === -3 ? last_describe : history[i + 1];
for (let b = 0; b < routeDots.length - 1; b++) {
let s = routeDots[b], e = routeDots[b + 1];
let bIdx = -1;
if (target_describe && target_describe.length > 2) {
for (let k = 2; k < target_describe.length; k += 2) {
if ((target_describe[k] === s && target_describe[k + 1] === e) ||
(target_describe[k] === e && target_describe[k + 1] === s)) {
bIdx = (k - 2) / 2;
break;
}
}
}
if (bIdx !== -1 && bIdx < arrowbrgs.length) {
let ab = arrowbrgs[bIdx];
let deg = getDeg(s, e);
let ori = origins[bIdx].replace(/px/g, '').trim().replace(/\s+/, ',');
let rotAnim = document.createElementNS('http://www.w3.org/2000/svg', 'animateTransform');
rotAnim.setAttribute('attributeName', 'transform');
rotAnim.setAttribute('attributeType', 'XML');
rotAnim.setAttribute('type', 'rotate');
rotAnim.setAttribute('from', `${deg} ${ori}`);
rotAnim.setAttribute('to', `${parseInt(deg) + 180} ${ori}`);
rotAnim.setAttribute('dur', '1s');
rotAnim.setAttribute('fill', 'freeze');
rotAnim.setAttribute('begin', `kam${n}.end`);
ab.appendChild(rotAnim);
}
}
// 20
if (code === -3) {
let strk = document.createElementNS('http://www.w3.org/2000/svg', 'set');
strk.setAttribute('id', `kad${n}`);
strk.setAttribute('attributeName', 'stroke');
strk.setAttribute('to', '#e77');
strk.setAttribute('begin', `kam${n}.end+1.2s`);
menx.appendChild(strk);
} else if (code === -4) {
bmen.forEach((bm, bidx) => {
let strk = document.createElementNS('http://www.w3.org/2000/svg', 'set');
strk.setAttribute('id', bidx === 0 ? `kad${n}` : `kad${n}_1`);
strk.setAttribute('attributeName', 'stroke');
strk.setAttribute('to', '#e77');
strk.setAttribute('begin', `kam${n}.end+1.2s`);
bm.appendChild(strk);
});
} else if (code === -5) {
let strk = document.createElementNS('http://www.w3.org/2000/svg', 'set');
strk.setAttribute('id', `kad${n}`);
strk.setAttribute('attributeName', 'stroke');
strk.setAttribute('to', 'none');
strk.setAttribute('begin', `kam${n}.end+1.2s`);
menx.appendChild(strk);
}
} else if (code === -2) { // 21
let strk = document.createElementNS('http://www.w3.org/2000/svg', 'set');
strk.setAttribute('id', `kad${n}`);
strk.setAttribute('attributeName', 'stroke');
strk.setAttribute('to', '#e77');
strk.setAttribute('begin', `kaj${n}.begin+1.2s`);
menx.appendChild(strk);
} else if (code === -1) { // 22
let g = document.createElementNS('http://www.w3.org/2000/svg', 'g');
g.setAttribute('visibility', 'hidden');
let routeDots = arr.slice(1);
for (let l = 0; l < routeDots.length; l += 2) {
let c1 = clone.querySelector(`circle[i="${routeDots[l]}"]`);
let c2 = clone.querySelector(`circle[i="${routeDots[l + 1]}"]`);
let line = document.createElementNS('http://www.w3.org/2000/svg', 'line');
line.setAttribute('x1', c1.getAttribute('cx'));
line.setAttribute('y1', c1.getAttribute('cy'));
line.setAttribute('x2', c2.getAttribute('cx'));
line.setAttribute('y2', c2.getAttribute('cy'));
line.setAttribute('stroke', '#e77');
line.setAttribute('stroke-width', '7');
line.setAttribute('stroke-linecap', 'round');
g.appendChild(line);
}
let setVis = document.createElementNS('http://www.w3.org/2000/svg', 'set');
setVis.setAttribute('id', `kad${n}`);
setVis.setAttribute('attributeName', 'visibility');
setVis.setAttribute('to', 'visible');
setVis.setAttribute('begin', `kaj${n}.begin+1.2s`);
g.appendChild(setVis);
clone.querySelector('.middlearea').appendChild(g);
}
n++;
} else {
last_describe = arr;
}
}
// 23
let kaend = document.createElementNS('http://www.w3.org/2000/svg', 'animate');
kaend.setAttribute('id', 'kaend');
kaend.setAttribute('begin', `kad${n - 1}.end`);
kaend.setAttribute('attributeName', 'opacity');
kaend.setAttribute('values', '1;1;1;1;0');
kaend.setAttribute('fill', 'freeze');
kaend.setAttribute('dur', '4s');
clone.appendChild(kaend);
// 24. 導出並提示
let svgStr = new XMLSerializer().serializeToString(clone);
let blob = new Blob([svgStr], { type: "image/svg+xml" });
let url = URL.createObjectURL(blob);
let a = document.createElement('a');
let d = new Date();
let fName = `konigsber_animate_${d.getFullYear()}${String(d.getMonth() + 1).padStart(2, '0')}${String(d.getDate()).padStart(2, '0')}_${String(d.getHours()).padStart(2, '0')}${String(d.getMinutes()).padStart(2, '0')}${String(d.getSeconds()).padStart(2, '0')}.svg`;
a.href = url;
a.download = fName;
a.click();
URL.revokeObjectURL(url);
let msg = document.createElement('div');
msg.style.position = 'fixed';
msg.style.top = '10px';
msg.style.left = '10px';
msg.style.background = 'rgba(0,0,0,0.8)';
msg.style.color = 'white';
msg.style.padding = '10px 15px';
msg.style.borderRadius = '8px';
msg.style.zIndex = '9999';
msg.style.fontSize = '16px';
msg.innerHTML = `⬇️ 導出成功<br>檔案:${fName}<br>大小:${blob.size} Bytes`;
document.body.appendChild(msg);
setTimeout(() => msg.remove(), 3000);
};
```https://ejsoon.vip/
弈趣極光:享受思維樂趣
弈趣極光:享受思維樂趣
Re: 改下哥尼斯堡網頁程式
代码: 全选
<svg id="konigsberganimate" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="720" height="480" viewBox="0 0 720 480" style="background: lightblue; height: 100%; width: 100%;" opacity="0">
<g class="appendarea">
<circle cx="180.00" cy="48.00" r="24" fill="#fff" stroke="#333" stroke-width="2" i="0" />
<circle cx="360.00" cy="48.00" r="24" fill="#fff" stroke="#333" stroke-width="2" i="1" />
<circle cx="540.00" cy="48.00" r="24" fill="#fff" stroke="#333" stroke-width="2" i="2" />
<circle cx="90.00" cy="203.88" r="24" fill="#e77" stroke="#333" stroke-width="2" i="3" />
<circle cx="270.00" cy="203.88" r="24" fill="#fff" stroke="#333" stroke-width="2" i="4" />
<circle cx="450.00" cy="203.88" r="24" fill="#fff" stroke="#333" stroke-width="2" i="5" />
<circle cx="630.00" cy="203.88" r="24" fill="#fff" stroke="#333" stroke-width="2" i="6" />
<circle cx="180.00" cy="359.77" r="24" fill="#fff" stroke="#333" stroke-width="2" i="7" />
<circle cx="360.00" cy="359.77" r="24" fill="#fff" stroke="#333" stroke-width="2" i="8" />
<circle cx="540.00" cy="359.77" r="24" fill="#fff" stroke="#333" stroke-width="2" i="9" />
<path class="arrowbrg" d="M118,203.88457268119896 v -12 h 100 v -12 l 24 24 l -24 24 v -12 h -100 Z" fill="#C19A6B" stroke="none" stroke-width="2" visibility="hidden" transform="rotate(0 180,203.885)">
<set attributeName="visibility" to="visible" begin="kap0.begin+0.36s" />
<set attributeName="stroke" to="#333" begin="kap0.begin+0.36s" />
<set attributeName="stroke" to="none" begin="kam0.end+1.2s" />
<animateTransform attributeName="transform" attributeType="XML" type="rotate" from="0 180,203.885" to="180 180,203.885" dur="1s" fill="freeze" begin="kam0.end" />
</path>
</g>
<g class="bottomarea">
<circle cx="90.00" cy="203.88" r="24" fill="#e3d" stroke="none" stroke-width="4">
<set attributeName="visibility" id="kaj0aaa" to="visible" begin="kastart.end+1s" />
<set attributeName="stroke" id="kaj0bbb" to="blue" begin="kastart.end+1s" />
<set attributeName="visibility" to="hidden" begin="kam0.begin" />
<set attributeName="visibility" to="visible" begin="kam0.end" />
<set attributeName="cx" to="270.00" begin="kam0.end" />
<set attributeName="cy" to="203.88" begin="kam0.end" />
<set id="kad0" attributeName="stroke" to="none" begin="kam0.end+1.2s" />
</circle>
<circle cx="630.00" cy="203.88" r="24" fill="#3d3" stroke="none" stroke-width="4" />
</g>
<g class="middlearea">
</g>
<path id="movingroute" class="route_tmp hide" d="M90,203.88457268119896 L 270,203.88457268119896 " fill="none" stroke="#333" stroke-linejoin="round" stroke-width="4" stroke-dasharray="12 7" visibility="hidden">
<animate class="dashoffset" attributeName="stroke-dashoffset" values="0;-24000" repeatCount="indefinite" dur="777s" />
<set attributeName="d" id="kap0" to="M 90.00,203.88 L 270.00,203.88" begin="kaj0.begin+1s" end="kam0.begin" />
<set attributeName="visibility" to="hidden" begin="kam0.begin" />
</path>
<g class="toparea">
<circle cx="0" cy="0" r="24" fill="#33d" stroke="lightyellow" stroke-width="4" stroke-dasharray="5 5" visibility="hidden">
<animate class="dashoffset" attributeName="stroke-dashoffset" values="0;-24000" repeatCount="indefinite" dur="777s" />
<set attributeName="visibility" to="visible" begin="kam0.begin" />
<animateMotion id="kam0" dur="1s" fill="freeze" path="M 90.00,203.88 L 270.00,203.88" />
<set attributeName="visibility" to="hidden" begin="kam0.end" />
</circle>
<circle cx="0" cy="0" r="24" fill="#3d3" stroke="lightyellow" stroke-width="4" stroke-dasharray="5 5" visibility="hidden">
<animate class="dashoffset" attributeName="stroke-dashoffset" values="0;-24000" repeatCount="indefinite" dur="777s" />
</circle>
</g>
<animate id="kastart" begin="0s;kaend.end" attributeName="opacity" values="0;0;1" fill="freeze" dur="2s" />
<animate id="kaend" begin="kad0.end" attributeName="opacity" values="1;1;1;1;0" fill="freeze" dur="4s" />
</svg>
https://ejsoon.vip/
弈趣極光:享受思維樂趣
弈趣極光:享受思維樂趣
-
- 相似主题
- 回复总数
- 阅读次数
- 最新帖子
在线用户
正浏览此版面之用户: 没有注册用户 和 4 访客
