本文目錄一覽:
用C語言在linux下編寫一個五子棋程序!
五子棋的核心算法
五子棋是一種受大眾廣泛喜愛的遊戲,其規則簡單,變化多端,非常富有趣味性和消遣性。這裡設計和實現了一個人機對下的五子棋程序,採用了博弈樹的方法,應用了剪枝和最大最小樹原理進行搜索發現最好的下子位置。介紹五子棋程序的數據結構、評分規則、勝負判斷方法和搜索算法過程。
一、相關的數據結構
關於盤面情況的表示,以鏈表形式表示當前盤面的情況,目的是可以允許用戶進行悔棋、回退等操作。
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(ab && mode==max)¦¦ (a b && mode==min)
return a;
else
return b;
}
五、小結
在Windows操作系統下,用VC++實現了這個人機對戰的五子棋程序。和國內許多只是採用規則或者只是採用簡單遞歸而沒有剪枝的那些程序相比,在智力上和時間有效性上都要好於這些程序。同時所討論的方法和設計過程為用戶設計其他的遊戲(如象棋和圍棋等)提供了一個參考。
參考資料:
C語言:編寫函數fun返回二維數組周邊元素之和,咋寫?
入門到放棄?
“C/C++真的太難學了,我準備放棄了!”
很多初學者在學完C和C++的基本語法後,就停滯不前了,最終走向“從入門到放棄”。其實,我們初學者最需要的不是HelloWorld,也不是語法知識的堆砌,需要的只是實戰項目的磨礪。
一個項目一座城
一個項目,一座城。寫完一個項目,攻克一座城池。
以下十三個循序漸進的項目,讓你從小白,快速晉陞為大牛。
奇牛項目1《黑客攻擊系統》-第一城
從完全零基礎開始,手把手開發這款黑客攻擊系統。
通過用戶端的輸入, 向服務器端木馬發送攻擊命令,實現多種方式的攻擊效果。
通過這個項目,可以掌握C/C++基礎(數據類型,變量的使用,各種運算,控制語句,命名空間,輸入輸出,函數調用,庫文件的使用等),直接使用圖形庫來實現窗口用戶界面,直接使用庫文件來實現攻擊效果。
奇牛項目2 《人工智能地形導航系統》-第二城
具備C/C++基礎後,進一步學習二維數組、多維數組在工程項目中的應用。
根據地圖的海拔數據,來識別地形上的各個峰點(最高點)和谷點(最低點),以確定地形中峰點的數目和位置,為探測器提供導航數據。
通過這個項目,可以深刻掌握二維數組、多維數組的本質,以及在工程項目中的應用方法。
奇牛項目3《人工智能雙色球預測系統》-第三城
根據筆者Rock的閑暇之作改寫,體會以小博大的樂趣。
通過自動分析博彩官網的海量數據,根據自定義的統計預測規則,來捕捉下期開獎的最大概率。
通過這個項目,掌握指針的使用,以及指針在工程項目中的應用。
奇牛項目4《地震監測系統》-第四城
地震檢波器每隔固定的時間間隔,採樣一次預測地震的能量數據,並保存到文件中。地震監測系統從這個文件中讀取相應的能量數據,測試在給定的時間點上,一個短時間窗口內的取樣值與一個長時間窗口內取樣值的商,如果這個比例高於給定的閾值,那麼在這個事件點上極有可能發生地震。
通過這個項目,掌握C/C++文件的讀寫、以及動態內存管理的使用,以及它們在工程項目中的應用。
奇牛項目5《智能婚戀交友系統》-第五城
程序員的相親活動,低調且奢華。這個項目直接致敬某XX佳緣婚戀交友平台,畢竟Rock也曾經是該平台的註冊會員,並在其中活躍良久。
這個項目實現了該平台的核心功能-高匹配度自動交友。
通過這個項目,掌握C++的面向對象思想、繼承和派生、多態、友元、運算符重載等核心機制,以及它們在工程中的應用。
奇牛項目6《廣州軍區微波通信系統》-第六城
這個項目是根據筆者Rock負責研發的廣州軍區南海無線微波通信系統改寫的, 已去除敏感數據。
這個項目是在菲律賓、越南肆意騷擾我國南海島嶼的背景下研發的。通過這個項目,掌握C++核心機制-多態的使用,以及在軍事工程項目中的應用。
奇牛項目7《模板庫高級編程-萬能擇優器》-第七城
在掌握了C、C++的核心特性之後,能否掌握C++標準模板庫STL, 是區分一名合格C++程序員的重要標誌。
這個項目通過構建一個通用的擇優器,來掌握C++泛型編程的使用,以及在自定義模塊開發中的應用。
奇牛項目8《遊戲服務器端數據庫》-第八城
在征服了C/C++語言的核心特性之後,很多人會感到新的迷茫:C/C++語言到底能做什麼?海量用戶數據怎麼處理?
這個項目從零開始構建大型遊戲數據庫,以掌握數據庫開發的方法,以及在產品級項目中的應用。
奇牛項目9 《企業QQ》-第九城
很多C/C++初學者,認為C和C++雖然很強大,但是對於用戶界面開發,就不是很方便了。
其實對於用戶界面的開發,C和C++,尤其是C++,是非常強悍的。各種絢麗的用戶界面,C++都能遊刃有餘地呈現。
這個項目能夠深度掌握基於C++的用戶界面開發,以及網絡編程,實現產品級的應用效果。
奇牛項目10 《跨平台Word》-第十城
IT外包開發時,用戶的需求總是千變萬化,界面和功能都需要做特殊的定製,這個項目讓我們掌握開發特定UI和特定功能的應用軟件,為以後獨立承接IT外包打下足夠的基礎。
奇牛項目11《 遊戲外*修改器》-第十一城
外*、逆向、破解無疑是每一位程序員為之嚮往的“禁地”,這個項目融合逆向、彙編、DLL注入、內存篡改等黑技術,開發客戶端遊戲的外掛,實現對遊戲數據的截取、修改。
通過這個項目,可以深刻掌握指針、逆向、DLL注入等技術的使用,以及Windows客戶端應用的開發。
奇牛項目12 《人工智能中國象棋人機對弈》-第十二城
完勝李世石和柯潔的阿爾法狗,其底層框架就是使用C++實現的。
除了圍棋,C++更是在象棋領域完勝人類。這個項目,就是使用C++打造的人工智能象棋。
通過這個項目,可以輕鬆掌握各種複雜數據結構,把個人編程能力提升到極致。
奇牛項目13 《電信級大型互聯網項目-共享順風車系統》-第十三城
掌握C、C++客戶端開發之後,高性能服務器開發,成為判別C++高級程序員的重要標誌。這個項目將實現電信級的大型互聯網服務器。
通過奇牛編程的項目實戰,可以掌握百萬級高並發服務器的核心技術(線程池、epool架構、協議開發等)
敲代碼的夜,清脆的鍵擊,孤獨而堅定。
彈指間,攻城略地,早已硝煙瀰漫。
十三座城池,待你來征服。
經過以上13個項目的修鍊,你已經從小白蛻變為能夠駕馭大型項目開發的大牛了。
c語言的題目
version1.0
#include stdio.h
#include stdlib.h
#define length 8
typedef struct circle
{
int row[length],cul[length];
} circle;
int main(void)
{
int num,temp,in,location=0,clow,rlow,flag,j;
scanf(“%d”,num);
circle *record=(circle *)malloc(num*sizeof(circle));
for(temp=0;tempnum;temp++)
for(in=0;inlength;in++)
{
scanf(“%d”,((*(record+temp)).row)+in);
scanf(“%d”,((*(record+temp)).cul)+in);
}
for(temp=0,flag=1;tempnum;temp++)
{
j=temp;
rlow=*((*(record+j)).row);
for(in=1;inlength;in++)
{
if(rlow*(((*(record+j)).row)+in))
rlow=*(((*(record+j)).row)+in);
}
clow=*(((*(record+j)).cul)+in);
while(in2*length)
{
if(rlow*(((*(record+j)).cul)+in))
rlow=*(((*(record+j)).cul)+in);
in++;
}
for(j=0;jnum;j++)
for(in=0;inlength;in++)
{
*(((*(record+j)).row)+in)-=rlow;
*(((*(record+j)).cul)+in)-=clow;
}
for(j=0;jnum;j++)
for(in=0;inlength;in++)
{
if(*(((*(record+j)).row)+in)==0||*(((*(record+j)).row)+in)==2)
if(*(((*(record+j)).cul)+in)3||*(((*(record+j)).cul)+in)0)
flag=0;
else if(*(((*(record+j)).row)+in)==1)
if(*(((*(record+j)).cul)+in)3||*(((*(record+j)).cul)+in)0||*(((*(record+j)).cul)+in)==1)
flag=0;
else
flag=0;
}
if(flag==1)
printf(“YES\n”);
else
printf(“NO\n”);
}
return 0;
}
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/245815.html