日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

c语言编程一个象棋游戏,急求:C语言编写的中国象棋游戏一个

發布時間:2025/3/15 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c语言编程一个象棋游戏,急求:C语言编写的中国象棋游戏一个 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

急求:C語言編寫的中國象棋游戲一個

來源:互聯網??2009-09-08 12:30:35??評論

分類: 電腦/網絡 >> 程序設計 >> 其他編程語言

問題描述:

由于學習需要......熱烈歡迎個位大俠,高手相助!小生在此道謝了!!! 希望留下您的郵箱或者QQ以遍交流。20分哦

參考答案:

先弄明白數據的結構:

MantisChessDef.h里的東西一定要先看一下, 否則會摸不到頭腦的。

還有棋盤坐標:

象棋棋盤大小9x10,為了便于編程,規定棋盤每條邊留有一個元素的邊界。

這樣棋盤大小(包括邊界)變成11x12。棋盤x坐標軸向右,y軸向下。

黑棋永遠在上方,在標準開局時左上角的黑車坐標是(1,1)。

局面用這三個變量表示:

static POINT g_pointChessman[32]; //棋子坐標

static int g_iChessmanMap[11][12]; //棋位狀態

static int g_iSide; //輪到哪方走

智能部分有幾個函數的前三個參數就是這個東西, 應該不難理解吧?

---------------------------------------------------------------------------------------

search函數:

先說明一下, 經常有朋友問我要原理, 但我公開源代碼是給大家一個參考, 而不是什么教程,所以我不想說那些理論的東西。

基本原理是α-β搜索, 很多人工智能的教科書上都有講到, 沒看過的的趕快去找一本來啃一啃;

雖然這些書上的文字大多晦澀難懂,但畢竟講得明明白白。

沒有書的朋友請發揮一下主觀能動性, 去找一找,不要來問我要, 因為我也沒有。

我在這里只分析一下search函數:

弄懂α-β搜索后來看看這個博弈樹, 看怎么編程實現它。

先規定一下, 我們用一個整數表示局面的好壞.

這個數越大說明局面對 "走棋方" 越有利,0表示雙方實力相等。

1a( 1) ┬ 2a(-1) ┬ 3a(-1)

│ └ 3b( 1)

└ 2b(-5) ┬ 3c( 2)

├ 3d(-4)

└ 3e( 5)

分析一下這棵樹,有這么個特點: 父結點的值 = -MAX(子結點的值)

我們還知道1、每個結點對應一個局面。2、底層的結點的值是"估"出來的。

于是我們可以寫出偽代碼了:

偽代碼: 搜索一個結點下的分支, 得到這個結點的值。

參數: 局面,搜索深度

返回值:結點的值

int search(局面,int depth)

{

if(depth!=0)//不是底層結點

{

枚舉出所有子結點(列出所有走法);

int count=子結點數;

int maxvalue= -∞;

for(int i=0;i

{

算出子結點局面;

maxvalue=max(maxvalue,search(子結點局面,depth-1));

}

return -maxvalue;

}

else //是底層結點

{

return 估計值;

}

}

這就是搜索算法的框架, 用到了遞歸。

MantisChess的智能部分函數都在MantisChessThink.cpp里, 其中search是搜索, 跟上面的這個search差不多,我把它copy出來注釋一下:

int Search(int tmap[11][12],POINT tmanposition[32],int &tside,int man, POINT point,int upmax,int depth)

{

//前面的三個參數就是局面。

//man 和point 是走法,用來計算本結點的局面。 這里是把計算局面放在函數的開頭,跟上面的偽代碼不太一樣。

//upmax: up - 上一層, max - 最大值, 這是α-β的剪枝用到的東西, 后面再講。

//depth: 搜索深度

int ate,cur,maxvalue,curvalue,xs,ys;

int count;

//#####################這一段是計算本結點的局面#########################################

ate=32;

//移動棋子:

xs=tmanposition[man].x;ys=tmanposition[man].y; //原坐標

if (SideOfMan[tmap[point.x][point.y]]==!tside) //目標點有對方的棋子

{

ate=tmap[point.x][point.y]; //記錄下被吃掉的棋子

if(ate==0 || ate==16)

{

return 9999;

}

tmanposition[ate].x=0; //目標點的棋子被吃掉

}

tmap[point.x][point.y]=man; //這兩行是:

tmap[xs][ys]=32; //在map上的移動

tmanposition[man]=point;

tside=!tside;

//####################################################################################

depth--;

if(depth>0) //不是底層結點

{

int chessman[125];

POINT targetpoint[125];

if(EnumList(tmap,tmanposition,tside,chessman,targetpoint,count)) //枚舉出所有子結點(列出所有走法)

{

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

//這里是剪枝(不是α-β剪枝), 原理是在正式搜索之前先用較淺的搜索來得到誤差較大的值

//然后根據這些值來對子結點排序, 只保留最好的S_WIDTH個結點進行正式搜索。

//顯然,這個剪枝有一定的風險

if(depth>=2 && count>S_WIDTH+2)

{

int value[125];

cur=0;

maxvalue=-10000;

while(cur< count)

{

curvalue=Search(tmap,tmanposition,tside,chessman[cur],targetpoint[cur],-10000,depth-2);

value[cur]=curvalue;

if(curvalue>maxvalue)maxvalue=curvalue;

cur ++;

}

::Mantis_QuickSort(value,chessman,targetpoint,0,count-1); //排序

count=S_WIDTH;//剪枝

}

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

maxvalue=-10000;

cur=0;

while(cur< count)

{

curvalue=Search(tmap,tmanposition,tside,chessman[cur],targetpoint[cur],maxvalue,depth);

if(curvalue>maxvalue)maxvalue=curvalue;

if(curvalue>=-upmax)goto _ENDSUB; //α-β剪枝, 符合剪枝條件的就Cut掉。 這里用了goto語句了, 千萬別學我。

cur ++;

}

}

else maxvalue=9800;

}

else //是底層結點

{

maxvalue=Value(tmap,tmanposition,tside); //估值

}

_ENDSUB:

//返回之前要恢復父結點的局面

//####################################################################################

tmanposition[man].x=xs; //這兩行是:

tmanposition[man].y=ys; //在face上的恢復

tmap[xs][ys]=man; //在map上的恢復

if(ate!=32)

{

tmanposition[ate]=point;

tmap[point.x][point.y]=ate;

}

else tmap[point.x][point.y]=32;

tside=!tside;

//####################################################################################

return -maxvalue;

}

上面的代碼用到了α-β剪枝, 舉個例子就明白了:

還是這個博弈樹,從上往下遍歷。

1a( 1) ┳ 2a(-1) ┳ 3a(-1)

┃ ┗ 3b( 1)

┗ 2b(-5) ┯ 3c( 2)

├ 3d(-4)

└ 3e( 5)

2a遍歷完后 upmax=-1, 繼續遍歷完3c后返回2b, 發現3c=2>-upmax, 這時就不用管3d和3e了, 因為無論他們的值是多少 2b=-max(3c,3d,3e)<2a 一定成立,

也就是說2b可以安全地剪掉。這就是α-β剪枝。

從上面的代碼來看我的MantisChess算法與標準的α-β剪枝搜索并沒有什么不同, 只不過加了排序和剪枝而已。

[b]分類:[/b] 電腦/網絡 >> 程序設計 >> 其他編程語言[br][b]問題描述:[/b][br]由于學習需要......熱烈歡迎個位大俠,高手相助!小生在此道謝了!!! 希望留下您的郵箱或者QQ以遍交流。20分哦[br][b]參考答案:[/b][br]先弄明白數據的結構:

MantisChessDef.h里的東西一定要先看一下, 否則會摸不到頭腦的。

還有棋盤坐標:

象棋棋盤大小9x10,為了便于編程,規定棋盤每條邊留有一個元素的邊界。

這樣棋盤大小(包括邊界)變成11x12。棋盤x坐標軸向右,y軸向下。

黑棋永遠在上方,在標準開局時左上角的黑車坐標是(1,1)。

局面用這三個變量表示:

static POINT g_pointChessman[32]; //棋子坐標

static int g_iChessmanMap[11][12]; //棋位狀態

static int g_iSide; //輪到哪方走

智能部分有幾個函數的前三個參數就是這個東西, 應該不難理解吧?

---------------------------------------------------------------------------------------

search函數:

先說明一下, 經常有朋友問我要原理, 但我公開源代碼是給大家一個參考, 而不是什么教程,所以我不想說那些理論的東西。

基本原理是α-β搜索, 很多人工智能的教科書上都有講到, 沒看過的的趕快去找一本來啃一啃;

雖然這些書上的文字大多晦澀難懂,但畢竟講得明明白白。

沒有書的朋友請發揮一下主觀能動性, 去找一找,不要來問我要, 因為我也沒有。

我在這里只分析一下search函數:

弄懂α-β搜索后來看看這個博弈樹, 看怎么編程實現它。

先規定一下, 我們用一個整數表示局面的好壞.

這個數越大說明局面對 "走棋方" 越有利,0表示雙方實力相等。

1a( 1) ┬ 2a(-1) ┬ 3a(-1)

│ └ 3b( 1)

└ 2b(-5) ┬ 3c( 2)

├ 3d(-4)

└ 3e( 5)

分析一下這棵樹,有這么個特點: 父結點的值 = -MAX(子結點的值)

我們還知道1、每個結點對應一個局面。2、底層的結點的值是"估"出來的。

于是我們可以寫出偽代碼了:

偽代碼: 搜索一個結點下的分支, 得到這個結點的值。

參數: 局面,搜索深度

返回值:結點的值

int search(局面,int depth)

{

if(depth!=0)//不是底層結點

{

枚舉出所有子結點(列出所有走法);

int count=子結點數;

int maxvalue= -∞;

for(int i=0;i

{

算出子結點局面;

maxvalue=max(maxvalue,search(子結點局面,depth-1));

}

return -maxvalue;

}

else //是底層結點

{

return 估計值;

}

}

這就是搜索算法的框架, 用到了遞歸。

MantisChess的智能部分函數都在MantisChessThink.cpp里, 其中search是搜索, 跟上面的這個search差不多,我把它copy出來注釋一下:

int Search(int tmap[11][12],POINT tmanposition[32],int &tside,int man, POINT point,int upmax,int depth)

{

//前面的三個參數就是局面。

//man 和point 是走法,用來計算本結點的局面。 這里是把計算局面放在函數的開頭,跟上面的偽代碼不太一樣。

//upmax: up - 上一層, max - 最大值, 這是α-β的剪枝用到的東西, 后面再講。

//depth: 搜索深度

int ate,cur,maxvalue,curvalue,xs,ys;

int count;

//#####################這一段是計算本結點的局面#########################################

ate=32;

//移動棋子:

xs=tmanposition[man].x;ys=tmanposition[man].y; //原坐標

if (SideOfMan[tmap[point.x][point.y]]==!tside) //目標點有對方的棋子

{

ate=tmap[point.x][point.y]; //記錄下被吃掉的棋子

if(ate==0 || ate==16)

{

return 9999;

}

tmanposition[ate].x=0; //目標點的棋子被吃掉

}

tmap[point.x][point.y]=man; //這兩行是:

tmap[xs][ys]=32; //在map上的移動

tmanposition[man]=point;

tside=!tside;

//####################################################################################

depth--;

if(depth>0) //不是底層結點

{

int chessman[125];

POINT targetpoint[125];

if(EnumList(tmap,tmanposition,tside,chessman,targetpoint,count)) //枚舉出所有子結點(列出所有走法)

{

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

//這里是剪枝(不是α-β剪枝), 原理是在正式搜索之前先用較淺的搜索來得到誤差較大的值

//然后根據這些值來對子結點排序, 只保留最好的S_WIDTH個結點進行正式搜索。

//顯然,這個剪枝有一定的風險

if(depth>=2 && count>S_WIDTH+2)

{

int value[125];

cur=0;

maxvalue=-10000;

while(cur< count)

{

curvalue=Search(tmap,tmanposition,tside,chessman[cur],targetpoint[cur],-10000,depth-2);

value[cur]=curvalue;

if(curvalue>maxvalue)maxvalue=curvalue;

cur ++;

}

::Mantis_QuickSort(value,chessman,targetpoint,0,count-1); //排序

count=S_WIDTH;//剪枝

}

//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

maxvalue=-10000;

cur=0;

while(cur< count)

{

curvalue=Search(tmap,tmanposition,tside,chessman[cur],targetpoint[cur],maxvalue,depth);

if(curvalue>maxvalue)maxvalue=curvalue;

if(curvalue>=-upmax)goto _ENDSUB; //α-β剪枝, 符合剪枝條件的就Cut掉。 這里用了goto語句了, 千萬別學我。

cur ++;

}

}

else maxvalue=9800;

}

else //是底層結點

{

maxvalue=Value(tmap,tmanposition,tside); //估值

}

_ENDSUB:

//返回之前要恢復父結點的局面

//####################################################################################

tmanposition[man].x=xs; //這兩行是:

tmanposition[man].y=ys; //在face上的恢復

tmap[xs][ys]=man; //在map上的恢復

if(ate!=32)

{

tmanposition[ate]=point;

tmap[point.x][point.y]=ate;

}

else tmap[point.x][point.y]=32;

tside=!tside;

//####################################################################################

return -maxvalue;

}

上面的代碼用到了α-β剪枝, 舉個例子就明白了:

還是這個博弈樹,從上往下遍歷。

1a( 1) ┳ 2a(-1) ┳ 3a(-1)

┃ ┗ 3b( 1)

┗ 2b(-5) ┯ 3c( 2)

├ 3d(-4)

└ 3e( 5)

2a遍歷完后 upmax=-1, 繼續遍歷完3c后返回2b, 發現3c=2>-upmax, 這時就不用管3d和3e了, 因為無論他們的值是多少 2b=-max(3c,3d,3e)<2a 一定成立,

也就是說2b可以安全地剪掉。這就是α-β剪枝。

從上面的代碼來看我的MantisChess算法與標準的α-β剪枝搜索并沒有什么不同, 只不過加了排序和剪枝而已。

總結

以上是生活随笔為你收集整理的c语言编程一个象棋游戏,急求:C语言编写的中国象棋游戏一个的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。