演算法實作自動掃雷游戲
1.游戲的構思
2.演算法偽代碼的實作
3.演算法的實作
1.首先需要建立起游戲的整個框架(棋盤的繪制,地雷的生成,基本函式的實作等)
2.構思AI演算法的大概樣貌(先嘗試寫偽碼)
void AI() //AI演算法
if(First)
SelectRandomPos()//游戲開始隨機選擇一處位置翻開
SelectPos()//根據已有條件選擇最佳翻開位置
if(!GameOver)
AI()//遞回繼續進行選擇,直到游戲結束
3.簡單的偽碼寫好后,接下來應該來思考如何具體實作這一演算法
3.1對于SelectRandomPos()實作隨機位置,我們可以使用
Col = (rand())%ColNum;
Row = (rand())%RowNum;//Col,Row為隨機翻開的行列坐標
//ColNum和RowNum為總的行列數
//注意這里的隨機為偽隨機,要想真正接近隨機可以使用下面這段代碼
srand((unsigned int)(time(NULL)));
int k = (rand())%25;
int l = (rand())%14;
參考:用時間做種子生成亂數
實作這一函式功能
3.2對于函式SelectPos(),這是我們的重頭戲,這個函式我們的作用是實作選擇最佳翻開位置,在我們不知道當前位置是否有雷的情況下,那么我們去選擇呢?我們需要將問題數字化,定義一個指數來判斷,是否應該翻開當前位置,而概率則可充當這一任務,
我們知道當第一次翻開時,我們是隨機的,那么第二次我們就可以根據我們已知的條件來判斷了,例如當前
對于當前情況我們需要分析當前點周圍出現地雷的概率

周圍有Count個點未被翻開,而周圍顯示有N個地雷,所以我們可以知道
P=N%Count,得到概率為0.25,注意此處N,P,Count應該定義為浮點型,
現在我們應該翻開它周圍點嗎?我們還需要思考能不能翻開它周圍以外的點,我稱它為冒險博弈GetRisk();
由于我們已經知道,被掀開點周圍有2個地雷Mine,(如果)地雷(MineNum)和行(Col)列(Row)數目是已知的,那我們就可以得到除了它周圍以外的點是地雷Mine的風險risk,P=(MineNum-已知地雷數目)%(Col*Row-9)
將得到的概率相互一比較,得到最優選擇,
當區域內多點被掀開,我們應該如何去考慮它的概率?如圖

但我們掀開周圍點后,發現另一個點周圍有三個地雷,那么如何確定這兩個點周圍點是地雷的概率呢?
首先我們需要確定新掀開的點周圍有雷的概率,然后再更新前一個點的概率,注意概率的更新只影響到被掀開點周圍的點,
然后將兩掀開點周圍的點納入一個陣列MineAround[]中,再計算被掀開點周圍有雷的概率,注意,這一步的計算和前面不同,我們先將區域劃分

計算區域1的概率時,我們暫時不考慮區域2,區域1中右上角的點已經被掀開,那么說明確定那一點沒有雷,那么剩下的點是雷的概率是P1=1%7;
同樣對于區域二來說它中心點周圍點為雷的概率是:P2=3%7;
然后我們來考慮兩者結合的情況,對于兩區域為被掀開的點來說它們是雷的概率由它周圍點來確定,例如我們簡單的舉出兩個點,如圖
對于點b的區域來說,它自身是沒有被掀開的,我們計算點b是雷的概率就需要通過它周圍的被掀開的點來確定,對于b來說,在它周圍只有左下角點被掀開,所以我們認為點b是雷的概率為Pb=P2=3%7,也就是顯示3的點的周圍點概率,
那么如何確定點a是雷的概率呢?
對于點a,它周圍有兩個點被掀開,我們就基于這兩個點來確定它是雷的概率Pa:
Pa1一定是雷的概率 = (1%7)(3%7)
Pa2一定不是雷的概率 = (6%7)(4%7)
對于這里我們的目的是知道a不是雷的概率,所以我們取Pa = 1-Pa1;
(雖然對于該點來說只有是雷和不是雷的情況,但是這里只討論可能性)
這樣,當我們計算得到所有周圍點的概率后,比較出一個最好的概率情況(概率相同時任意取),然后再與Risk比較,得出最后最優選擇點位,
當然在實際除錯情況中,我們不僅僅將只是遇到這些情況,例如:
1.當我們遇到確認是地雷的點該怎么辦?
2.當我們遇到的所有點周圍是雷的概率都很高(但不確定是雷或者不是雷)怎么辦?
3.等等等等,,,還需要我們慢慢去探討,
2020/12/15
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/235576.html
標籤:其他
上一篇:sort函式自定義排序
下一篇:JAVA小游戲 混亂大槍戰
