㈠ 求五子棋演算法,能預測幾步的演算法
假設電腦是黑:
如果黑優的局勢:
電腦選一堆白必防的點(活三,活跳三,跳四或沖四),然後算白可能能防在哪裡(1到3個點)。然後再選一堆白必防的點,然後再算白可能防在哪裡。每節樹可能分2到6個叉。你下個黑石或是連珠妙手看看。這些軟體能算好多步驟。建議下黑石,你能看出電腦算出來的點。
如果沒有白必須防禦的點,電腦就選一堆黑優的點(一手棋2個以上活二的點),這樣的話白無論防在哪裡下一步一定能活三。
如果黑是劣勢則反之。
建議用Mini Max + Alpha-Beta演算法。
㈡ 關於QQ五子棋的積分演算法
QQ游戲五子棋的積分計算方法
兩個人分差小於 100 的時候 :
勝者得分 :
如果勝者積分 >= 負者積分
勝者得分為 : 10 – 兩人分差 / 10
如果勝者積分 < 負者積分
勝者得分為 : 10 + 兩人分差 / 10
和棋得分 :
分低者得分為: 兩人分差 / 10
高低者得分為: - 兩人分差 / 10
負者失分數等於勝者得分數
兩人分差不小於 100 的時候:
勝者得 1 分,負者輸 1 分
和棋時,分高者輸一分,分低者贏一分
兩個玩家的分數差別大於等於 200 分時,勝負都不計分。
㈢ C語言五子棋演算法
五子棋勝負的判定,一般有一下兩種演算法:
1.掃描整個棋盤,分別掃描四個方向是否有5個連子。網上找了很多五子棋源碼都是用此演算法,這意味著每下一個棋子都要掃描一遍19×19的棋盤,復雜而且低效,代碼略。
2.每下一字,從該子開始掃描其四個方向(例如:從該子的(x-4,y)坐標開始掃描橫向)是否存在5個連子。此演算法較為常用,而且不涉及更為復雜的數據結構。
另外,為解決掃描越界的問題,在聲明棋盤棋子位置時,可聲明一個(4+19+4)×(4+19+4)的棋盤,而讓棋子偏移(4,4)個坐標。
演算法2源代碼如下:
? void IfWin(int x,int y,int color){ TCHAR win[20]; int a,b; if(stone[x][y]==1) wcscpy_s(win,_T("黑棋勝利!")); else wcscpy_s(win,_T("白棋勝利!")); for(a=x-4;a<=x+4;a++)//判斷橫 if(stone[a][y]==color&&stone[a+1][y]==color&&stone[a+2][y]==color&&stone[a+3][y]==color&&stone[a+4][y]==color) {MessageBoxW(Xqwl.hWnd,win,TEXT(""),MB_OK);return;} for(b=y-4;b<=y+4;b++)//判斷豎 if(stone[x][b]==color&&stone[x][b+1]==color&&stone[x][b+2]==color&&stone[x][b+3]==color&&stone[x][b+4]==color) {MessageBoxW(Xqwl.hWnd,win,TEXT(""),MB_OK);return;} for(a=x-4,b=y-4;a<=x+4;a++,b++)//判斷右斜 if(stone[a][b]==color&&stone[a+1][b+1]==color&&stone[a+2][b+2]==color&&stone[a+3][b+3]==color&&stone[a+4][b+4]==color) {MessageBoxW(Xqwl.hWnd,win,TEXT(""),MB_OK);return;} for(a=x-4,b=y+4;a<=x+4;a++,b--)//判斷左斜 if(stone[a][b]==color&&stone[a+1][b-1]==color&&stone[a+2][b-2]==color&&stone[a+3][b-3]==color&&stone[a+4][b-4]==color) {MessageBoxW(Xqwl.hWnd,win,TEXT(""),MB_OK);return;}}
㈣ 求五子棋獲勝的演算法
在確認下子的同時,獲取當前位置的坐標,然後分別從8個方向上計算屬於同一個玩家的棋子,即左、右、上、下、左上、右下、右上、左下,只要有在同一直線上的兩個方向上的棋子之和為5,就判斷該玩家取得勝利。
/*輸贏判斷語句*/
winFail()
{
/*往左數*/
int k,l,count1=0,count2=0,count3=0,count4=0,count5=0,count6=0,count7=0,count8=0;
/*printf("%d",intX);*/
for(k=intX;k>0;k--)
if(point[k][intY]!=point[intX][intY]) break;
else
count1++;
/*往右數*/
for(k=intX;k<=N;k++)
if(point[k][intY]!=point[intX][intY]) break;
else
count2++;
/*左右相加*/
if(count1+count2-1==5) initial(point[intX][intY]);
/*printf("%d",count1+count2-1);*/
/*往上數*/
for(l=intY;l>0;l--)
if(point[intX][l]!=point[intX][intY]) break;
else
count3++;
/*往下數*/
for(l=intY;l<=N;l++)
if(point[intX][l]!=point[intX][intY]) break;
else
count4++;
/*上下相加*/
if(count3+count4-1==5) initial(point[intX][intY]);
/*往左上數*/
for(k=intX,l=intY;k>0,l>0;k--,l--)
if(point[k][l]!=point[intX][intY]) break;
else
count5++;
/*往右下數*/
for(k=intX,l=intY;k<=N,l<=N;k++,l++)
if(point[k][l]!=point[intX][intY]) break;
else
count6++;
/*右上左下相加*/
if(count5+count6-1==5) initial(point[intX][intY]);
/*往右上數*/
for(k=intX,l=intY;k<=N,l>0;k++,l--)
if(point[k][l]!=point[intX][intY]) break;
else
count7++;
/*往左下數*/
for(k=intX,l=intY;k>0,l<=N;k--,l++)
if(point[k][l]!=point[intX][intY]) break;
else
count8++;
/*右上左下相加*/
if(count7+count8-1==5) initial(point[intX][intY]);
}
㈤ 求五子棋人機對戰演算法
總的來說,要讓電腦知道該在哪一點下子,就要根據盤面的形勢,為每
一可能落子的點計算其重要程度,也就是當這子落下後會形成什麼棋型(如:「沖四」、「活三」等),然後通覽
全盤選出最重要的一點,這便是最基本的演算法。當然,僅靠當前盤面進行判定是遠遠不夠的,這樣下棋很輕易掉進
玩家設下的陷阱,因為它沒有考慮以後的變化。所以在此基礎上我們加入遞歸調用,即:在電腦中猜測出今後幾步
的各種走法,以便作出最佳選擇,這也是我們下棋時常說的「想了幾步」。如此一來您的程序便具有一定的水平了。
什麼?不信!過來試試吧!
總體思路弄清之後,下面進行具體討論:
一:數據結構
先來看看數據結構,我們需要哪些變數?
首先得為整個棋盤建立一張表格用以記錄棋子信息,我們使用一個15*15的二維數組 Table[15][15] (15*15是
五子棋棋盤的大小),數組的每一個元素對應棋盤上的一個交叉點,用『0』表示空位、『1』代表己方的子、『2』
代表對方的子;這張表也是今後分析的基礎。
在此之後還要為電腦和玩家雙方各建立一張棋型表Computer[15][15][4]和Player[15][15][4],用來存放棋型
數據,就是剛才所說的重要程度,比如用『20』代表「沖四」的點,用『15』代表「活三」的點,那麼在計算重要
性時,就可以根據20>15得出前者比後者重要,下子時電腦便會自動選擇「沖四」的點。那為什麼棋型表要使用三
維數組呢?因為棋盤上的每一個點都可以與橫、豎、左斜、右斜四個方向的棋子構成不同的棋型,所以一個點總共
有4個記錄;這樣做的另一個好處是可以輕易判定出復合棋型,例如:假如同一點上有2個『15』就是雙三、有一個『15』和一個『20』就是四三。
怎麼樣!3個數組構成了程序的基本數據骨架,今後只要再加入一些輔助變數便可以應付自如了。應該不會太
難吧?OK!有了這么多有用的數據,我們就可以深入到程序的流程中去了。
二:程序流程
我們主要討論五子棋的核心演算法,即:人工智慧部分,而其他像圖形顯示、鍵盤滑鼠控制等,因較為簡單,所
以就不作過多介紹了。
我們看到本程序由六個基本功能模塊構成,各模塊的具體分析如下:
(1)初始化:首先,建立盤面數組Table[15][15]、對戰雙方的棋型表Computer[15][15][4]和Player[15]
[15][4]並將它們清零以備使用;然後初始化顯示器、鍵盤、鼠等輸入輸出設備並在屏幕上畫出棋盤。
(2)主循環控制模塊:控制下棋順序,當輪到某方下子時,負責將程序轉到相應的模塊中去,主要擔當一個
調度者的角色。
(3)玩家下子:當輪到玩家下時,您通過鍵盤或滑鼠在棋盤上落子,程序會根據該點的位置,在Table[15]
[15]數組的相應地方記錄『2』,以表明該子是玩家下的。
(4)盤面分析填寫棋型表:本程序核心模塊之一,人工智慧演算法的根本依據!其具體實現方法如下:您在下
五子棋時,一定會先根據棋盤上的情況,找出當前最重要的一些點位,如「活三」、「沖四」等;然後再在其中
選擇落子點。但是,電腦不會像人一樣分析問題,要讓它知道哪是「活三」、哪是「沖四」,就得在棋盤上逐點
計算,一步一步的教它。
先來分析己方的棋型,我們從棋盤左上角出發,向右逐行搜索,當碰到一個空白點時,以它為中心向左挨個
查找,假如碰到己方的子則記錄然後繼續,假如碰到對方的子、空白點或邊界就停止查找。左邊完成後再向右進
行同樣的操作;最後把左右兩邊的記錄合並起來,得到的數據就是該點橫向上的棋型,然後把棋型的編號填入到Computer[x][y][n]中就行了(x、y代表坐標,n=0、1、2、3分別代表橫、豎、左斜、右斜四個方向)。而其他三
個方向的棋型也可用同樣的方法得到,當搜索完整張棋盤後,己方棋型表也就填寫完畢了。然後再用同樣的方法
填寫對方棋型表。
注重:所有棋型的編號都要事先定義好,越重要的號數越大!
OK! 怎麼樣?有點累了吧?不過千萬別泄氣!因為好戲還在後頭。
Let's go!
(5)電腦下子:有了上面填寫的兩張棋型表,現在要作的就是讓電腦知道在哪一點下子了。其中最簡單的
計算方法,就是遍歷棋型表Computer[15][15][4]和Player[15][15][4]找出其中數值最大的一點,在該點下子即
可。但這種演算法的弱點非常明顯,只顧眼前利益,不能顧全大局,這就和許多五子棋初學者一樣犯了「目光短淺」
的毛病。
要解決這個問題,我們引入『今後幾步猜測法』,具體方法是這樣的: 首先, 讓電腦分析一個可能的點,
假如在這兒下子將會形成對手不得不防守的棋型(例如:『沖四』、『活三』);那麼下一步對手就會照您的思
路下子來防守您,如此一來便完成了第一步的猜測。這時再調用模塊4對猜測後的棋進行盤面分析,假如出現了
『四三』、『雙三』或『雙四』等制勝點,那麼己方就可以獲勝了(當然對黑棋而言『雙三』、『雙四』是禁手
,另當別論);否則照同樣的方法向下分析,就可猜測出第二步、第三步……
等一等,要是盤面上沒有對手必須防的棋型,哪該怎麼辦呢?進攻不成的話就得考慮防守了,將自己和對手
調換一下位置,然後用上面的方法來猜測對手的棋,這樣既可以防住對手巧妙的攻擊,又能侍機發動反擊,何樂
而不為呢!
但是必須告訴大家的是:猜測法的運算量相當之大,據我的經驗,用Pentium-100猜測3步的走法平均需要15
秒以上時間,所以建議猜測量在5步以內。可別小瞧了這5步,有時它甚至會走出讓您拍手叫絕的妙著呢!
(6)勝敗判定:務須多言,某方形成五子連即獲勝;若黑棋走出『雙三』、『雙四』或長連即以禁手判負。
到現在為止,整個五子棋軟體就基本完成了,其水平大約在中級上下。當然,這種演算法並不是最好的,但我
相信它的基本思路是正確的。
㈥ 速求五子棋的C演算法
總的來說(我們假定您熟悉五子棋的基本規則),要讓電腦知道該在哪一點下子,就要根據盤面的形勢,為每
一可能落子的點計算其重要程度,也就是當這子落下後會形成什麼棋型(如:「沖四」、「活三」等),然後通覽
全盤選出最重要的一點,這便是最基本的演算法。當然,僅靠當前盤面進行判斷是遠遠不夠的,這樣下棋很容易掉進
玩家設下的陷阱,因為它沒有考慮以後的變化。所以在此基礎上我們加入遞歸調用,即:在電腦中預測出今後幾步
的各種走法,以便作出最佳選擇,這也是我們下棋時常說的「想了幾步」。如此一來您的程序便具有一定的水平了。
什麼?不信!過來試試吧!
總體思路弄清之後,下面進行具體討論:
一:數據結構
先來看看數據結構,我們需要哪些變數?
首先得為整個棋盤建立一張表格用以記錄棋子信息,我們使用一個15*15的二維數組 Table[15][15] (15*15是
五子棋棋盤的大小),數組的每一個元素對應棋盤上的一個交叉點,用『0』表示空位、『1』代表己方的子、『2』
代表對方的子;這張表也是今後分析的基礎。
在此之後還要為電腦和玩家雙方各建立一張棋型表Computer[15][15][4]和Player[15][15][4],用來存放棋型
數據,就是剛才所說的重要程度,比如用『20』代表「沖四」的點,用『15』代表「活三」的點,那麼在計算重要
性時,就可以根據20>15得出前者比後者重要,下子時電腦便會自動選擇「沖四」的點。那為什麼棋型表要使用三
維數組呢?因為棋盤上的每一個點都可以與橫、豎、左斜、右斜四個方向的棋子構成不同的棋型,所以一個點總共
有4個記錄;這樣做的另一個好處是可以輕易判斷出復合棋型,例如:如果同一點上有2個『15』就是雙三、有一個『15』和一個『20』就是四三。
怎麼樣!3個數組構成了程序的基本數據骨架,今後只要再加入一些輔助變數便可以應付自如了。應該不會太
難吧?OK!有了這么多有用的數據,我們就可以深入到程序的流程中去了。
二:程序流程
我們主要討論五子棋的核心演算法,即:人工智慧部分,而其他像圖形顯示、鍵盤滑鼠控制等,因較為簡單,所
以就不作過多介紹了。
我們看到本程序由六個基本功能模塊構成,各模塊的詳細分析如下:
(1)初始化:首先,建立盤面數組Table[15][15]、對戰雙方的棋型表Computer[15][15][4]和Player[15]
[15][4]並將它們清零以備使用;然後初始化顯示器、鍵盤、鼠等輸入輸出設備並在屏幕上畫出棋盤。
(2)主循環控制模塊:控制下棋順序,當輪到某方下子時,負責將程序轉到相應的模塊中去,主要擔當一個
調度者的角色。
(3)玩家下子:當輪到玩家下時,您通過鍵盤或滑鼠在棋盤上落子,程序會根據該點的位置,在Table[15]
[15]數組的相應地方記錄『2』,以表明該子是玩家下的。
(4)盤面分析填寫棋型表:本程序核心模塊之一,人工智慧演算法的根本依據!其具體實現方法如下:您在下
五子棋時,一定會先根據棋盤上的情況,找出當前最重要的一些點位,如「活三」、「沖四」等;然後再在其中
選擇落子點。但是,電腦不會像人一樣分析問題,要讓它知道哪是「活三」、哪是「沖四」,就得在棋盤上逐點
計算,一步一步的教它。
先來分析己方的棋型,我們從棋盤左上角出發,向右逐行搜索,當遇到一個空白點時,以它為中心向左挨個
查找,如果遇到己方的子則記錄然後繼續,如果遇到對方的子、空白點或邊界就停止查找。左邊完成後再向右進
行同樣的操作;最後把左右兩邊的記錄合並起來,得到的數據就是該點橫向上的棋型,然後把棋型的編號填入到Computer[x][y][n]中就行了(x、y代表坐標,n=0、1、2、3分別代表橫、豎、左斜、右斜四個方向)。而其他三
個方向的棋型也可用同樣的方法得到,當搜索完整張棋盤後,己方棋型表也就填寫完畢了。然後再用同樣的方法
填寫對方棋型表。
注意:所有棋型的編號都要事先定義好,越重要的號數越大!
OK! 怎麼樣?有點累了吧?不過千萬別泄氣!因為好戲還在後頭。
Let's go!
(5)電腦下子:有了上面填寫的兩張棋型表,現在要作的就是讓電腦知道在哪一點下子了。其中最簡單的
計算方法,就是遍歷棋型表Computer[15][15][4]和Player[15][15][4]找出其中數值最大的一點,在該點下子即
可。但這種演算法的弱點非常明顯,只顧眼前利益,不能顧全大局,這就和許多五子棋初學者一樣犯了「目光短淺」
的毛病。歡迎光臨學網,收藏本篇文章 [1] [2]
$False$
要解決這個問題,我們引入『今後幾步預測法』,具體方法是這樣的: 首先, 讓電腦分析一個可能的點,
如果在這兒下子將會形成對手不得不防守的棋型(例如:『沖四』、『活三』);那麼下一步對手就會照您的思
路下子來防守您,如此一來便完成了第一步的預測。這時再調用模塊4對預測後的棋進行盤面分析,如果出現了
『四三』、『雙三』或『雙四』等制勝點,那麼己方就可以獲勝了(當然對黑棋而言『雙三』、『雙四』是禁手
,另當別論);否則照同樣的方法向下分析,就可預測出第二步、第三步……
等一等,要是盤面上沒有對手必須防的棋型,哪該怎麼辦呢?進攻不成的話就得考慮防守了,將自己和對手
調換一下位置,然後用上面的方法來預測對手的棋,這樣既可以防住對手巧妙的攻擊,又能侍機發動反擊,何樂
而不為呢!
但是必須告訴大家的是:預測法的運算量相當之大,據我的經驗,用Pentium-100預測3步的走法平均需要15
秒以上時間,所以建議預測量在5步以內。可別小瞧了這5步,有時它甚至會走出讓您拍手叫絕的妙著呢!
(6)勝負判斷:務須多言,某方形成五子連即獲勝;若黑棋走出『雙三』、『雙四』或長連即以禁手判負。
到現在為止,整個五子棋軟體就基本完成了,其水平大約在中級上下。當然,這種演算法並不是最好的,但我
相信它的基本思路是正確的。
資料來源:學網(www.xue5.com),原文地址: http://www.xue5.com/ite/200707/129221.html
㈦ 求問五子棋AI演算法思路
五子棋的核心演算法
五子棋是一種受大眾廣泛喜愛的游戲,其規則簡單,變化多端,非常富有趣味性和消遣性。這里設計和實現了一個人機對下的五子棋程序,採用了博弈樹的方法,應用了剪枝和最大最小樹原理進行搜索發現最好的下子位置。介紹五子棋程序的數據結構、評分規則、勝負判斷方法和搜索演算法過程。
一、相關的數據結構
關於盤面情況的表示,以鏈表形式表示當前盤面的情況,目的是可以允許用戶進行悔棋、回退等操作。
CList StepList;
其中Step結構的表示為:
struct Step
{
int m; //m,n表示兩個坐標值
int n;
char side; //side表示下子方
};
以數組形式保存當前盤面的情況,
目的是為了在顯示當前盤面情況時使用:
char FiveArea[FIVE_MAX_LINE][FIVE_MAX_LINE];
其中FIVE_MAX_LINE表示盤面最大的行數。
同時由於需要在遞歸搜索的過程中考慮時間和空間有效性,只找出就當前情況來說相對比較好的幾個盤面,而不是對所有的可下子的位置都進行搜索,這里用變數CountList來表示當前搜索中可以選擇的所有新的盤面情況對象的集合:
CList CountList;
其中類CBoardSituiton為:
class CBoardSituation
{
CList StepList; //每一步的列表
char FiveArea[FIVE_MAX_LINE][FIVE_MAX_LINE];
struct Step machineStep; //機器所下的那一步
double value; //該種盤面狀態所得到的分數
}
二、評分規則
對於下子的重要性評分,需要從六個位置來考慮當前棋局的情況,分別為:-,¦,/,\,//,\\
實際上需要考慮在這六個位置上某一方所形成的子的布局的情況,對於在還沒有子的地方落子以後的當前局面的評分,主要是為了說明在這個地方下子的重要性程度,設定了一個簡單的規則來表示當前棋面對機器方的分數。
基本的規則如下:
判斷是否能成5, 如果是機器方的話給予100000分,如果是人方的話給予-100000 分;
判斷是否能成活4或者是雙死4或者是死4活3,如果是機器方的話給予10000分,如果是人方的話給予-10000分;
判斷是否已成雙活3,如果是機器方的話給予5000分,如果是人方的話給予-5000 分;
判斷是否成死3活3,如果是機器方的話給予1000分,如果是人方的話給予-1000 分;
判斷是否能成死4,如果是機器方的話給予500分,如果是人方的話給予-500分;
判斷是否能成單活3,如果是機器方的話給予200分,如果是人方的話給予-200分;
判斷是否已成雙活2,如果是機器方的話給予100分,如果是人方的話給予-100分;
判斷是否能成死3,如果是機器方的話給予50分,如果是人方的話給予-50分;
判斷是否能成雙活2,如果是機器方的話給予10分,如果是人方的話給予-10分;
判斷是否能成活2,如果是機器方的話給予5分,如果是人方的話給予-5分;
判斷是否能成死2,如果是機器方的話給予3分,如果是人方的話給予-3分。
實際上對當前的局面按照上面的規則的順序進行比較,如果滿足某一條規則的話,就給該局面打分並保存,然後退出規則的匹配。注意這里的規則是根據一般的下棋規律的一個總結,在實際運行的時候,用戶可以添加規則和對評分機制加以修正。
三、勝負判斷
實際上,是根據當前最後一個落子的情況來判斷勝負的。實際上需要從四個位置判斷,以該子為出發點的水平,豎直和兩條分別為 45度角和135度角的線,目的是看在這四個方向是否最後落子的一方構成連續五個的棋子,如果是的話,就表示該盤棋局已經分出勝負。具體見下面的圖示:
四、搜索演算法實現描述
注意下面的核心的演算法中的變數currentBoardSituation,表示當前機器最新的盤面情況, CountList表示第一層子節點可以選擇的較好的盤面的集合。核心的演算法如下:
void MainDealFunction()
{
value=-MAXINT; //對初始根節點的value賦值
CalSeveralGoodPlace(currentBoardSituation,CountList);
//該函數是根據當前的盤面情況來比較得到比較好的可以考慮的幾個盤面的情況,可以根據實際的得分情況選取分數比較高的幾個盤面,也就是說在第一層節點選擇的時候採用貪婪演算法,直接找出相對分數比較高的幾個形成第一層節點,目的是為了提高搜索速度和防止堆棧溢出。
pos=CountList.GetHeadPosition();
CBoardSituation* pBoard;
for(i=0;ivalue=Search(pBoard,min,value,0);
Value=Select(value,pBoard->value,max);
//取value和pBoard->value中大的賦給根節點
}
for(i=0;ivalue)
//找出那一個得到最高分的盤面
{
currentBoardSituation=pBoard;
PlayerMode=min; //當前下子方改為人
Break;
}
}
其中對於Search函數的表示如下:實際上核心的演算法是一個剪枝過程,其中在這個搜索過程中相關的四個參數為:(1)當前棋局情況;(2)當前的下子方,可以是機器(max)或者是人(min);(3)父節點的值oldValue;(4)當前的搜索深度depth。
double Search(CBoardSituation&
board,int mode,double oldvalue,int depth)
{
CList m_DeepList;
if(deptholdvalue))== TRUE)
{
if(mode==max)
value=select(value,search(successor
Board,min,value,depth+1),max);
else
value=select(value,search(successor
Board,max,value,depth+1),min);
}
return value;
}
else
{
if ( goal(board)<>0)
//這里goal(board)<>0表示已經可以分出勝負
return goal(board);
else
return evlation(board);
}
}
注意這里的goal(board)函數是用來判斷當前盤面是否可以分出勝負,而evlation(board)是對當前的盤面從機器的角度進行打分。
下面是Select函數的介紹,這個函數的主要目的是根據 PlayerMode情況,即是機器還是用戶來返回節點的應有的值。
double Select(double a,double b,int mode)
{
if(a>b && mode==max)¦¦ (a< b && mode==min)
return a;
else
return b;
}
五、小結
在Windows操作系統下,用VC++實現了這個人機對戰的五子棋程序。和國內許多隻是採用規則或者只是採用簡單遞歸而沒有剪枝的那些程序相比,在智力上和時間有效性上都要好於這些程序。同時所討論的方法和設計過程為用戶設計其他的游戲(如象棋和圍棋等)提供了一個參考。
㈧ 五子棋的Java演算法
五子棋的演算法是比較簡單的。
把棋盤當作一個
2
維數組。
用2維數組來當作棋盤的坐標系
當落子
之後。
把落子,插入到
數組中
獲得
棋盤
的數組,
循環剛才數組,
判斷,
剛才
數組元素
的
橫向坐標
-5
到剛才
數組元素坐標
+
5
是否都是
一個數字(黑子代表
1
,白子代表0)
只要其中
有連續
5個
都是
黑子,或者白子,
則黑子或白子
贏了。
判斷,剛才元素
縱向坐標
-5
到
+
5
如上判斷。
判斷
右斜線。
判斷
橫向坐標
-5
y
-5
到
橫向坐標
+
5
y
+
5
判斷
y
+
5
x
+
5
到
y-5
x
-5
簡單來說。
用2維數組
來代表
棋盤
,
每次在
界面上,
由白子,或黑子
落子之後,
在數組相應坐標,放入
1
或者0
。
然後循環數組判斷,
數組橫向
豎向
右斜線
左斜線
是否是
黑子或者白子
連續的。
如果是,則獲勝。
㈨ 跪求五子棋演算法c語言版
任何一種棋類游戲其關鍵是對當前棋局是否有正確的評分,評分越准確則電腦的AI越高。五子棋游戲也是如此,但在打分之前,我們先掃描整個棋盤,把每個空位從八個方向上的棋型填入數組gStyle(2, 15, 15, 8, 2),其中:第一個下標為1時表示黑棋,為2時表示白棋,第二和第三個下標表示(x,y),第四個下標表示8個方向,最後一個下標為1時表示棋子數,為2時表示空格數,如:
gStyle(1,2,2,1,1)=3表示與坐標(2,2)在第1個方向上相鄰的黑棋棋子數為3
gstyle(1,2,2,1,2)=4表示與坐標(2,2)在第1個方向上的最近的空格數為4
在定義方向時,也應該注意一定的技巧,表示兩個相反的方向的數應該差4,在程序中我是這樣定義的:
Const DIR_UP = 1
Const DIR_UPRIGHT = 2
Const DIR_RIGHT = 3
Const DIR_RIGHTDOWN = 4
Const DIR_DOWN = 5
Const DIR_DOWNLEFT = 6
Const DIR_LEFT = 7
Const DIR_LEFTUP = 8
這樣我們前四個方向可以通過加四得到另一個方向的值。如果你還是不太明白,請看下面的圖:
---------
---------
---oo----
-ox*xx---
---------
---------
圖中的*點從標為(4,4),(打*的位置是空位),則:
gStyle(2,4,4,1,1)=1在(4,4)點相鄰的上方白棋數為1
gStyle(2,4,4,1,2)=2在(4,4)點的上方距上方白棋最近的空格數為2
gStyle(1,4,4,3,1)=2在(4,4)點相鄰的右方黑棋數為2
gStyle(1,4,4,3,2)=1在(4,4)點的右方距右方黑棋最近的空格數為3
...
一旦把所有空點的棋型值填完,我們很容易地得出黑棋水平方向上點(4,4)的價值,由一個沖1(我把有界的棋稱為沖)和活2(兩邊無界的
棋稱為活)組成的。對於而白棋在垂直方向上點(4,4)的價值是一個活1,而在/方向也是活1所以,只要我們把該點的對於黑棋和白棋的價值算出
來,然後我們就取棋盤上各個空點的這兩個值的和的最大一點作為下棋的點。然而,對各種棋型應該取什麼值呢?我們可以先作如下假設:
Fn 表示先手n個棋子的活棋型,如:F4表示先手活四
Fn'表示先手n個棋子的沖棋型,如:F4'表示先手沖四
Ln 表示後手n個棋子的活棋型,如:L3表示後手活三
Ln'表示後手n個棋子的沖棋型,如:L3'表示後手沖三
.
.
.
根據在一行中的棋型分析,得到如下關系:
L1'<=F1'<L2'<=F2'<=L1<F1<L2<F2<L3'<=F3'<L4'<F4'=F4
從這個關系包含了進攻和防守的關系(當然,這個關系是由我定的,你可以自己定義這些關系)。對這些關系再進一步細化,如在一個可下棋的點,其四個方向上都有活三,也比不上一個沖四,所以我們可以又得到4*F3<L4'這個關系,同樣,我們還可以得到其它的關系,如:4*F2<L3、4*L3<F3...,這些的關系由於你的定法和我的定法制可能不一樣,這樣計算機的AI也就不一樣,最後我們把分值最小的L1'值定為1,則我們就得到了下面各種棋型的分值,由C語言表示為:
F[2][5]={{0,2,5,50,16000},{0,10,30,750,16000}};
L[2][5]={{0,1,5,50,3750},{0,10,30,150,4000}};
F數組表示先手,第一個下標為0時表示沖型,第二個下標表示棋子數,則F2'對應F[0][2]L數組表示後手,第一個下標為0時表示沖型,第二個下標表示棋子數,則L2對應F[1][2]Ok,棋型的分值關系確定好了以後,我們把每一個可下點的四個方向的棋型值相加(包括先手和後手的分
值),最後選擇一個最大值,並把這一點作為計算機要下的點就OK了:)。
後話:
1、得到最大值也許不止一個點,但在我的程序中只選擇第一個最大點,當然你可以用於個隨機數來決定選擇那一個最大值點,也可以對這些最大值點再作進一步的分析。
2、在這個演算法中我只考慮了周圍有棋子的點,而其它點我沒有考慮。
3、可以再更進一步,用這個演算法來預測以後的幾步棋,再選擇預測值最好的一步,這樣電腦的AI就更高了.
4、這個演算法沒有考慮黑棋的禁手(雙3、雙四和多於五子的連棋)。因為在平時我下的五子棋是沒有這些禁手的。: )