跳棋遊戲利用樹構建合法路徑出現迴圈的解決辦法

2021-09-20 18:47:27 字數 1522 閱讀 4165

我在做跳棋遊戲時利用樹來儲存每乙個棋子的合法路徑,構造落點樹時,要求遍歷路徑上每乙個可能的落點。於是出現了乙個尷尬的狀況——三個落點圍成了圈,如下圖。

黑色實心點為棋子位置,三個虛線表示位置為形成迴圈的空位。其他棋子構造合法落點樹時,一旦遍歷到三個位置中的乙個,就會陷入迴圈。因為棋子在三個中的任乙個位置時,其餘兩個點都是合法落點,可以無限跳轉下去,這條路徑會有無限長。

出現這種情況可能是由於我寫的人工智慧演算法不夠機智,後續除錯過程中發現了另外一些類似棋局狀況,即三個空位形成迴圈。

遍歷已經形成的落點樹,重複點捨去,重複次數過多時停止遍歷(未實現)

遍歷已經形成的落點樹顯然是一種明顯思路,但是對於我的程式來說實現較為複雜。

我寫的構造落點樹程式在可以隔一子跳躍時發生遞迴,遞迴後只儲存了部分上一層資料,也就是本次跳躍的起點或者說來路,最多只能追溯兩層資料。然而形成迴圈基本是兩次遍歷以後的結果,即涉及到三層資料,以我現有的程式不滿足直接判斷重複落點的條件。且我也不能排除以後出現四子迴圈出現的可能性。

於是考慮將落點樹改為類中的乙個私有變數,其在方法中的作用範圍類似於全域性變數(為方便表述下文稱其類別為全域性變數)。

但是嘗試後發現,在遞迴中幾乎無法使用這種有層次的全域性變數(有層次的變數即多維變數)。上網搜尋後發現一般遞迴中使用全域性變數都沒有層次,例如利用遞迴求累加和等。

後又嘗試將函式中的變數作為快取,一部分遍歷完成後將結果直接替換到落點樹中。沒寫成。總是會有重複替換,合適的替換位置不存在。

所以從全域性變數的角度來說,遍歷形成的深度是沒有意義的。一維變數更適合作為全域性變數使用。

記錄跳轉次數,跳轉過多時懷疑出現迴圈(已實現)

沒辦法阻止迴圈出現,就在迴圈出現後處理。

我寫的人工智慧太廢柴,所以一般跳轉次數不會太多,但是就算跳轉很多次,有棋盤高度的限制,跳轉次數一般也不會超過20。

跳轉次數基本等同於遞迴次數,所以遞迴次數有乙個上限,我將其設定為10,正常來講我的遞迴次數不會超過10,一旦超過就意味著有異常,我就有理由懷疑出現了迴圈。

確定迴圈出現方法:

我把棋子路徑的六個方向分別標記為1-6,每一次跳轉時記錄跳轉方向,列表儲存,稱其為方向列表。如果出現迴圈,則方向列表中的資料一定有迴圈。

在出現迴圈的基礎上,方向列表中的最後乙個資料一定屬於迴圈資料中的乙個。檢測其出現次數,就算路徑方向集中,同一方向也不應該出現太多次。所以同一資料出現若超過3次,則判定為出現迴圈。

處理迴圈的方法:

返回空列表。(待改進,貌似有些過於簡單粗暴。(但有效))

#懷疑出現迴圈

if firstmove>10:

#最後乙個元素一定在迴圈中,所以確認其數量,過大時確認為迴圈出現

if wayofplace.count(wayofplace[len(wayofplace)-1])>3:

#處理迴圈

return

利用資訊熵構建決策樹

決策樹演算法普遍存在於我們的日常生活中,我們在不經意間就會使用到決策樹。比如你在糾結是否要去一家公司工作時,可能會用到下面的決策樹 整個決策過程是這樣的 如果公司待遇高,你可能就願意去 如果待遇不高,你可能會繼續考慮公司的平台好不好。如果連平台都不好,那就直接拒絕。如果平台很好,你就會繼續考慮自己在...

利用Dockerfile構建映象

dockerfile 是乙個文字檔案,其內包含了一條條的指 instruction 每一條指令構建一層,因此每一條指令的內容,就是描述該層應當如何構建。還以之前定製 nginx 映象為例,這次我們使用 dockerfile 來定製。first dockerfile from ubuntu 14.04...

利用scons構建project

scons有非常多相對於make構建系統的優秀特性,可是因為發展時間比較短如今的應用範圍還是不太多,可以找到的資料也不是非常多。scons如今一大問題就是初始上手還是有點難度的,對於有python的基礎的還是有點問題,畢竟他跟寫成的python還是不一樣的。儘管他遵循了python語言的語法,相同用...