Ⅰ 五子棋的演算法用哪種比較簡單
可以採用這樣的笨演算法,運行起來慢點,但是很簡單易懂,而且效果很好。如果能夠加以優化,則其實是很好的演算法:
1、首先遍歷整個棋盤,找到一個可以落子的點,然後假設自己在該點落子,再然後判斷如果棋子落到這個點上後會對自己有什麼利益,比如會不會形成沖4活三、雙活三等等,(事先將沖四活三、雙活三等效果定義上利益值,當然,如果是五個子連起來了的話,利益值要被定義成最高,最好是無窮大的),將各種效果的利益值相加,得到己方的利益值。
2、將角色互換一下,重復第一步,得到對方的利益值(其實是遞桂演算法)。
3、將己方的利益值減去對方的利益值,得到該點的總利益值。
4、整個棋盤所有能落子的點都計算出利益值之後,找出利益值最大的那個點,將棋子落到該點。
當然,這個演算法可以有很大程度的優化,比如,如果沒有相鄰的棋子,可以放棄該點。還有一旦找出可以勝利的點,就不再繼續往下計算。。。。
模擬演算法:
int liyi(角色, 層次)
{
if(層次=0)
return 0;
for(第一個可以落子的點 到 最後一個可以落子的點)
{
int 利益,最大利益;
//遞桂...
利益 = 獲取本角色利益值() - liyi(角色=相反角色,層次-1);
if(利益>最大利益)
{
最大利益 = 利益;
保存該點。
}
落子到所保存的點。
}
Ⅱ 求問五子棋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++實現了這個人機對戰的五子棋程序。和國內許多隻是採用規則或者只是採用簡單遞歸而沒有剪枝的那些程序相比,在智力上和時間有效性上都要好於這些程序。同時所討論的方法和設計過程為用戶設計其他的游戲(如象棋和圍棋等)提供了一個參考。
Ⅲ 五子棋游戲計算機採用哪些演算法來確定勝負
明星局為斜指開局的第11局,其結論為:RIF規則下黑必勝。
明星開局屬於分離型開局,故白4不易防黑的優勢區,最好採用「牽制」的辦法。即:H9,控制黑的一個活2,自己做一個活2,如下面圖1。如果「跟隨」防守,黑將會繼續在下方擴大優勢,如下面圖2。
白4選擇H9後,黑只好G9控制,如下面圖1,這樣黑既可以往下發展,也可以往左發展。
根據開局搶2原則,白6顯然走I7,擋對面的活2,自己成活2。
由於白6形成了新的活2,黑又沒有進攻可言,所以黑只能繼續控制,I6,把局勢繼續往下拉。
黑7選擇了I6,黑的連接點主要有G6和G8、F8。F8或G8是一個三通點,G6是活3點,所以G8要強於G6。本次我們討論G6。由於G8和白棋靠的較近,所以F8更強一些。
此時白10可選擇G8,斷黑的一個活2,自己成一個活2。
但此時黑的活2比較多,攻勢已經非常大,經過下面圖1的進攻線路可以取勝。
望採納,謝謝
Ⅳ 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]);
}
Ⅵ 圍棋(5子棋)是怎麼下的 有幾中演算法
五子棋:只要你的棋子有五個是相連的(橫、豎、斜著都行)就算贏了。
圍棋:並不是光算棋子的數量,最終是要看你占的地盤的大小。演算法有好幾種(各個國家的演算法都不太相同),具體你還是看書吧,講的比較清楚。
Ⅶ 五子棋高級演算法
基本演算法:
採用博弈比較常用的策略。
計算機下子前,分別對玩家和電腦棋型進行評估,然後根據棋型對每一位置打分(玩家和電腦在同一點的分數不同),比如活三100分,沖四1000分等,然後根據每個落子點分數進行選擇。採用極大極小值策略,進行多步計算。
-_-.........代碼在文件夾chess里啊..........
一些可能有用的鏈接
http://topic.csdn.net/t/20001021/09/35626.html
http://..com/question/46388110.html?si=6