立體五子棋中的乙個有趣的bug

2022-04-10 02:17:54 字數 1199 閱讀 7883

跟隨鄒老師在msra的ustc軟體工程課程中有乙個有趣的作業,實現乙個立體的棋類遊戲,可以兩個對戰也可以人機對戰,覺得想法非常有創意,非常有興趣,也是為了藉機學習一下silverlight,就開始編寫乙個立體五子棋。大概進展是這樣的:

乙個星期:學習silverlight,熟悉vs環境

乙個星期半:編寫乙個立體的人機互動介面,但不會旋轉,可以在上面下棋,並判斷輸贏,關鍵是解決在模型層面立體棋盤上座標系及正負位移統一表示的問題。

乙個半星期:編寫初步的博弈樹演算法,可以實現人機對弈,但機器屬於「防守型」的選手,只會防守,不會進攻,即使防守,高超的技藝也不會,雖然能抵擋一陣,但最終被人所擊敗。

乙個半星期:暫時擱置ai,研究如何讓立體棋盤旋轉起來,走了許多彎路,主要是對投影中繞z軸旋轉的問題不很清楚,最後只實現了繞乙個自由度的旋轉,如不借助第三方控制項,用silverlight實現三個自由度的旋轉有一定的難度。

半個星期:回頭改進ai,加入剪枝技術和新的模式,經過改進機器的棋藝果然有了很大提高,會主動進攻了,與之博弈,稍不留神就被他贏了。但這時卻出現了乙個奇怪的bug,困擾了很久。。。。。。

如圖所示:

在該棋局中,機器持白棋后行,很成功地斷掉敵人的「雙衝四」的陰謀,非常成功。

但接下來。。。。。。

卻出現了黑棋活三,白棋竟然不知道斷!

但這是最基本的常識,早已解決了,並驗證通過了,為什麼在這裡卻沒有發現活三呢!

經過長期的除錯,終於發現原來這並不是程式的問題,而是對五子棋的業務不夠了解造成的。五子棋規則中明確給出了黑棋的禁手,用於抵銷黑棋先行的優勢。雙活三,雙活四等都屬於禁手,若黑棋下了禁手,並被對方發現,反而判定為輸。 這就避免了白棋很快被搞死。

五子棋禁手詳見:

由於不知規則,將禁手作為規則編入程式,這就可以解釋為什麼機器連最起碼的活三都不知道救了。

原來,在當前的情況下,白棋實際上是又向下考慮了一步:如果救了活三,黑棋最壞的情況是又做了一雙活三,也是死棋(按照給他程式設計的邏輯),等死,還不如冒險做個白活三呢,如對方看不到,我就搞死他。。。。。。

看來五子棋裡面有很多玄妙的地方,不像原先想象的大眾都會玩的簡單棋類,這就是它為什麼也像圍棋一樣也分段位的原因吧。

下五子棋的bot 五子棋演算法

include include include include include include jsoncpp json.h c 編譯時預設包含此庫 define n 7 每個節點的分支數 以下為各棋型的識別碼 權重 define win 1 4000 define lose 2 4000 defi...

乙個簡單的JAVA五子棋

參照書本寫了乙個很簡單的五子棋程式 主要有如下功能 1 初始化棋盤initboard 2 下棋play 未完成的功能 1 沒有實現棋子ai 2 沒有實現連機 3 ui可以繼續優化 個人感覺五子棋只有在判斷輸贏的演算法上稍微需要思考一下,別的地方都可以參考書本或者網路自己完成。具體如下 1 首先定義一...

乙個連珠五子棋的演算法

為了實現連珠六子及六子以上自殺的功能,中間沒有使用break及return 語句,執行效率有所降低。注 1 使用的是c 語法。2 如果 五 子 六 子 連 按自殺處理。3 三三禁軍功能還沒有實現,以後會進一步完善。晚輩學習c 的時間不長,還望前輩們多多指教。是否贏 棋盤中的所有棋子 所下棋子的最後乙...