「益智遊戲」和「抽象弈棋」
回复
头像
ejsoon
一枝独秀一枝独秀
帖子: 6827
注册时间: 2022年 11月 18日 17:36
联系:

又有一個新的弈棋創意:拚數棋!

帖子 ejsoon »

代码: 全选

<svg id="etani" version="1.1" xmlns="http://www.w3.org/2000/svg" width="480" height="480" rfm="repeat" viewBox="0 0 480 480" preserveAspectRatio="xMidYMid meet"> <defs mode="0" rotatestep="1" rotatestart="0" stepvalue="45" snapto="0" displaywait="1">   <g id="tile0" frontfill="#4965e4" backfill="#c8d2ff" stroke="#ccc"><path fill="#c8d2ff" d="M -30,-30 L 30,-30 L 30,30 L -30,30 Z"/>
<path fill="none" stroke-width="6" stroke="#4965e4" d="M -26,-26 L 26,-26"/>
<path fill="#4965e4" stroke="none" d="M 0,-12 L 15.588,15 L -15.588,15 Z"/>
</g><g id="tile1" frontfill="#d54730" backfill="#ffc6bd"><path stroke="#ccc" fill="#ffc6bd" d="M -30,-30 L 30,-30 L 30,30 L -30,30 Z"/>
<path fill="none" stroke-width="6" stroke="#d54730" d="M -26,-26 L 26,-26"/>
<path fill="#d54730" stroke="none" d="M 0,-12 L 15.588,15 L -15.588,15 Z"/>
</g><g id="tile2" frontfill="#4965e4" backfill="#c8d2ff" stroke="#ccc"><path fill="#c8d2ff" d="M -30,-30 L 30,-30 L 30,30 L -30,30 Z"/>
<path fill="none" stroke-width="6" stroke="#4965e4" d="M -26,26 L -26,-26 L 26,-26"/>
<path fill="#4965e4" stroke="none" d="M -16.971,-16.971 L 3.106,-11.591 L -11.591,3.106 Z"/>
<path fill="#4965e4" stroke="none" d="M 0,0 L 20.076,5.38 L 5.38,20.076 Z"/>
</g><g id="tile3" frontfill="#d54730" backfill="#ffc6bd" stroke="#ccc"><path fill="#ffc6bd" d="M -30,-30 L 30,-30 L 30,30 L -30,30 Z"/>
<path fill="none" stroke-width="6" stroke="#d54730" d="M -26,26 L -26,-26 L 26,-26"/>
<path fill="#d54730" stroke="none" d="M -16.971,-16.971 L 3.106,-11.591 L -11.591,3.106 Z"/>
<path fill="#d54730" stroke="none" d="M 0,0 L 20.076,5.38 L 5.38,20.076 Z"/>
</g><g id="tile4" frontfill="#4965e4" backfill="#c8d2ff" stroke="#ccc"><path fill="#c8d2ff" d="M -30,-30 L 30,-30 L 30,30 L -30,30 Z"/>
<path fill="none" stroke-width="6" stroke="#4965e4" d="M -26,26 L -26,-26 M 26,26 L 26,-26"/>
<path fill="#4965e4" stroke="none" d="M -18,0 l 12,-12 v 24 Z"/>
<path fill="#4965e4" stroke="none" d="M 18,0 l -12,-12 v 24 Z"/>
</g><g id="tile5" frontfill="#d54730" backfill="#ffc6bd" stroke="#ccc"><path fill="#ffc6bd" d="M -30,-30 L 30,-30 L 30,30 L -30,30 Z"/>
<path fill="none" stroke-width="6" stroke="#d54730" d="M -26,26 L -26,-26 M 26,26 L 26,-26"/>
<path fill="#d54730" stroke="none" d="M -18,0 l 12,-12 v 24 Z"/>
<path fill="#d54730" stroke="none" d="M 18,0 l -12,-12 v 24 Z"/>
</g><g id="tile6" frontfill="#4965e4" backfill="#c8d2ff" stroke="#ccc"><path fill="#c8d2ff" d="M -30,-30 L 30,-30 L 30,30 L -30,30 Z"/>
<path fill="none" stroke-width="6" stroke="#4965e4" d="M -26,26 L -26,-26 L 26,-26 L 26,26"/>
<path fill="#4965e4" stroke="none" d="M -18,12 l 12,-12 v 24 Z"/>
<path fill="#4965e4" stroke="none" d="M 18,12 l -12,-12 v 24 Z"/>
<path fill="#4965e4" stroke="none" d="M 0,-18 l 12,12 h -24 Z"/>
</g><g id="tile7" frontfill="#d54730" backfill="#ffc6bd" stroke="#ccc"><path fill="#ffc6bd" d="M -30,-30 L 30,-30 L 30,30 L -30,30 Z"/>
<path fill="none" stroke-width="6" stroke="#d54730" d="M -26,26 L -26,-26 L 26,-26 L 26,26"/>
<path fill="#d54730" stroke="none" d="M -18,12 l 12,-12 v 24 Z"/>
<path fill="#d54730" stroke="none" d="M 18,12 l -12,-12 v 24 Z"/>
<path fill="#d54730" stroke="none" d="M 0,-18 l 12,12 h -24 Z"/>
</g><g id="tile8" frontfill="#4965e4" backfill="#c8d2ff" stroke="#ccc" stroke-linecap="round"><path fill="#c8d2ff" d="M -30,-30 L 30,-30 L 30,30 L -30,30 Z"/>
<path fill="none" stroke-width="6" stroke="#4965e4" d="M -26,-26 L 26,26 M -26,26 L 26,-26"/>
</g><g id="tile9" frontfill="#d54730" backfill="#ffc6bd" stroke="#ccc" stroke-linecap="round"><path fill="#ffc6bd" d="M -30,-30 L 30,-30 L 30,30 L -30,30 Z"/>
<path fill="none" stroke-width="6" stroke="#d54730" d="M -26,-26 L 26,26 M -26,26 L 26,-26"/>
</g></defs> <g class="etdrop" stroke-linecap="round" stroke="#777" stroke-width="2" stroke-linejoin="round" transform="translate(240,240) scale(1,1)" id="etanidrop"><g class="etboard"><circle r="6" cx="0" cy="0" fill="purple" stroke="none" stroke-width="0" class="bcenter"/><path stroke-width="1" stroke="#aaa" d="&#xA;M -210,-210 L -210,210 L 210,210 L 210,-210 Z&#xA;M -210,-150 h 420 M -210,-90 h 420 M -210,-30 h 420 M -210,30 h 420 M -210,90 h 420 M -210,150 h 420 M -150,-210 v 420 M -90,-210 v 420 M -30,-210 v 420 M 30,-210 v 420 M 90,-210 v 420 M 150,-210 v 420" fill="none" class="boardsnap0"/></g><use href="#tile0" fill="#c8d2ff" transform="translate(60,0) scale(-1,1) rotate(-90)" class="tiledropped"/><use href="#tile1" fill="#d54730" transform="translate(0,60) scale(1,1) rotate(0)" class="tiledropped"/><use href="#tile3" fill="#ffc6bd" transform="translate(60,60) scale(-1,1) rotate(0)" class="tiledropped"/><use href="#tile7" fill="#d54730" transform="translate(-60,60) scale(1,1) rotate(180)" class="tiledropped"/><use href="#tile7" fill="#d54730" transform="translate(0,-60) scale(1,1) rotate(0)" class="tiledropped"/><use href="#tile4" fill="#4965e4" transform="translate(-120,60) scale(1,1) rotate(-90)" class="tiledropped"/><use href="#tile4" fill="#4965e4" transform="translate(120,0) scale(1,1) rotate(-90)" class="tiledropped"/><use href="#tile0" fill="#c8d2ff" transform="translate(-120,-60) scale(-1,1) rotate(0)" class="tiledropped"/><use href="#tile0" fill="#c8d2ff" transform="translate(-120,-120) scale(-1,1) rotate(0)" class="tiledropped"/><use href="#tile0" fill="#c8d2ff" transform="translate(-60,-120) scale(-1,1) rotate(0)" class="tiledropped"/><use href="#tile2" fill="#4965e4" transform="translate(0,0) scale(1,1) rotate(0)" class="tiledropped"/><use href="#tile2" fill="#4965e4" transform="translate(-60,120) scale(1,1) rotate(-90)" class="tiledropped"/><use href="#tile2" fill="#4965e4" transform="translate(120,-60) scale(1,1) rotate(90)" class="tiledropped"/><use href="#tile3" fill="#ffc6bd" transform="translate(60,-60) scale(-1,1) rotate(0)" class="tiledropped"/><use href="#tile3" fill="#ffc6bd" transform="translate(0,-180) scale(-1,1) rotate(90)" class="tiledropped"/><use href="#tile3" fill="#ffc6bd" transform="translate(-120,-180) scale(-1,1) rotate(90)" class="tiledropped"/><use href="#tile3" fill="#ffc6bd" transform="translate(-180,0) scale(-1,1) rotate(90)" class="tiledropped"/><use href="#tile5" fill="#d54730" transform="translate(60,120) scale(1,1) rotate(0)" class="tiledropped"/><use href="#tile5" fill="#d54730" transform="translate(-120,0) scale(1,1) rotate(0)" class="tiledropped"/><use href="#tile5" fill="#d54730" transform="translate(-180,-120) scale(1,1) rotate(0)" class="tiledropped"/><use href="#tile6" fill="#4965e4" transform="translate(-180,-180) scale(1,1) rotate(0)" class="tiledropped"/><use href="#tile6" fill="#4965e4" transform="translate(60,-180) scale(1,1) rotate(0)" class="tiledropped"/><use href="#tile6" fill="#4965e4" transform="translate(60,180) scale(1,1) rotate(180)" class="tiledropped"/><use href="#tile6" fill="#4965e4" transform="translate(-180,60) scale(1,1) rotate(180)" class="tiledropped"/><use href="#tile9" fill="#d54730" transform="translate(180,60) scale(1,1) rotate(0)" class="tiledropped"/><use href="#tile9" fill="#d54730" transform="translate(120,-120) scale(1,1) rotate(0)" class="tiledropped"/><use href="#tile9" fill="#d54730" transform="translate(0,180) scale(1,1) rotate(0)" class="tiledropped"/><use href="#tile8" fill="#4965e4" transform="translate(60,-120) scale(1,1) rotate(0)" class="tiledropped"/><use href="#tile1" fill="#d54730" transform="translate(-180,120) scale(1,1) rotate(-90)" class="tiledropped"/><use href="#tile1" fill="#d54730" transform="translate(-180,180) scale(1,1) rotate(-90)" class="tiledropped"/><use href="#tile1" fill="#d54730" transform="translate(180,0) scale(1,1) rotate(180)" class="tiledropped"/><use href="#tile8" fill="#4965e4" transform="translate(180,120) scale(1,1) rotate(0)" class="tiledropped"/><use href="#tile8" fill="#4965e4" transform="translate(180,180) scale(1,1) rotate(0)" class="tiledropped"/><use href="#tile8" fill="#4965e4" transform="translate(120,180) scale(1,1) rotate(0)" class="tiledropped"/><use href="#tile8" fill="#4965e4" transform="translate(180,-120) scale(1,1) rotate(0)" class="tiledropped"/><use href="#tile7" fill="#d54730" transform="translate(120,-180) scale(1,1) rotate(0)" class="tiledropped"/><use href="#tile7" fill="#d54730" transform="translate(180,-180) scale(1,1) rotate(90)" class="tiledropped"/><use href="#tile9" fill="#d54730" transform="translate(-120,120) scale(1,1) rotate(0)" class="tiledropped"/><use href="#tile5" fill="#d54730" transform="translate(-120,180) scale(1,1) rotate(-90)" class="tiledropped"/><use href="#tile2" fill="#4965e4" transform="translate(-60,-180) scale(1,1) rotate(0)" class="tiledropped"/><use href="#tile4" fill="#4965e4" transform="translate(0,-120) scale(1,1) rotate(0)" class="tiledropped"/><use href="#tile5" fill="#d54730" transform="translate(-60,-60) scale(1,1) rotate(-90)" class="tiledropped"/><use href="#tile6" fill="#4965e4" transform="translate(120,120) scale(1,1) rotate(90)" class="tiledropped"/><use href="#tile2" fill="#4965e4" transform="translate(-180,-60) scale(1,1) rotate(0)" class="tiledropped"/><use href="#tile0" fill="#c8d2ff" transform="translate(-60,0) scale(-1,1) rotate(180)" class="tiledropped"/><use href="#tile1" fill="#d54730" transform="translate(120,60) scale(1,1) rotate(90)" class="tiledropped"/><use href="#tile4" fill="#4965e4" transform="translate(0,120) scale(1,1) rotate(90)" class="tiledropped"/><use href="#tile4" fill="#c8d2ff" transform="translate(-60,180) scale(-1,1) rotate(180)" class="tiledropped"/><use href="#tile7" fill="#d54730" transform="translate(180,-60) scale(1,1) rotate(90)" class="tiledropped"/></g></svg>
SVG preview
https://ejsoon.vip/
金梭越空:極速暢遊天地
头像
ejsoon
一枝独秀一枝独秀
帖子: 6827
注册时间: 2022年 11月 18日 17:36
联系:

Re: 又有一個新的弈棋創意:拚數棋!

帖子 ejsoon »

遊戲規則

簡介:拚數棋是一款二人弈棋(抽象策略遊戲)。雙方你中有我,我中有你,建牆之後又拆牆,相當有趣!

目標:

雙方比拚多個區域內的數字,數字之差將作為得分。雙方互換先後手玩兩局,總分高者獲勝。

棋子:

本棋共有五種棋子,每方每種棋子有五個。

這五種棋子分別為「單一、雙二、角二、網三、叉零」:

「單一」是一個正方形有一條實邊和一個三角形;
「雙二」是一個正方形有兩條分開的實邊和兩個三角形;
「角二」是一個正方形有兩條相連實邊和兩個三角形;
「圍三」是一個正方形有三條實邊和三個三角形;
「零叉」是一個正方形內部兩條對角線交叉。

棋盤:

七乘七方格,中間的格子上有圓點標記。

棋規:

落子規則:

先手第一手棋一定要用「角二」下到棋盤中心位置,此後雙方輪流落子。要求落下的棋子要跟場上已有的棋子相鄰,但實邊不能相鄰。不能形成空洞。先手方必須落完二十五個棋子,後手方要落下二十四個棋子,最後剩下的棋子不能是「叉零」。

提子規則:

落子結束後開始提子,由後手方先提子,任意選取一個己方棋子,按它上面的三角形指向行動,單一則走一步,雙二則選擇兩個方向的其中一個走一步,角二則選擇斜向一步或兩步,圍三則三個方向選一個走一步,一直走到一個己方的「叉零」。不能走到沒有棋子的空位上或對方的「叉零」,也不能走出棋盤邊界。如果選取的是「叉零」則直接完成本次提子。把這些棋子拿在手上,之後輪到先手方提子。雙方輪流提完五個「叉零」,則本局結束。

計分規則:

當落子階段結束,實邊圍成的一個區域內,一方的三角形數量減去另一方的三角形數,結果即為這一方在本區域的得分。當一個區域只有一方棋子,則不能計分,必須是比拚過雙方三角形數量的區域才可計分。如果是通向棋盤外的區域,則視為同一區域。在計完落子階段的分數後,才能開始提子,然後再計提子分數。一方每回合所提的棋子中,己方棋子的三角形數量減去對方的棋子的三角形數量,則是本回合提子得分,如果只包含本方棋子則不能得分。

勝負判定:

雙方玩兩局,最終分數為正整數者獲勝。

在任意一局中,如果一方不能按規則落子或提子,則直接判負。

規則介紹完畢。
上次由 ejsoon 在 2026年 9月 19日 13:41,总共编辑 4 次。
https://ejsoon.vip/
金梭越空:極速暢遊天地
头像
ejsoon
一枝独秀一枝独秀
帖子: 6827
注册时间: 2022年 11月 18日 17:36
联系:

Re: 又有一個新的弈棋創意:拚數棋!

帖子 ejsoon »

代码: 全选

製作遊戲《拚數棋》
遊戲規則

拚數棋是一個二人弈棋,即二人抽象策略遊戲。

目標:

雙方比拚多個區域內的數字,數字大的一方則可得分。雙方互換先後手玩兩局,總分高者獲勝。

棋子:

本棋共有五種棋子,每方每種棋子有五個。

這五種棋子分別為「單一、雙二、角二、網三、叉零」:

「單一」是一個正方形有一條實邊和一個三角形;
「雙二」是一個正方形有兩條分開的實邊和兩個三角形;
「角二」是一個正方形有兩條相連實邊和兩個三角形;
「圍三」是一個正方形有三條實邊和三個三角形;
「零叉」是一個正方形內部兩條對角線交叉。

棋盤:

七乘七方格,中間的格子上有圓點標記。

棋規:

落子規則:

先手第一手棋一定要用「角二」下到棋盤中心位置,此後雙方輪流落子。要求落下的棋子要跟場上已有的棋子相鄰,但實邊不能相鄰。不能形成空洞。先手方必須落完二十五個棋子,後手方要落下二十四個棋子。

提子規則:

落子結束後開始提子,由後手方先提子,任意選取一個非「叉零」的己方棋子,按它上面的三角形指向行動,單一則走一步,雙二則選擇兩個方向的其中一個走一步,角二則選擇斜向一步或兩步,圍三則三個方向選一個走一步,一直走到一個己方的「叉零」。把這些棋子拿在手上,之後輪到先手方提子。不能走到沒有棋子的空位上,當走出邊界則會從另一邊回來,上下、左右是打通的。

計分規則:

當落子階段結束,實邊圍成的一個區域內,一方的三角形數量減去另一方的三角形數,結果即為這一方在本區域的得分。當一個區域只有一方棋子,則不能計分,必須是比拚過雙方三角形數量的區域才可計分。如果是通向棋盤外的區域,則視為同一區域。在計完落子階段的分數後,才能開始提子,然後再計提子分數。一方所提的棋子中,己方棋子的三角形數量減去對方的棋子的三角形數量,則是提子得分。在落子階段結束時,後手方會剩下一個棋子,這個棋子也將計到提子階段的得分。

勝負判定:

雙方玩兩局,最終分數超過對方者獲勝。

在任意一局中,如果一方不能按規則落子或提子,則直接判負。

規則介紹完畢,下面是程式製作要求:

棋盤和棋子的svg已在附件中給出,在defs中的g#tile(n)就是棋子,n為偶數就是玩家一的棋子,奇數則是玩家二的棋子。

在整個遊戲介面中,中間區域是棋盤區,棋盤區的上方是消息欄,下方是工具欄,棋盤svg置於中間,保持高寬相等,盡量放大,但不要被上下兩欄擋住。電腦端右邊(手機端下邊)是玩家一的控制區,電腦端左邊(手機端上邊)是玩家二控制區。

控制區中有「分數、五種棋子及其數量、AI和人類切換按鈕」,每個棋子都用調用defs中的棋子定義通過use引用,當點擊會選中這個棋子,再點擊棋盤的一個位置則會落下這個棋子。每個棋子按鈕將分成四個區,點擊一個區則可使其實邊最多的部分轉至這個方向,「單一、雙二、圍三」用叉形來分區,「角二」用十字形來分區。

在電腦端,控制區中的按鈕將是縱向排列,玩家一的棋子數量顯示在棋子右方,玩家二的棋子數量顯示在棋子左方。在手機端,控制區中的按鈕將是横向排列,玩家一和玩家二的棋子數量都顯示在棋子下方。

分數將從第一手棋開始計,當一方為正分,則另一方為負分,數字應是相同的。

點擊「AI與人類切換按鈕」會在「人類、簡單AI、困難AI、專家AI、自訂AI」之間切換,玩家一默認是人類,玩家二默認是簡單AI。

消息欄會顯示「第幾回合、當前輪到哪一方」,如果落子或提子選取錯誤,則會給出提示(比如:先手第一手棋必須用「角二」落在棋盤中心、每一手棋都要跟場上已有棋子貼合、棋子之間的實邊不能重合、棋子不能形成空洞),當一方因為無法合規落子或提子則提示「因為……玩家一或二直接判負」。

工具欄有「回退、前進、AI設置、導出棋譜、下載svg、自動旋轉」,每一個都是svg按鈕,其中「回退、前進」當能點擊時會高亮,AI設置、導出棋譜、下載svg、恢復窗口會始終高亮,自動旋轉會在點擊時切換高亮。

回退和前進是雙方行動的撤銷與重做。當進入提子階段,如果一方提了至少一個棋子,點擊回退則會回到提子前。當進入第二局,仍可回退到第一局的終局狀態。

AI設置可為雙方選擇人類及各等級AI,下方是對應的思考時間輸入框,簡單AI是3s,困難是6s,專家是12秒,自訂是24秒。當修改時間輸入框內的值時,上方的AI等級會對應切換,如果沒有對應的,則會切換至自訂。

導出棋譜和下載svg功能將在以後介紹。

當自動旋轉按鈕激活時,輪到玩家二,雙方的控制區會旋轉一百八十度,消息欄和工具欄也會以棋盤為中心旋轉一百八十度。

當遊戲下到一局結束時,或某一方因為無法合規行動而判負時,會自動彈出雙方的勝負窗口(雙方在落子和提子階段的得分),這個窗口的右上角會有關閉窗口的svg叉形按鈕,當關閉按鈕後,點擊消息欄或棋盤的任意區域會再次彈出這個窗口。如果是第一局結束,會有兩個按鈕「雙方互換先後手再玩一局」和「結束遊戲」,第二局結束則會有兩局的總分以及「重新開始遊戲」按鈕。

為本遊戲加上MCTS,要寫成javascript/worker,歸一化。當MCTS搜尋時,消息欄將精簡顯示思考用時和搜尋數量,每0.1s更新一次。當思考結束開始行動時,消息欄要精簡給出「總用時、總搜尋量、期望、勝率」,過2秒後恢復到一般的回合提示。

當打開頁面要有一個美觀的開始介面,元素包括「大標題」(拚數棋)(Battle Number),「小標題」(在七乘七格子中的二人弈棋),「中文︱English」語言切換(為本遊戲的所有窗口和文字添加多國語言),「規則介紹」按鈕(只需要文字,不用邊框,點擊它會彈出規則介紹窗口),「開始遊戲」按鈕。

回答要求:把所有代碼都寫到一個html中,適配電腦端和手機端。
https://ejsoon.vip/
金梭越空:極速暢遊天地
头像
ejsoon
一枝独秀一枝独秀
帖子: 6827
注册时间: 2022年 11月 18日 17:36
联系:

Re: 又有一個新的弈棋創意:拚數棋!

帖子 ejsoon »

拚數棋|Battle Number.jpg
拚數棋|Battle Number.jpg (208.27 KiB) 查看 36 次
現在做一款遊戲,早上有想法,中午就做好了。
附件
battlenumber.html.7z
(25.35 KiB) 已下载 1 次
https://ejsoon.vip/
金梭越空:極速暢遊天地
头像
ejsoon
一枝独秀一枝独秀
帖子: 6827
注册时间: 2022年 11月 18日 17:36
联系:

Re: 又有一個新的弈棋創意:拚數棋!

帖子 ejsoon »

代码: 全选

改進
最新遊戲規則為:

遊戲規則

拚數棋是一款二人弈棋,即二人抽象策略遊戲。

目標:

雙方比拚多個區域內的數字,數字之差將作為得分。雙方互換先後手玩兩局,總分高者獲勝。

棋子:

本棋共有五種棋子,每方每種棋子有五個。

這五種棋子分別為「單一、雙二、角二、網三、叉零」:

「單一」是一個正方形有一條實邊和一個三角形;
「雙二」是一個正方形有兩條分開的實邊和兩個三角形;
「角二」是一個正方形有兩條相連實邊和兩個三角形;
「圍三」是一個正方形有三條實邊和三個三角形;
「零叉」是一個正方形內部兩條對角線交叉。

棋盤:

七乘七方格,中間的格子上有圓點標記。

棋規:

落子規則:

先手第一手棋一定要用「角二」下到棋盤中心位置,此後雙方輪流落子。要求落下的棋子要跟場上已有的棋子相鄰,但實邊不能相鄰。不能形成空洞。先手方必須落完二十五個棋子,後手方要落下二十四個棋子,最後剩下的棋子不能是「叉零」。

提子規則:

落子結束後開始提子,由後手方先提子,任意選取一個己方棋子,按它上面的三角形指向行動,單一則走一步,雙二則選擇兩個方向的其中一個走一步,角二則選擇斜向一步或兩步,圍三則三個方向選一個走一步,一直走到一個己方的「叉零」。不能走到沒有棋子的空位上,也不能走出棋盤邊界。如果選取的是「叉零」則直接完成本次提子。把這些棋子拿在手上,之後輪到先手方提子。雙方輪流提完五個「叉零」,則本局結束。

計分規則:

當落子階段結束,實邊圍成的一個區域內,一方的三角形數量減去另一方的三角形數,結果即為這一方在本區域的得分。當一個區域只有一方棋子,則不能計分,必須是比拚過雙方三角形數量的區域才可計分。如果是通向棋盤外的區域,則視為同一區域。在計完落子階段的分數後,才能開始提子,然後再計提子分數。一方每回合所提的棋子中,己方棋子的三角形數量減去對方的棋子的三角形數量,則是本回合提子得分,如果只包含本方棋子則不能得分。

勝負判定:

雙方玩兩局,最終分數為正整數者獲勝。

在任意一局中,如果一方不能按規則落子或提子,則直接判負。

規則介紹完畢,下面說明這版規則跟上一版的區別:

在落子階段,後手方最後剩下的棋子不能是「叉零」。去掉「在落子階段結束時,後手方會剩下一個棋子,這個棋子也將計到提子階段的得分」這條規則,這個棋子將不再參與計分。

在提子階段,每方可以任意選擇一個己方棋子,包括「叉零」。去掉「當走出邊界則會從另一邊回來,上下、左右是打通的」這條規則,邊界將不再打通。之前的提子只有一輪,現在要進行五輪,雙方要把己方所有的「叉零」都提走。每回合的提子都獨立計分,並且要包含對方的棋子,否則不能計分。

回答要求:明確給出所要修改的地方和所要替換的代碼。
https://gpt.quanquan.space/share/cmhERc ... kCKOHbiAQ8
附件
battlenumber21.html.7z
(26.59 KiB) 已下载 1 次
上次由 ejsoon 在 2026年 9月 19日 16:17,总共编辑 1 次。
https://ejsoon.vip/
金梭越空:極速暢遊天地
头像
ejsoon
一枝独秀一枝独秀
帖子: 6827
注册时间: 2022年 11月 18日 17:36
联系:

Re: 又有一個新的弈棋創意:拚數棋!

帖子 ejsoon »

簡介:拚數棋是一款二人弈棋(抽象策略遊戲)。雙方你中有我,我中有你,建牆之後又拆牆,相當有趣!
https://ejsoon.vip/
金梭越空:極速暢遊天地
头像
ejsoon
一枝独秀一枝独秀
帖子: 6827
注册时间: 2022年 11月 18日 17:36
联系:

Re: 又有一個新的弈棋創意:拚數棋!

帖子 ejsoon »

不能走到沒有棋子的空位上或對方的「叉零」,也不能走出棋盤邊界。
https://ejsoon.vip/
金梭越空:極速暢遊天地
头像
ejsoon
一枝独秀一枝独秀
帖子: 6827
注册时间: 2022年 11月 18日 17:36
联系:

Re: 又有一個新的弈棋創意:拚數棋!

帖子 ejsoon »

之前在落子階段的計分規則為:「如果是通向棋盤外的區域,則視為同一區域。」
現在要改成:「如果是通向棋盤外的區域,則將不計分。」

包括規則說明、計分邏輯、AI思考等都要修改,明確給出所要修改的地方和所要替換的代碼。

代码: 全选

需要修改 **4 個必要位置**:中文版規則、英文版規則、主程式計分、MCTS Worker 計分。另建議更新棋譜中的規則版本。

關鍵點是:**不要刪除把邊界格連到 `outside` 節點的程式**。這些聯集操作仍然需要,用來辨認哪些區域通向棋盤外;只需在最後計分時跳過該區域。

---

# 一、修改 MCTS Worker 的計分邏輯

位置在:

```html
<script id="mctsWorkerSource" type="text/plain">
```

中的:

```js
function regionScore(board) {
```

這個函數供 MCTS AI 模擬棋局及評估分數使用。

## 找到原本這段

```js
let score = 0;

for (const group of groups.values()) {
  if (group.owners[0] && group.owners[1]) {
    score += group.triangles[0] - group.triangles[1];
  }
}

return score;
```

## 替換為

```js
// 所有能通向棋盤外的格子都會與 outside 屬於同一集合。
// 新規則下,這個區域完全不參與計分。
const outsideRoot = find(outside);

let score = 0;

for (const [root, group] of groups.entries()) {
  if (root === outsideRoot) {
    continue;
  }

  if (group.owners[0] && group.owners[1]) {
    score += group.triangles[0] - group.triangles[1];
  }
}

return score;
```

修改後,AI 模擬落子時會:

- 忽略所有通向棋盤外的區域;
- 只評估封閉區域;
- 封閉區域仍須同時包含雙方棋子才計分。

---

# 二、修改主遊戲的計分邏輯

位置在後面的主程式:

```html
<script>
(() => {
```

中的:

```js
function calculatePlacementScore(board) {
```

這個函數負責:

- 畫面即時分數;
- 落子階段最終分數;
- 結果視窗;
- 備用 AI 的落子判斷。

## 找到原本這段

```js
let score = 0;

for (const group of groups.values()) {
  if (group.owners[0] && group.owners[1]) {
    score += group.triangles[0] - group.triangles[1];
  }
}

return score;
```

## 替換為

```js
// 找出與棋盤外相連的區域。
// 新規則:任何通向棋盤外的區域均不計分。
const outsideRoot = find(outside);

let score = 0;

for (const [root, group] of groups.entries()) {
  if (root === outsideRoot) {
    continue;
  }

  if (group.owners[0] && group.owners[1]) {
    score += group.triangles[0] - group.triangles[1];
  }
}

return score;
```

---

# 三、不要修改或刪除邊界聯集程式

在 Worker 的 `regionScore()` 和主程式的 `calculatePlacementScore()` 中,都有以下類似程式:

```js
if (r === 0 && !hasEdge(board[i], 0)) union(i, outside);
if (c === N - 1 && !hasEdge(board[i], 1)) union(i, outside);
if (r === N - 1 && !hasEdge(board[i], 2)) union(i, outside);
if (c === 0 && !hasEdge(board[i], 3)) union(i, outside);
```

以及主程式版本:

```js
if (row === 0 && !tileHasEdge(board[index], 0)) {
  union(index, outside);
}

if (col === N - 1 && !tileHasEdge(board[index], 1)) {
  union(index, outside);
}

if (row === N - 1 && !tileHasEdge(board[index], 2)) {
  union(index, outside);
}

if (col === 0 && !tileHasEdge(board[index], 3)) {
  union(index, outside);
}
```

這些程式應當保留。

它們現在的用途從「把所有外部區域合併後計分」,改為「標記所有外部區域,最後統一排除」。

---

# 四、修改中文版規則說明

位置:

```js
const RULE_SECTIONS = {
  zh: [
```

找到中文的:

```js
{
  title: "計分",
  html: `
    <p><strong>落子分:</strong>實邊把棋盤分成多個區域。通向棋盤外的部分視為同一區域。只有同時含有雙方棋子的區域才計分;玩家一三角形數減去玩家二三角形數,就是玩家一在該區域的淨分,玩家二取得相反分數。</p>
    <p><strong>提子分:</strong>每一個提子回合獨立計分。己方棋子的三角形數量減去對方棋子的三角形數量,就是該回合的提子分。如果該回合只提到本方棋子,則該回合得零分。</p>
  `
},
```

## 替換為

```js
{
  title: "計分",
  html: `
    <p><strong>落子分:</strong>實邊把棋盤分成多個區域。任何通向棋盤外的區域均不計分。只有封閉且同時含有雙方棋子的區域才計分;玩家一的三角形數量減去玩家二的三角形數量,就是玩家一在該區域的淨分,玩家二取得相反分數。如果封閉區域內只有一方的棋子,該區域同樣不計分。</p>
    <p><strong>提子分:</strong>每一個提子回合獨立計分。己方棋子的三角形數量減去對方棋子的三角形數量,就是該回合的提子分。如果該回合只提到本方棋子,則該回合得零分。</p>
  `
},
```

如果目前檔案仍使用原始舊版提子文字,也可以只替換落子分段:

## 原文字

```html
<p><strong>落子分:</strong>實邊把棋盤分成多個區域。通向棋盤外的部分視為同一區域。只有同時含有雙方棋子的區域才計分;玩家一三角形數減去玩家二三角形數,就是玩家一在該區域的淨分,玩家二取得相反分數。</p>
```

## 替換為

```html
<p><strong>落子分:</strong>實邊把棋盤分成多個區域。任何通向棋盤外的區域均不計分。只有封閉且同時含有雙方棋子的區域才計分;玩家一的三角形數量減去玩家二的三角形數量,就是玩家一在該區域的淨分,玩家二取得相反分數。如果封閉區域內只有一方的棋子,該區域同樣不計分。</p>
```

---

# 五、修改英文版規則說明

位置:

```js
en: [
```

找到:

```js
{
  title: "Scoring",
  html: `
    <p><strong>Placement:</strong> solid edges divide the board into regions. All openings leading outside the board belong to one outside region. A region scores only when it contains pieces belonging to both players. Player One's triangles minus Player Two's triangles is Player One's net score; Player Two receives the opposite score.</p>
    <p><strong>Extraction:</strong> every extraction turn is scored separately. Friendly triangles minus opposing triangles is the score for that turn. If the extracted path contains only friendly pieces, that turn scores zero.</p>
  `
},
```

## 替換為

```js
{
  title: "Scoring",
  html: `
    <p><strong>Placement:</strong> solid edges divide the board into regions. Any region connected to the outside of the board does not score. Only an enclosed region containing pieces belonging to both players scores. Player One's triangles minus Player Two's triangles is Player One's net score, and Player Two receives the opposite score. An enclosed region containing pieces from only one player also scores zero.</p>
    <p><strong>Extraction:</strong> every extraction turn is scored separately. Friendly triangles minus opposing triangles is the score for that turn. If the extracted path contains only friendly pieces, that turn scores zero.</p>
  `
},
```

如果仍使用原始提子文字,只需要將原英文落子分段:

```html
<p><strong>Placement:</strong> solid edges divide the board into regions. All openings leading outside the board belong to one outside region. A region scores only when it contains pieces belonging to both players. Player One's triangles minus Player Two's triangles is Player One's net score; Player Two receives the opposite score.</p>
```

替換為:

```html
<p><strong>Placement:</strong> solid edges divide the board into regions. Any region connected to the outside of the board does not score. Only an enclosed region containing pieces belonging to both players scores. Player One's triangles minus Player Two's triangles is Player One's net score, and Player Two receives the opposite score. An enclosed region containing pieces from only one player also scores zero.</p>
```

---

# 六、AI 相關程式不需要再修改其他位置

修改 Worker 的 `regionScore()` 後,MCTS AI 的整條計算鏈會自動使用新規則:

```text
applyAction()
  → regionScore()
  → next.ps
  → normalizedEvaluation()
  → MCTS 搜尋結果
```

原本 Worker 中:

```js
next.ps = regionScore(next.board);
```

應保留,不需要更改。

原本:

```js
function normalizedEvaluation(s, rootPlayer) {
  let score = s.ps + s.raw[0] - s.raw[1];
```

也不需要更改,因為 `s.ps` 現在已經是不包含外部區域的落子分數。

備用 AI 的程式:

```js
const p1Score = calculatePlacementScore(board);
```

同樣不需要更改,因為主程式的 `calculatePlacementScore()` 已經使用新規則。

因此兩類 AI 都已涵蓋:

| AI 類型 | 使用的函數 | 修改位置 |
|---|---|---|
| MCTS Worker AI | `regionScore()` | 第一項 |
| Worker 失敗時的備用 AI | `calculatePlacementScore()` | 第二項 |

---

# 七、建議更新棋譜中的規則版本

這項不是計分運作的必要條件,但可避免新舊規則的棋譜混淆。

在 `exportRecord()` 的:

```js
const payload = {
  game: "Battle Number",
  version: 2,
```

如果之前已按新版規則改成 `version: 2`,現在建議替換為:

```js
const payload = {
  game: "Battle Number",
  version: 3,
  ruleset: "outside-regions-do-not-score",
```

如果目前仍然是:

```js
version: 1,
```

也可以直接替換成:

```js
version: 3,
ruleset: "outside-regions-do-not-score",
```

完整相關部分例如:

```js
const payload = {
  game: "Battle Number",
  version: 3,
  ruleset: "outside-regions-do-not-score",
  exportedAt: new Date().toISOString(),
  language,
  controllers: controllers.slice(),
  aiTimes: aiTimes.slice(),
  currentRound: state.round,
  status: state.status,
  completedRounds: allAvailableSummaries(),
  actions: state.record
};
```

---

# 八、修改後的計分結果

新的落子計分條件如下:

| 區域情況 | 是否計分 |
|---|---:|
| 通向棋盤外,含雙方棋子 | 不計分 |
| 通向棋盤外,只含一方棋子 | 不計分 |
| 封閉,含雙方棋子 | 計分 |
| 封閉,只含一方棋子 | 不計分 |
| 封閉,不含棋子 | 不計分 |

計分仍是:

```js
group.triangles[0] - group.triangles[1]
```

但只會對「**封閉且含有雙方棋子**」的區域執行。

---

# 九、修改後應測試的情況

建議至少測試以下四種棋局:

1. **棋盤邊緣的開放區域同時有雙方棋子**  
   預期:該區域為零分。

2. **完全被實邊封閉的區域同時有雙方棋子**  
   預期:按雙方三角形數量之差計分。

3. **完全封閉,但只有一方棋子**  
   預期:零分。

4. **相同棋局交給 AI 思考**  
   預期:畫面分數、備用 AI 評估及 MCTS AI 評估均不再把外部區域算入分數。
https://ejsoon.vip/
金梭越空:極速暢遊天地
头像
ejsoon
一枝独秀一枝独秀
帖子: 6827
注册时间: 2022年 11月 18日 17:36
联系:

Re: 又有一個新的弈棋創意:拚數棋!

帖子 ejsoon »

當前的計分規則仍然有誤,檢查代碼,看當前是怎麼看待「叉零」棋子在構建圍牆時的作用,「叉零」應相當於一個「能與任何棋子相鄰的四面都是實邊」的棋子。同時檢查計分還可能在哪裡出錯,以及解決在undo和redo時,計分更新狀態出錯的問題。

https://gpt.quanquan.space/share/AFpLdS ... y5ihEoP_Ls
https://ejsoon.vip/
金梭越空:極速暢遊天地
头像
ejsoon
一枝独秀一枝独秀
帖子: 6827
注册时间: 2022年 11月 18日 17:36
联系:

Re: 又有一個新的弈棋創意:拚數棋!

帖子 ejsoon »

規則增加兩條
一是在落子階段的計分規則,之前通往棋盤邊界的區域都不計分,現在要改成棋盤邊界也將跟棋子的實邊一樣,能圍成一個計分的區域。
二是在提子階段,當一個方向上出現空位時,將可越過空位,走到這個方向上最近的棋子。

當AI在提子階段時,它要每777ms逐一選取棋子。

在消息欄中,把玩家一或玩家二後面的括號「先手」或「後手」,替換成括號「落子階段」或「提子階段」,把其下方的「落子階段」或「提子階段」去掉。消息欄應始終只有一行。
附件
battlenumber221.html.7z
(27.23 KiB) 尚未被下载
https://ejsoon.vip/
金梭越空:極速暢遊天地
回复
  • 相似主题
    回复总数
    阅读次数
    最新帖子

在线用户

正浏览此版面之用户: Semrush [Bot] 和 13 访客