真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

C++語言設(shè)計(jì)實(shí)現(xiàn)五子棋-創(chuàng)新互聯(lián)

本文為大家分享了C++五子棋的設(shè)計(jì)思路和設(shè)計(jì)實(shí)現(xiàn),供大家參考,具體內(nèi)容如下

成都創(chuàng)新互聯(lián)從2013年成立,先為興寧等服務(wù)建站,興寧等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為興寧企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。

算法思路:

在結(jié)束了對C++的學(xué)習(xí)之后,準(zhǔn)備自己編制一些簡單的練習(xí)程序。目前初步設(shè)想是編制一個人機(jī)對戰(zhàn)的簡易五子棋軟件。 以下為個人設(shè)計(jì)思考的過程。

首先,進(jìn)行問題分析與設(shè)計(jì)。計(jì)劃實(shí)現(xiàn)的功能為,開局選擇人機(jī)或雙人對戰(zhàn),確定之后比賽開始。比賽結(jié)束后初始化棋盤,詢問是否繼續(xù)比賽或退出。后續(xù)可加入復(fù)盤、悔棋等功能。整個過程中,涉及到了棋子和棋盤兩種對象,同時(shí)要加上人機(jī)對弈時(shí)的AI對象,即涉及到三個對象。

棋盤類的設(shè)計(jì)。

數(shù)據(jù)存儲:五子棋棋盤為15*15的網(wǎng)格結(jié)構(gòu),即一共有225個節(jié)點(diǎn),每個節(jié)點(diǎn)有橫豎坐標(biāo)各一,同時(shí)每個節(jié)點(diǎn)狀態(tài)有3種,黑,白,或者為空。可考慮采用二維數(shù)組來存儲。每個節(jié)點(diǎn)三種狀態(tài),適合采用枚舉(enum)類型。
-* 實(shí)現(xiàn)功能*:1. 棋盤對象應(yīng)負(fù)責(zé)實(shí)時(shí)更新棋盤狀態(tài)并對外顯示,因此需要接收棋子對象的輸入,同時(shí)需要對外輸出。而棋盤對象不需要對棋子對象發(fā)送信息,所以可以設(shè)計(jì)棋盤類中更新棋盤狀態(tài)的函數(shù)接收棋子對象作為形參。2. 同時(shí),在每次走棋之后,棋盤對象都要及時(shí)更新棋盤信息,即輸出棋盤狀態(tài)。3. 而且,每次走棋之后更新輸出之前,應(yīng)該對棋子走棋是否符合規(guī)則以及輸贏進(jìn)行判定。若將規(guī)則判定單獨(dú)封裝為一個對象,則不方便調(diào)用棋盤信息,故將規(guī)則判定設(shè)計(jì)為棋盤類的成員函數(shù),接收兩個形參,一個是棋盤當(dāng)前的狀態(tài),一個是即將走的下一步棋,即一個棋子對象。

設(shè)計(jì)棋子對象。棋子對象應(yīng)包含兩種信息。一是棋子顏色,二是當(dāng)前要走的棋子的位置坐標(biāo),并保留對外輸出的接口。

接下來細(xì)化規(guī)則判定函數(shù)。

  • 首先進(jìn)行走棋規(guī)則判定。接收當(dāng)前棋子位置信息后,判定該位置是否越界或?yàn)榭?,若非空或者越界,則判定違規(guī),拋擲異常,交付上級調(diào)用處理。
  • 然后進(jìn)行輸贏判定。按照一定順序?qū)Ξ?dāng)前落子位置的相鄰元素進(jìn)行同色判定并計(jì)數(shù)。當(dāng)發(fā)現(xiàn)某條直線上同色棋子超過四枚,則判定當(dāng)前走棋方獲勝 。判定過程中同樣需要注意是否越界。若均未構(gòu)成五星連珠,則進(jìn)入平局判定。
  • 平局判定,遍歷棋盤,統(tǒng)計(jì)空位,若空位為0,即棋盤已滿,判定為平局。

接下來設(shè)計(jì)下棋AI。設(shè)計(jì)為一個棋子類型的函數(shù),即接收當(dāng)前棋盤狀態(tài)和對方最后一次落棋,返回棋子對象類型。

對弈算法設(shè)計(jì)。

  • 首先進(jìn)行先后手判定:若棋盤為空則直接落子(8,8),正中開局。
  • 然后進(jìn)行防守判定:針對對方上次落棋進(jìn)行活棋檢測,在橫、豎、左斜、右斜四條直線上依次進(jìn)行檢測。在任意方向檢測到四或活三,即可進(jìn)行 封堵操作,給出所有可行的封堵位置。若未檢測到四或活三,則統(tǒng)計(jì)活二并給出所有可能的封堵位置。然后針對所有可能的封堵位置進(jìn)行評分,選取分?jǐn)?shù)最高的位置進(jìn)行落子。若上述檢測均未找到防守點(diǎn),則轉(zhuǎn)入進(jìn)攻算法。
  • 進(jìn)攻算法:采用枚舉,即暴力破解的方法。遍歷整個棋盤的所有空位,并給出每個空位的評分,選取最高分進(jìn)行落子。
  • 活棋檢測算法:給定參照棋子,在四個方向上分別檢測。以橫向檢測為例,設(shè)參照棋子坐標(biāo)為(x,y),設(shè)定同色計(jì)數(shù)器count=1(計(jì)算同色棋子數(shù)目),設(shè)定封鎖端統(tǒng)計(jì)量lock=0,設(shè)定已判斷的方向統(tǒng)計(jì)judge=0。對x-1,判斷節(jié)點(diǎn)狀態(tài),若同色計(jì)數(shù)器加1,繼續(xù)判斷x-2;若異色,則lock+1,judge+1,若judge=2,終止判斷,若judge<2,反向判斷x+1;若空白,judge+1,若judge=2,終止判斷,若judge<2,反向判斷。最后得到被封堵的端口數(shù)lock和同色數(shù)count。若lock=0,count=3或2,判定為活3或活2。若lock=1,count=4,判定為4,若lock=1,count=3,判定為半3。但是在這種算法中,關(guān)于空白的判定存在著一些問題。用0代表空白,用+代表同色,-代表異色,則當(dāng)出現(xiàn)下列情況時(shí):-0++0-,-+++0-,事實(shí)上是死棋,而+0++0,+0+++-,實(shí)際上相當(dāng)于活3或半4。為此,需要對活2和半3的情況進(jìn)行進(jìn)一步篩選,即空白端應(yīng)保證連續(xù)兩個空白。在活棋檢測過程中,如果遇到活3或者半4,則立即終止檢測,返回落子的可能位置。若沒有則記錄活2半3的防守位置,換方向檢測。最后返回一個棋子類的數(shù)組,包含所有建議的落子位置。若均無,則遍歷棋盤,統(tǒng)計(jì)所有空白位置,返回。
  • 落子位置評分算法:對活棋檢測返回?cái)?shù)組中的每個位置進(jìn)行評分,即以該點(diǎn)為己方參照點(diǎn),進(jìn)行活棋檢測,若有count=5,直接返回該落子位置。有活三或者半4,分?jǐn)?shù)加20,有活2,分?jǐn)?shù)加5,對角線有相鄰?fù)?,分?jǐn)?shù)+2,有異色,分?jǐn)?shù)-2,橫豎有同色,分?jǐn)?shù)+1,有異色,分?jǐn)?shù)-1。最后排序,取最高分對應(yīng)的落子,返回該落子。

接下來則是數(shù)據(jù)結(jié)構(gòu)和對象設(shè)計(jì)及主函數(shù)調(diào)用實(shí)現(xiàn):

類及類的實(shí)現(xiàn)

#define RENJU_H
#include 
#include 
#include 
#define hor 7
#define ver 4
using namespace std;


//用于記錄坐標(biāo)
struct position
{
 int x;
 int y;
 position()
 {
 x = 0;
 y = 0;
 }
 position(int a,int b)
 {
 x = a;
 y = b;
 }
};


//用于記錄棋子顏色和節(jié)點(diǎn)狀態(tài)
enum state
{
 blank=0,black=1,white=2


};


//用于存儲棋局分析信息:未完賽,犯規(guī),平局,黑方勝,白方勝
enum result
{
 go_on,error,draw,black_win,white_win
};


// 設(shè)置光標(biāo)
void setpos(COORD a) 
{
 HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
 SetConsoleCursorPosition(out, a);
}


// 設(shè)置光標(biāo)
void setpos(int i, int j)
{
 COORD pos = { i, j };
 setpos(pos);
}


//繪圖函數(shù),用于在指定坐標(biāo)輸出指定字符
inline void gps(int x,int y,char c)
{
 setpos(y,x);
 cout<=10)
 cout< max)
 max = a[i];
 }
 return max;
}


//檢測是否符合勝利條件


//棋子類
class chess
{
public:
 inline chess(int x=0,int y=0,state c=blank)
 { point.x=x,point.y=y;
 color=c;
 };
 inline chess(chess &ch) 
 { point=ch.drop_point();
 color=ch.get_color();
 }
 ~chess(){};
 struct position drop_point()const;//用于向外部提供棋子位置
 inline state get_color() const { return color;}//提供棋子顏色信息
 void set_point();//用于從外部獲取棋子位置
 void set_point(int x,int y){ point.x=x,point.y=y;}
 void set_point(position p){ point.x=p.x,point.y=p.y;}
 void set_color(state c){ color=c;}//設(shè)置棋子顏色
private:
 position point;
 enum state color;
 };


position chess::drop_point()const
{
 return point; 
}
 
void chess::set_point()
{
 if(color==black)
 {
 setpos(110,1);
 cout<<"請黑方輸入落子列數(shù)和行數(shù),空格隔開:";
 cin>>point.x>>point.y;
 while(point.x<1||point.x>15)
 {
 setpos(110,1);
 cout<<"列數(shù)輸入超出范圍,請重新輸入1~15之間數(shù)字  ";
 cin>>point.x;
 }
 while(point.y<1||point.y>15)
 {
 setpos(110,2);
 cout<<"行數(shù)輸入超出范圍,請重新輸入1~15之間數(shù)字 ";
 cin>>point.y;
 }
 }
 else if(color==white)
 {
 setpos(110,1);
 cout<<"請白方輸入落子列數(shù)和行數(shù),空格隔開:";
 cin>>point.x>>point.y;
 while(point.x<1||point.x>15)
 {
 setpos(110,1);
 cout<<"列數(shù)輸入超出范圍,請重新輸入1~15之間數(shù)字  ";
 cin>>point.x;
 }
 while(point.y<1||point.y>15)
 {
 setpos(110,2);
 cout<<"行數(shù)輸入超出范圍,請重新輸入1~15之間數(shù)字 ";
 cin>>point.y;
 }
 }
 point.x--;
 point.y--;
}


//棋盤類
class chessboard
{
public:
 chessboard()
 {
 for(int i=0;i<15;i++)
 for(int j=0;j<15;j++)
 {
 square[i][j]=blank;
 }
 }
 chessboard(chessboard *cb)
 {
 for(int i=0;i<15;i++)
 for(int j=0;j<15;j++)
 {
 square[i][j]=cb->viewboard(i,j);
 }
 }
 inline state viewboard(position p_c) const;//接收坐標(biāo),返回該位置的狀態(tài)
 inline state viewboard(int x,int y) const;//接收整數(shù)坐標(biāo),返回該位置的狀態(tài)
 void update(chess ch);//接收新棋子,更新棋盤狀態(tài)
 void display()const;//向外輸出棋盤狀態(tài)
 result judge(chess ch)const;//規(guī)則函數(shù),判斷走棋是否犯規(guī)和輸贏
 void clear()//清空棋盤
 {
 for(int i=0;i<15;i++)
 for(int j=0;j<15;j++)
 {
 square[i][j]=blank;
 }
 }
private:
 state square[15][15];
};
int check_five(chessboard bd,chess ch)
{
 position ori=ch.drop_point();
 int count=1;//計(jì)數(shù)器,統(tǒng)計(jì)同色個數(shù)
 int sum[4]={0};
 bool locked=0;//邏輯標(biāo)記量,用來標(biāo)記是否遇到了非同色節(jié)點(diǎn)
 //水平方向檢測
 for(int i=0,locked=0;i<5&&((ori.x-i)>=0)&&(!locked);i++)//終止循環(huán)條件:同色超過4個或觸碰到棋盤邊界或遇到非同色節(jié)點(diǎn)
 if(ch.get_color()==bd.viewboard(ori.x-i,ori.y))
 count++;
 else
 if(i!=0)
 locked=1;
 //sum[0]=count-1;
 for(int i=0,locked=0;i<5&&((ori.x+i)<=14)&&(!locked);i++)//終止循環(huán)條件:同色超過4個或觸碰到棋盤邊界或遇到非同色節(jié)點(diǎn)
 if(ch.get_color()==bd.viewboard(ori.x+i,ori.y))
 count++;
 else
 if(i!=0)
 locked=1;
 //sum[1]=count-sum[0]-2;
 sum[0]=count;
 if(count>=5)
 return count;
 //豎直方向檢測
 count=1;
 for(int i=0,locked=0;i<5&&((ori.y-i)>=0)&&(!locked);i++)//終止循環(huán)條件:同色超過4個或觸碰到棋盤邊界或遇到非同色節(jié)點(diǎn)
 if(ch.get_color()==bd.viewboard(ori.x,ori.y-i))
 count++;
 else
 if(i!=0)
 locked=1;
 //sum[2]=count-1;
 for(int i=0,locked=0;i<5&&((ori.y+i)<=14)&&(!locked);i++)//終止循環(huán)條件:同色超過4個或觸碰到棋盤邊界或遇到非同色節(jié)點(diǎn)
 if(ch.get_color()==bd.viewboard(ori.x,ori.y+i))
 count++;
 else
 if(i!=0)
 locked=1;
 //sum[3]=count-sum[2]-2;
 sum[1]=count;
 if(count>=5)
 return count;
 //左上到右下斜向檢測
 count=1;
 for(int i=0,locked=0;i<5&&((ori.y-i)>=0)&&((ori.x-i)>=0)&&(!locked);i++)//終止循環(huán)條件:同色超過4個或觸碰到棋盤邊界或遇到非同色節(jié)點(diǎn)
 if(ch.get_color()==bd.viewboard(ori.x-i,ori.y-i))
 count++;
 else
 if(i!=0)
 locked=1;
 //sum[4]=count-1;
 for(int i=0,locked=0;i<5&&((ori.x+i)<=14)&&((ori.y+i)<=14)&&(!locked);i++)//終止循環(huán)條件:同色超過4個或觸碰到棋盤邊界或遇到非同色節(jié)點(diǎn)
 if(ch.get_color()==bd.viewboard(ori.x+i,ori.y+i))
 count++;
 else
 if(i!=0)
 locked=1;
 //sum[5]=count-sum[4]-2;
 sum[2]=count;
 if(count>=5)
 return count;
 //左下到右上斜向檢測
 count=1;
 for(int i=0,locked=0;i<5&&((ori.y+i)<=14)&&((ori.x-i)>=0)&&(!locked);i++)//終止循環(huán)條件:同色超過4個或觸碰到棋盤邊界或遇到非同色節(jié)點(diǎn)
 if(ch.get_color()==bd.viewboard(ori.x-i,ori.y+i))
 count++;
 else
 if(i!=0)
 locked=1;
 //sum[6]=count-1;
 for(int i=0,locked=0;i<5&&((ori.x+i)<=14)&&((ori.y-i)>=0)&&(!locked);i++)//終止循環(huán)條件:同色超過4個或觸碰到棋盤邊界或遇到非同色節(jié)點(diǎn)
 if(ch.get_color()==bd.viewboard(ori.x+i,ori.y-i))
 count++;
 else
 if(i!=0)
 locked=1;
 //sum[7]=count-sum[6]-2;
 sum[3]=count;
 if(count>=5)
 return count;
 return MAX(sum,4);
}


state chessboard::viewboard(position p_c) const
{
 return square[p_c.x][p_c.y];
}
state chessboard::viewboard(int x,int y) const
{
 return square[x][y];
}
void chessboard::update(chess ch)
{
 position pos=ch.drop_point();
 square[pos.x][pos.y]=ch.get_color();
}


void chessboard::display()const
{
 system("cls");


 for(int i=0;i<15;i++)//打印列坐標(biāo)說明
 {
 gps(0,6+i*hor,i+1);
 }
 for(int i=0;i<15;i++)//打印列坐標(biāo)說明
 {
 gps(16*ver,6+i*hor,i+1);
 }
 for(int i=0;i<15;i++)//打印行坐標(biāo)說明
 {
 gps(3+i*ver,1,i+1);
 }
 for(int i=0;i<15;i++)//打印行坐標(biāo)說明
 {
 gps(3+i*ver,1+16*hor,i+1);
 }
 for(int i=0,j=0;i<15;i++)
 {
 for(j=0;j<15;j++)
 tab(1+i*ver,3+hor*j,square[j][i]);
 }
 cout<=5&&(set.get_color()==black))
 return black_win;


 if(check_five(*this,set)>=5&&(set.get_color()==white))
 return white_win;


 for(int i=0;i<15;i++)
 for(int j=0;j<15;j++)
 {
 if(square[i][j]==blank) 
 full=0;
 }
 if(full==1)
 return draw;
 else
 return go_on;
}
#endif

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)建站www.cdcxhl.com,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。


分享標(biāo)題:C++語言設(shè)計(jì)實(shí)現(xiàn)五子棋-創(chuàng)新互聯(lián)
新聞來源:http://weahome.cn/article/cdijsd.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部