① 求五子棋人機對戰演算法
總的來說,要讓電腦知道該在哪一點下子,就要根據盤面的形勢,為每
一可能落子的點計算其重要程度,也就是當這子落下後會形成什麼棋型(如:「沖四」、「活三」等),然後通覽
全盤選出最重要的一點,這便是最基本的演算法。當然,僅靠當前盤面進行判定是遠遠不夠的,這樣下棋很輕易掉進
玩家設下的陷阱,因為它沒有考慮以後的變化。所以在此基礎上我們加入遞歸調用,即:在電腦中猜測出今後幾步
的各種走法,以便作出最佳選擇,這也是我們下棋時常說的「想了幾步」。如此一來您的程序便具有一定的水平了。
什麼?不信!過來試試吧!
總體思路弄清之後,下面進行具體討論:
一:數據結構
先來看看數據結構,我們需要哪些變數?
首先得為整個棋盤建立一張表格用以記錄棋子信息,我們使用一個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語言演算法、、 詳細點、、
#include<stdio.h>
#define N 8
#define M 8
void init(char flag[N][M])
{
int i,j;
for( i=0;i<N;i++)
for(j=0;j<M;j++)
{ flag[i][j]=』0』;
printf("%c",flag[i][j]);
if(j==N-1)
printf("\n");
}
}
void draw(char flag[N][M])
{
int i,j;
for(i=0;i<N;i++)
for( j=0;j<M;j++)
{ printf("%c",flag[i][j]);
if(j==N-1)
printf("\n");
}
}
void ciin(char flag[N][M],char t,char v)
{
int i,j;
printf("qin %c zou\n",t);
printf("qin shu ru liang ge #iao *u %d de shu zi:",N);
scanf("%d,%d",&i,&j);
while(i>=N||i<1||j>=M||j<1||flag[i][j]=='*'||flag[i][j]=='#')
{
if(i>=N||i<1||j>=M||j<1)
{
printf("shu ru cuo wu??qin chong #in shu ru\n");
printf("qin shu ru liang ge #iao *u %d de shu zi:",N);
scanf("%d,%d",&i,&j);
}
else
{
printf("ci chu *ou qi zi,qin chong #in shu ru.");
printf("qin shu ru liang ge #iao *u %d de shu zi:",N);
scanf("%d,%d",&i,&j);
}
}
flag[i][j]=v;
draw(flag);
}
void test(char flag[][M],char t)
{
int i,j;
for(i=1;i<N;i++)
{ for(j=1;j<M;j++)
if((flag[i][j]=='*'&&flag[i][j+1]=='*'&&flag[i][j+2]=='*'&&flag[i][j+3]=='*'&&flag[i][j+4]=='*')||(flag[i][j]=='#'&&flag[i][j+1]=='#'&&flag[i][j+2]=='#'&&flag[i][j+3]=='#'&&flag[i][j+4]=='#')||(flag[i][j]=='*'&&flag[i+1][j]=='*'&&flag[i+2][j]=='*'&&flag[i+3][j]=='*'&&flag[i+4][j]=='*')||(flag[i][j]=='#'&&flag[i+1][j]=='#'&&flag[i+2][j]=='#'&&flag[i+3][j]=='#'&&flag[i+4][j]=='#')||(flag[i][j]=='*'&&flag[i+1][j+1]=='*'&&flag[i+2][j+2]=='*'&&flag[i+3][j+3]=='*'&&flag[i+4][j+4]=='*')||(flag[i][j]=='#'&&flag[i+1][j+1]=='#'&&flag[i+2][j+2]=='#'&&flag[i+3][j+3]=='#'&&flag[i+4][j+4]=='#')||(flag[i][j]=='*'&&flag[i+1][j-1]=='*'&&flag[i+2][j-2]=='*'&&flag[i+3][j-3]=='*'&&flag[i+4][j-4]=='*')||(flag[i][j]=='#'&&flag[i+1][j-1]=='#'&&flag[i+2][j-2]=='#'&&flag[i+3][j-3]=='#'&&flag[i+4][j-4]=='#'))
printf("%c Win",t);
}
}
void main()
{
int i;
char flag[N][M];
init(flag);
for(i=0;i<(N-1)*(M-1);i++)
{
ciin(flag,'A','*');
test(flag,'A');
ciin(flag,'B','#');
test(flag,'B');
}
}
望採納! 不懂可以再問,我定義的五子棋大小為8行8列的
③ 求五子棋AI演算法
我給你發了一個xl的源代碼,是所有開源的五子棋中AI水平最高的了
④ 五子棋演算法 vc++(MFC)
就是給1000分,估計也沒有人為這個給你寫代碼。因為來這里的高手才不稀罕分數,而低手又寫不出來。
不過,我可以給你提供一個思路。
這個,可以用深度優先搜索演算法。
提供一個偽代碼給你:
//寫一個估值函數
int 獲得價值( int nPlayer, int x, int y )
{
// 函數說明:
// 假設把棋子落到x,y處,所能獲得的價值。
// nPlyaer == 1表示黑方,nPlyaer==2表示白方
1、判斷如果是贏(橫向、縱向、斜向五個連起來)就返回無窮大(一個遠遠大於最高價值的值,例如1000)
2、判斷如果是雙沖4,返回 200
3、判斷如果是沖四活三,返回150
4、判斷如果是雙活三,返回100
5、如果挨著自己的棋子,兩頭又有空隙,返回50
6、其他的有利的判斷。。。。
7、返回以上判斷的價值
}
//寫一個獲得最佳位置的函數
//int 獲得最佳位置( int 黑方或白方, int 層數, POINT& 返回位置 )
int GetBestPosition( int nP, int n, POINT& ptBest )
{
1、枚舉所有可以落子的位置。
2、假設將棋子落到該處。
3、獲得該處的價值( 保存在 int nJia );
4、如果層數==1,轉到第7步:;
5、否則:
6、//遞歸的調用GetBastPosition( 對方, 層數減一 );
nJia -= GetBastPositon( nP == 1 ? 2 : 1, -- n );
7、找出所枚舉的所有的落子點中價值最高的那個位置。
8、將7中找到的位置存入ptBest,返回nJia.
}
說明一下:
層數,就是想讓程序能夠考慮幾步。
總體的思路就是,搜索所有可以落子的地點(當然可以優化,比如遠離交戰焦點的地方可以忽略),假設將棋子落到該處,然後評估這個位置的價值,再減去敵人能獲得的最高價值,就等於這個位置的實際價值,找出實際價值最高的點,就是最好的落子點了。
最難的就是寫估值函數。一個良好的估值函數,加上搜索的一些優化,就是一個很好的博弈演算法。
⑤ 求五子棋獲勝的演算法
在確認下子的同時,獲取當前位置的坐標,然後分別從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]);
}
⑥ 五子棋高級演算法
基本演算法:
採用博弈比較常用的策略。
計算機下子前,分別對玩家和電腦棋型進行評估,然後根據棋型對每一位置打分(玩家和電腦在同一點的分數不同),比如活三100分,沖四1000分等,然後根據每個落子點分數進行選擇。採用極大極小值策略,進行多步計算。
-_-.........代碼在文件夾chess里啊..........
一些可能有用的鏈接
http://topic.csdn.net/t/20001021/09/35626.html
http://..com/question/46388110.html?si=6
⑦ 五子棋人工智慧演算法講解
五子棋演算法可簡可繁,要看你對自己五子棋程序智能的要求, 人機對戰的意思就是人和電腦下,也就是說電腦會思考如何下棋....其實這才是五子棋程序的核心.如果只實現人與人對戰的話,是一件很簡單的事情,無非就是繪制棋盤,然後繪制下棋的效果,再寫個下棋合法性判斷,勝負判斷....大概就搞定了....所以核心其實是人機對戰的電腦那部分人工智慧.這東西吧,可以研究的很多,不過主要的幾個設計要點就是搜索演算法和估值演算法,這兩個是最主要的,還有提高電腦思考銷率的方法就有多cpu的計算機多線程思考的設計....通過一些手段讓電腦變得更像人類棋手的,例如利用一些遺傳演算法之類的讓電腦具有學習能力,可以在失敗中吸取教訓,開局庫,歷史啟發之類的一大堆......但是總而言之,這一系列演算法的設計沒有一個標准,只要能讓你的電腦下棋下的更聰明,更快那就是好演算法.國內有一個叫王曉春的寫過一本叫<<pc游戲編程( 人機博弈)>>的書,這是一本研究人機博弈程序很經典的書,書的後面還附了一個五子棋的程序實例,你可以參考一下.下面是csdn的下載地址,你也可以自己去搜一下.http://download.csdn.net/source/1925326
⑧ 誰知道下五子棋的演算法和訣竅呢
http://jingyan..com/article/4e5b3e198bc8b991901e24d0.html 去看下吧 會有幫助的
⑨ 五子棋的演算法用哪種比較簡單
可以採用這樣的笨演算法,運行起來慢點,但是很簡單易懂,而且效果很好。如果能夠加以優化,則其實是很好的演算法:
1、首先遍歷整個棋盤,找到一個可以落子的點,然後假設自己在該點落子,再然後判斷如果棋子落到這個點上後會對自己有什麼利益,比如會不會形成沖4活三、雙活三等等,(事先將沖四活三、雙活三等效果定義上利益值,當然,如果是五個子連起來了的話,利益值要被定義成最高,最好是無窮大的),將各種效果的利益值相加,得到己方的利益值。
2、將角色互換一下,重復第一步,得到對方的利益值(其實是遞桂演算法)。
3、將己方的利益值減去對方的利益值,得到該點的總利益值。
4、整個棋盤所有能落子的點都計算出利益值之後,找出利益值最大的那個點,將棋子落到該點。
當然,這個演算法可以有很大程度的優化,比如,如果沒有相鄰的棋子,可以放棄該點。還有一旦找出可以勝利的點,就不再繼續往下計算。。。。
模擬演算法:
int liyi(角色, 層次)
{
if(層次=0)
return 0;
for(第一個可以落子的點 到 最後一個可以落子的點)
{
int 利益,最大利益;
//遞桂...
利益 = 獲取本角色利益值() - liyi(角色=相反角色,層次-1);
if(利益>最大利益)
{
最大利益 = 利益;
保存該點。
}
落子到所保存的點。
}
⑩ 誰有五子棋的高級演算法100分
已經發給你了,帶注釋的AI(&i,&j)演算法