C++程序設(shè)計(jì)-五子棋
前言:很多剛剛接觸編程的人都不知道怎么下手編寫程序,特別是學(xué)習(xí)了新的知識(shí)點(diǎn),不知道有什么用,那么本文將以簡(jiǎn)單的存儲(chǔ)結(jié)構(gòu)及簡(jiǎn)單的運(yùn)算,條件語(yǔ)句,分支語(yǔ)句,循環(huán)語(yǔ)句結(jié)合,帶來(lái)一個(gè)雙人對(duì)戰(zhàn)版五子棋,這是一個(gè)簡(jiǎn)單的模型,實(shí)現(xiàn)了五子棋最最基本的功能,還有好多地方需要補(bǔ)全,如邊界問(wèn)題,設(shè)計(jì)問(wèn)題,游戲邏輯問(wèn)題,希望讀者閱讀后能夠注意,通過(guò)自己的努力來(lái)完善它,還能擴(kuò)展各種功能,如悔棋,網(wǎng)絡(luò)對(duì)戰(zhàn)等,有時(shí)候?qū)懗绦蚝托∩粯樱龝?huì)成長(zhǎng),而我們作為“父母”的看到自己的小寶寶成為有用之才,過(guò)程之欣喜特別棒!下面正題!
需求分析:通過(guò)C++語(yǔ)言來(lái)實(shí)現(xiàn)一個(gè)以windows控制臺(tái)為展示平臺(tái)的簡(jiǎn)單版五子棋程序,其中通過(guò)鍵盤輸入來(lái)控制游戲中的行為(光標(biāo)移動(dòng)、落子、確認(rèn))。規(guī)則要求某一方在橫豎斜方向連續(xù)存在五個(gè)或五個(gè)以上本人所執(zhí)棋子獲得為獲勝。
流程設(shè)計(jì):
游戲流程分析:
當(dāng)我們要扒一個(gè)已存在的程序時(shí)(有的是五子棋的程序,可以在互聯(lián)網(wǎng)里找到很多),我們可以從他的UI入手,通過(guò)我們所觀察到的,所感受到,所使用到的服務(wù),來(lái)對(duì)軟件進(jìn)行分析,從而獲得以上流程,但我們一旦需要將需求變?yōu)榇a時(shí),我們的設(shè)計(jì)就要考慮的更多了。
這樣我們就需要一種能力--抽象
1.首先,我們需要一個(gè)棋盤,那么我可以使用C++里的什么來(lái)存儲(chǔ)和表示棋盤呢?通過(guò)抽象,因?yàn)槠灞P是個(gè)二維圖形,我推薦使用二維數(shù)組,假設(shè)我們構(gòu)建一個(gè)19行*19列的棋盤。
實(shí)現(xiàn):
int qiPan[19][19]; //聲明一個(gè)19行19列的數(shù)組來(lái)存儲(chǔ)棋盤 for(int h=0;h<19;h++) //對(duì)數(shù)組進(jìn)行遍歷,所有元素進(jìn)行初始化(賦值),默認(rèn)為0值 { for(int l=0;l<19;l++) { qiPan[h][l]=0; //對(duì)當(dāng)前元素進(jìn)行初始化(賦值),默認(rèn)為0值 } } for(int h=0;h<19;h++) //打印 { for(int l=0;l<19;l++) { switch(qiPan[h][l]) { case 0: //如果棋盤存儲(chǔ)的元素為0時(shí),我們打印 · 樣式的字符 cout<<"·"; break; } } cout<<endl; }
運(yùn)行以上代碼,我們可以得到一個(gè)棋盤。
2.那么擁有棋盤后,我們需要擁有一個(gè)光標(biāo),來(lái)對(duì)落子位置進(jìn)行定點(diǎn),那么我如何進(jìn)行表示呢。我們可以在棋盤上找一個(gè)點(diǎn),也就是在數(shù)組對(duì)應(yīng)位置找一個(gè)元素,更改他的值,我們用8來(lái)表示光標(biāo),而找到這個(gè)元素我們需要知道其橫縱坐標(biāo)值,我們用兩個(gè)int變量表示。
int X=9; //2.聲明并初始化光標(biāo)的橫縱坐標(biāo) int Y=9; qiPan[9][9]=8; //更改棋盤中光標(biāo)所在元素的值為8
打印時(shí),我們只要在switch 語(yǔ)句中添加一個(gè)case 選項(xiàng) 8即可:
case 8: //如果棋盤存儲(chǔ)的元素為0時(shí),我們打印 · 樣式的字符 cout<<"╋"; break;
獲得光標(biāo)后我們?nèi)绾我苿?dòng)他呢?那么我們可以通過(guò)接受鍵盤輸入的字符來(lái)控制光標(biāo)的移動(dòng),本例中使用 W上,S下,A左,D右 來(lái)移動(dòng)光標(biāo)。
char xx=getch(); //控制臺(tái)從鍵盤獲得一個(gè)字符的函數(shù)(方法) switch(xx) //控制 { case 'w': //上 Y=Y-1; //使光標(biāo)縱坐標(biāo)-1 qiPan[Y][X]=8; //將光標(biāo)寫入棋盤 qiPan[Y+1][X]=0; //使原本位置的值還原 break; case 's': //下 Y=Y+1; qiPan[Y][X]=8; qiPan[Y-1][X]=0; break; case 'a': //左 X=X-1; qiPan[Y][X]=8; qiPan[Y][X+1]=0; break; case 'd': //右 X=X+1; qiPan[Y][X]=8; qiPan[Y][X-1]=0; break; }
3.這時(shí),我們可以控制光標(biāo)的移動(dòng)了,接下來(lái)要實(shí)現(xiàn)落子操作,棋子又怎么表示呢?
我們可以使用兩個(gè)int類型的值來(lái)表示:白子- 1,黑子- 2,那么我們只要在棋盤中更改光標(biāo)所在位置元素的值為1或2就可以了,那么我們這么做可行嗎?
我們回顧一下光標(biāo)移動(dòng)的代碼,我們會(huì)發(fā)現(xiàn),光標(biāo)的移動(dòng)會(huì)影響元素的變化,那么我們?nèi)绻谄灞P中進(jìn)行落子后,我們光標(biāo)再次移動(dòng)有可能會(huì)改變已記錄的落子信息,為了使光標(biāo)與棋子不沖突,我們使用兩個(gè)圖層,表示兩個(gè)相同的棋盤。
那么我就需要再聲明一個(gè)棋盤,方法和1中一樣:
int qiPanTwo[19][19]; //聲明一個(gè)19行19列的數(shù)組來(lái)存儲(chǔ)棋盤 for(int h=0;h<19;h++) //對(duì)數(shù)組進(jìn)行遍歷,所有元素進(jìn)行初始化(賦值),默認(rèn)為0值 { for(int l=0;l<19;l++) { qiPanTwo[h][l]=0; //對(duì)當(dāng)前元素進(jìn)行初始化(賦值),默認(rèn)為0值 } }
好,棋盤2已經(jīng)建立好了,那么我們?nèi)绾温渥??我們一定要選擇執(zhí)棋方后,在光標(biāo)位置通過(guò)接收鍵盤輸入的j落子,那么我們只需要在2.中switch語(yǔ)句中添加一個(gè)分支 case 'j':即可,并且我們需要使用一個(gè)變量來(lái)表示玩家,我們可以在程序一開始定義:
int player=1;//設(shè)定玩家并進(jìn)行初始化賦值 case 'j': //落子 if(player==1) //如果當(dāng)前玩家為白色方時(shí) { qiPanTwo[Y][X]=1; //通過(guò)棋盤1中的光標(biāo)位置更改棋盤2 //中對(duì)應(yīng)元素的值為1,也就是白棋落子 player=2; //白棋落子后更換玩家 } else if(player==2) { qiPanTwo[Y][X]=2; player=1; } break;
落子成功,接下來(lái)我們可以把它展示出來(lái),由于此時(shí)我們要對(duì)兩個(gè)棋盤進(jìn)行統(tǒng)一的打印,那么我們使用swicth就不能進(jìn)行統(tǒng)一的分支選擇了,此時(shí)我們需要將1.中的打印內(nèi)容改為:
if(qiPan[h][l]==8) //由于光標(biāo)所在圖層應(yīng)該在棋子圖層之上,所以優(yōu)先考慮。 { cout<<"╋"; } else if(qiPanTwo[h][l]==0) { cout<<"·"; } else if(qiPanTwo[h][l]==1) { cout<<"●"; } else if(qiPanTwo[h][l]==2) { cout<<"○"; }
4.游戲規(guī)則,我們落子之后要進(jìn)行一個(gè)判斷,如何判斷是否勝利呢?
此時(shí),我們就要使用游戲規(guī)則來(lái)進(jìn)行算法的分析,當(dāng)落子位橫、縱、斜5格內(nèi)存在相互連接的五個(gè)同類棋子時(shí),我們可認(rèn)為執(zhí)該棋者獲勝,所以我們需要在各個(gè)方向進(jìn)行判斷。
int shu=1,heng=1,pie=1,na=1;//橫豎撇捺計(jì)數(shù)器,累計(jì)到5則表示某方向出現(xiàn)五個(gè)相同的旗子 for(int i=1;i<=4;i++) //上 { if(qiPanTwo[Y+i][X]==qiPanTwo[Y][X]&&qiPanTwo[Y][X]!=0) shu++; else break; } for(int i=1;i<=4;i++) //下 { if(qiPanTwo[Y-i][X]==qiPanTwo[Y][X]&&qiPanTwo[Y][X]!=0) shu++; else break; } for(int i=1;i<=4;i++) //左 { if(qiPanTwo[Y][X-i]==qiPanTwo[Y][X]&&qiPanTwo[Y][X]!=0) heng++; else break; } for(int i=1;i<=4;i++) //右 { if(qiPanTwo[Y][X+i]==qiPanTwo[Y][X]&&qiPanTwo[Y][X]!=0) heng++; else break; } for(int i=1;i<=4;i++) //左下 { if(qiPanTwo[Y+i][X-i]==qiPanTwo[Y][X]&&qiPanTwo[Y][X]!=0) pie++; else break; } for(int i=1;i<=4;i++) //右上 { if(qiPanTwo[Y-i][X+i]==qiPanTwo[Y][X]&&qiPanTwo[Y][X]!=0) pie++; else break; } for(int i=1;i<=4;i++) //右下 { if(qiPanTwo[Y+i][X+i]==qiPanTwo[Y][X]&&qiPanTwo[Y][X]!=0) na++; else break; } for(int i=1;i<=4;i++) //左上 { if(qiPanTwo[Y-i][X-i]==qiPanTwo[Y][X]&&qiPanTwo[Y][X]!=0) na++; else break; } if(shu==5||heng==5||pie==5||na==5) { if(qiPanTwo[Y][X]==1) { cout<<"白子獲勝!"; system("pause"); break; } else { cout<<"黑子獲勝!"; system("pause"); break; } } shu=1,heng=1,pie=1,na=1;
好 當(dāng)完成這一步時(shí),我們的程序基本就搞定了,剩下就是按照一開始的流程進(jìn)行拼接了,其中我們?cè)诖蛴∑聊恢?,要?duì)上一次打印的結(jié)果進(jìn)行擦除,使用函數(shù)
system(“cls”);//擦除控制臺(tái)中所有已顯示的字符
就可以完成了。
完整代碼(可運(yùn)行):
#include<iostream> #include<string> #include<windows.h> #include<conio.h> using namespace std; int main() { int player=1; //定義一個(gè)玩家,當(dāng)1時(shí)為白方,2時(shí)為黑方 //................................棋盤1.............................................. int qiPan[19][19]; //1.聲明一個(gè)19行19列的數(shù)組來(lái)存儲(chǔ)棋盤 1 for(int h=0;h<19;h++) //對(duì)數(shù)組進(jìn)行遍歷,所有元素進(jìn)行初始化(賦值),默認(rèn)為0值 { for(int l=0;l<19;l++) { qiPan[h][l]=0; //對(duì)當(dāng)前元素進(jìn)行初始化(賦值),默認(rèn)為0值 } } //...............................棋盤2................................................ int qiPanTwo[19][19]; //聲明一個(gè)19行19列的數(shù)組來(lái)存儲(chǔ)棋盤 2 for(int h=0;h<19;h++) //對(duì)數(shù)組進(jìn)行遍歷,所有元素進(jìn)行初始化(賦值),默認(rèn)為0值 { for(int l=0;l<19;l++) { qiPanTwo[h][l]=0; //對(duì)當(dāng)前元素進(jìn)行初始化(賦值),默認(rèn)為0值 } } //...............................光標(biāo)聲明............................................. int X=9; //2.聲明并初始化光標(biāo)的橫縱坐標(biāo) int Y=9; qiPan[9][9]=8; //..............................顯示................................................... for(int h=0;h<19;h++) { for(int l=0;l<19;l++) { if(qiPan[h][l]==8) { cout<<"╋"; } else if(qiPanTwo[h][l]==0) { cout<<"·"; } else if(qiPanTwo[h][l]==1) { cout<<"●"; } else if(qiPanTwo[h][l]==2) { cout<<"○"; } } cout<<endl; } //..............................輸入控制............................................... while(true) { char xx=getch(); //控制臺(tái)從鍵盤獲得一個(gè)字符 switch(xx) //控制 { case 'w': //上 Y=Y-1; //使光標(biāo)縱坐標(biāo)-1 qiPan[Y][X]=8; //講光標(biāo)寫入棋盤 qiPan[Y+1][X]=0; //使原本位置的值還原 break; case 's': //下 Y=Y+1; qiPan[Y][X]=8; qiPan[Y-1][X]=0; break; case 'a': //左 X=X-1; qiPan[Y][X]=8; qiPan[Y][X+1]=0; break; case 'd': //右 X=X+1; qiPan[Y][X]=8; qiPan[Y][X-1]=0; break; case 'j': //落子 if(player==1) //如果當(dāng)前玩家為白色方時(shí) { qiPanTwo[Y][X]=1; //通過(guò)棋盤1中的光標(biāo)位置更改棋盤2中對(duì)應(yīng)元素的值為1,也就是白棋落子 player=2; //白棋落子后更換玩家 } else if(player==2) { qiPanTwo[Y][X]=2; player=1; } break; } //................................清屏操作................................................ system("cls"); //...............................打印..................................................... for(int h=0;h<19;h++) { for(int l=0;l<19;l++) { if(qiPan[h][l]==8) { cout<<"╋"; } else if(qiPanTwo[h][l]==0) { cout<<"·"; } else if(qiPanTwo[h][l]==1) { cout<<"●"; } else if(qiPanTwo[h][l]==2) { cout<<"○"; } } cout<<endl; } //.........................游戲規(guī)則.............................................. int shu=1,heng=1,pie=1,na=1;//橫豎撇捺 for(int i=1;i<=4;i++) //上 { if(qiPanTwo[Y+i][X]==qiPanTwo[Y][X]&&qiPanTwo[Y][X]!=0) shu++; else break; } for(int i=1;i<=4;i++) //下 { if(qiPanTwo[Y-i][X]==qiPanTwo[Y][X]&&qiPanTwo[Y][X]!=0) shu++; else break; } for(int i=1;i<=4;i++) //左 { if(qiPanTwo[Y][X-i]==qiPanTwo[Y][X]&&qiPanTwo[Y][X]!=0) heng++; else break; } for(int i=1;i<=4;i++) //右 { if(qiPanTwo[Y][X+i]==qiPanTwo[Y][X]&&qiPanTwo[Y][X]!=0) heng++; else break; } for(int i=1;i<=4;i++) //左下 { if(qiPanTwo[Y+i][X-i]==qiPanTwo[Y][X]&&qiPanTwo[Y][X]!=0) pie++; else break; } for(int i=1;i<=4;i++) //右上 { if(qiPanTwo[Y-i][X+i]==qiPanTwo[Y][X]&&qiPanTwo[Y][X]!=0) pie++; else break; } for(int i=1;i<=4;i++) //右下 { if(qiPanTwo[Y+i][X+i]==qiPanTwo[Y][X]&&qiPanTwo[Y][X]!=0) na++; else break; } for(int i=1;i<=4;i++) //左上 { if(qiPanTwo[Y-i][X-i]==qiPanTwo[Y][X]&&qiPanTwo[Y][X]!=0) na++; else break; } if(shu==5||heng==5||pie==5||na==5) { if(qiPanTwo[Y][X]==1) { cout<<"白子獲勝!"; system("pause"); break; } else { cout<<"黑子獲勝!"; system("pause"); break; } } } return 0; }
以上就是本文的全部?jī)?nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,同時(shí)也希望多多支持我們!
欄 目:C語(yǔ)言
下一篇:C/C++中運(yùn)算符的優(yōu)先級(jí)、運(yùn)算符的結(jié)合性詳解
本文標(biāo)題:C++程序設(shè)計(jì)-五子棋
本文地址:http://mengdiqiu.com.cn/a1/Cyuyan/1731.html
您可能感興趣的文章
- 04-02c語(yǔ)言沒(méi)有round函數(shù) round c語(yǔ)言
- 01-10深入理解C++中常見的關(guān)鍵字含義
- 01-10使用C++實(shí)現(xiàn)全排列算法的方法詳解
- 01-10c++中inline的用法分析
- 01-10用C++實(shí)現(xiàn)DBSCAN聚類算法
- 01-10全排列算法的非遞歸實(shí)現(xiàn)與遞歸實(shí)現(xiàn)的方法(C++)
- 01-10C++大數(shù)模板(推薦)
- 01-10淺談C/C++中的static與extern關(guān)鍵字的使用詳解
- 01-10深入C/C++浮點(diǎn)數(shù)在內(nèi)存中的存儲(chǔ)方式詳解
- 01-10深入理解C/C++混合編程


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 04-02c語(yǔ)言函數(shù)調(diào)用后清空內(nèi)存 c語(yǔ)言調(diào)用
- 04-02func函數(shù)+在C語(yǔ)言 func函數(shù)在c語(yǔ)言中
- 04-02c語(yǔ)言的正則匹配函數(shù) c語(yǔ)言正則表達(dá)
- 04-02c語(yǔ)言用函數(shù)寫分段 用c語(yǔ)言表示分段
- 04-02c語(yǔ)言中對(duì)數(shù)函數(shù)的表達(dá)式 c語(yǔ)言中對(duì)
- 04-02c語(yǔ)言編寫函數(shù)冒泡排序 c語(yǔ)言冒泡排
- 04-02c語(yǔ)言沒(méi)有round函數(shù) round c語(yǔ)言
- 04-02c語(yǔ)言分段函數(shù)怎么求 用c語(yǔ)言求分段
- 04-02C語(yǔ)言中怎么打出三角函數(shù) c語(yǔ)言中怎
- 04-02c語(yǔ)言調(diào)用函數(shù)求fibo C語(yǔ)言調(diào)用函數(shù)求
隨機(jī)閱讀
- 01-10C#中split用法實(shí)例總結(jié)
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 04-02jquery與jsp,用jquery
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 01-10delphi制作wav文件的方法
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改