C語(yǔ)言實(shí)現(xiàn)井字棋小游戲
C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單的“井字棋游戲”,供大家參考,具體內(nèi)容如下
總體構(gòu)造:
1.游戲菜單的邏輯實(shí)現(xiàn)
2.游戲本體的代碼實(shí)現(xiàn)
part 1:游戲菜單的整體邏輯
①簡(jiǎn)單的通過(guò)一個(gè)輸入0和1的switch函數(shù)實(shí)現(xiàn)判斷是玩游戲還是退出游戲的邏輯
輸入1則進(jìn)入游戲,而且打完game()即游戲本體之后因?yàn)閐o…while函數(shù)輸入1會(huì)繼續(xù)循環(huán)詢問(wèn)是否玩游戲
輸入0則break退出游戲,且退出do…while循環(huán),程序結(jié)束。
int main() { int input = 0; srand((unsigned int)time(NULL)); do { menu(); printf("請(qǐng)輸入>--"); scanf("%d", &input); switch (input) { case 1: game(); break; case 0: printf("游戲退出...exit...\n"); break; default: printf("輸入錯(cuò)誤,請(qǐng)重新輸入\n"); } } while (input); return 0; }
②簡(jiǎn)單粗暴的菜單打印函數(shù)如下
void menu() { printf("******************************\n"); printf("********** 1.play ***********\n"); printf("********** 0.exit ***********\n"); printf("******************************\n"); }
part 2:游戲本體的實(shí)現(xiàn)如下
1.我們先定義一個(gè)二維數(shù)組Board[ROW][COL]作為棋盤(pán),
char Board[ROW][COL] = { 0 };
定義全局變量ROW和COL也就是行數(shù)和列數(shù)為3
#define ROW 3 #define COL 3
2.棋盤(pán)創(chuàng)建好了之后對(duì)這個(gè)棋盤(pán)初始化(構(gòu)建函數(shù))
給這個(gè)函數(shù)傳參需要傳行與列和二維數(shù)組(棋盤(pán))
initBoard(Board, ROW, COL);
用兩層for循環(huán)簡(jiǎn)單的給二維數(shù)組初始化為“空格”
void initBoard(char Board[ROW][COL],int row,int col) { int r = 0; int c = 0; for (r = 0; r < ROW; r++) { for (c = 0; c < COL; c++) { Board[r][c] = ' '; } } }
3.初始化完之后把這個(gè)棋盤(pán)打印出來(lái),定義一個(gè)打印函數(shù)
showBoard(Board,ROW,COL);
用簡(jiǎn)單的豎線和空格打印一個(gè)棋盤(pán)
void showBoard(char Board[ROW][COL], int row, int col) { int r = 0; int c = 0; printf("\n------------\n"); for (r = 0; r < ROW; r++) { for (c = 0; c < COL; c++) { if (c == 2) { printf(" %c ", Board[r][c]); } else { printf(" %c ", Board[r][c]); printf("|"); } } printf("\n------------\n"); } printf("\n"); }
4.構(gòu)建一個(gè)玩家下棋的函數(shù)
PlayerMove(Board, ROW, COL);
玩家輸入了要下的坐標(biāo)后要判斷:
1:玩家輸入的坐標(biāo)是否在棋盤(pán)內(nèi)
2:玩家輸入的坐標(biāo)是不是已經(jīng)被下過(guò)子了
用簡(jiǎn)單的for循環(huán)遍歷和if語(yǔ)句判斷就可以完成
并且每一次需要重新輸入的情況中都打印一次棋盤(pán)作為參考
void PlayerMove(char Board[ROW][COL], int row, int col) { while (1) { int r = 0; int c = 0; char input = '0'; printf("請(qǐng)輸入您要下子的坐標(biāo):(例如:1 2)\n"); scanf("%d %d", &r, &c); if (r > 3 || r<1 || c>3 || c < 1) { system("cls"); printf("錯(cuò)誤的坐標(biāo),請(qǐng)重新輸入!\n"); showBoard(Board, ROW, COL); } else if (Board[r - 1][c - 1] == 'x' || Board[r - 1][c - 1] == '0') { system("cls"); printf("這里已經(jīng)下過(guò)子了,請(qǐng)重新輸入!\n"); showBoard(Board, ROW, COL); } else { system("cls"); Board[r-1][c-1] = 'x'; showBoard(Board, ROW, COL); break; } } }
5.構(gòu)建電腦下棋的函數(shù)
PcMove(Board, ROW, COL);
我們使用隨機(jī)值函數(shù)簡(jiǎn)單的為電腦下棋 ( scand()和rand() )
也要判斷電腦的坐標(biāo)是否已經(jīng)被下過(guò)了
void PcMove(char Board[ROW][COL], int row, int col) { int r = 0; int c = 0; while (1) { r = rand() % ROW; c = rand() % COL; if (Board[r][c] != 'x' && Board[r][c] != '0') { system("cls"); Board[r][c] = '0'; showBoard(Board, ROW, COL); break; } } }
6.最后是判斷輸贏的函數(shù)
這里我們用ret接收一個(gè)函數(shù)返回值,1,2,0分別對(duì)應(yīng)我們贏和電腦贏以及平局
ret = win(Board, ROW, COL);
井字棋獲勝的規(guī)則是三行三豎或者對(duì)角線相同則獲勝,依次判斷即可
int win(char Board[ROW][COL], int row, int col) { int r = 0; int c = 0; int sum = 0; for(r = 0; r < ROW; r++) { //玩家贏返回1,電腦贏返回2 //三橫三豎的判斷 if (Board[r][0] == Board[r][1] && Board[r][2] == Board[r][1] && Board[r][1] == 'x' || Board[0][r] == Board[1][r] && Board[2][r] == Board[1][r] && Board[1][r] == 'x') return 1; if (Board[r][0] == Board[r][1] && Board[r][2] == Board[r][1] && Board[r][1] == '0' || Board[0][r] == Board[1][r] && Board[2][r] == Board[1][r] && Board[1][r] == '0') return 2; } //斜向的判斷 if (Board[0][0] == Board[1][1] && Board[1][1] == Board[2][2] && Board[1][1] == 'x' || Board[0][0] == Board[1][1] && Board[1][1] == Board[2][2] && Board[1][1] == 'x') return 1; if (Board[0][0] == Board[1][1] && Board[1][1] == Board[2][2] && Board[1][1] == '0' || Board[0][0] == Board[1][1] && Board[1][1] == Board[2][2] && Board[1][1] == '0') return 2; //平局的判斷 for (r = 0; r < ROW; r++) { for (c = 0; c < COL; c++) { if (Board[r][c] == 'x'||Board[r][c]=='0') sum++; } } if (sum == 9) return 0; //返回3代表游戲繼續(xù) return 3; }
7.游戲邏輯
游戲的邏輯是:玩家走和電腦走之后都要判斷一次輸贏,下棋我們可以寫(xiě)成一個(gè)死循環(huán)while(1),只有當(dāng)游戲有結(jié)果的時(shí)候(輸贏平局)才會(huì)break跳出循環(huán),并且打印游戲結(jié)果
void game() { int ret = 0; char Board[ROW][COL] = { 0 }; initBoard(Board, ROW, COL); showBoard(Board,ROW,COL); while (1) { PlayerMove(Board, ROW, COL); PcMove(Board, ROW, COL); ret = win(Board, ROW, COL); if (ret != 3) break; } if (ret == 1) { system("cls"); printf("恭喜你獲勝!\n"); showBoard(Board, ROW, COL); } else if (ret == 2) { system("cls"); printf("電腦都打不過(guò)?\n"); showBoard(Board, ROW, COL); } }
總結(jié):
1.理順游戲的邏輯
比如每一次玩家走和電腦走之后都要判斷一次輸贏平局
比如游戲菜單的do…while和switch循環(huán)的作用
2.游戲函數(shù)實(shí)現(xiàn)中的陷阱
不能忽略比如說(shuō)如果一個(gè)坐標(biāo)已經(jīng)被占用了需要重新輸入坐標(biāo)的情況
或者是輸贏函數(shù)中三種不同輸贏條件的判斷問(wèn)題
總體來(lái)說(shuō)游戲沒(méi)有太大的難點(diǎn),關(guān)鍵的邏輯方面弄懂了就能寫(xiě)出來(lái),但是不能粗心,很容易錯(cuò)過(guò)一些容易被錯(cuò)過(guò)的點(diǎn)。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- 基于C語(yǔ)言實(shí)現(xiàn)井字棋游戲
- C語(yǔ)言代碼實(shí)現(xiàn)井字棋游戲
- 利用C語(yǔ)言實(shí)現(xiàn)三子棋(井字棋)小游戲
- C語(yǔ)言實(shí)現(xiàn)三子棋(井字棋)算法
- C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單的井字棋游戲
- C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單井字棋游戲
- C語(yǔ)言實(shí)現(xiàn)井字棋(三子棋)
- C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)易井字棋游戲
- C語(yǔ)言實(shí)現(xiàn)井字棋游戲
- C語(yǔ)言實(shí)現(xiàn)井字棋游戲(人機(jī)對(duì)弈)
相關(guān)文章
C語(yǔ)言函數(shù)棧幀的創(chuàng)建和銷(xiāo)毀詳解
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言函數(shù)棧幀的創(chuàng)建和銷(xiāo)毀,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助2022-02-02Qt 實(shí)現(xiàn)畫(huà)線筆鋒效果詳細(xì)原理及示例代碼
這篇文章主要介紹了Qt 實(shí)現(xiàn)畫(huà)線筆鋒效果詳細(xì)原理及示例代碼。文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04用C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單的三子棋
這篇文章主要為大家詳細(xì)介紹了用C語(yǔ)言實(shí)現(xiàn)三子棋,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06C語(yǔ)言內(nèi)存泄漏常見(jiàn)情況及解決方案詳解
這篇文章主要為大家介紹了C語(yǔ)言內(nèi)存泄漏常見(jiàn)情況及解決方案詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08一文詳解matlab實(shí)現(xiàn)形態(tài)學(xué)圖像處理
這篇文章主要為大家介紹了matlab實(shí)現(xiàn)形態(tài)學(xué)圖像處理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03使用代碼驗(yàn)證linux子進(jìn)程與父進(jìn)程的關(guān)系
Linux下父進(jìn)程可以使用fork 函數(shù)創(chuàng)建子進(jìn)程,但是當(dāng)父進(jìn)程先退出后,子進(jìn)程會(huì)不會(huì)也退出呢?通過(guò)下面這個(gè)小實(shí)驗(yàn),我們能夠很好的看出來(lái)2014-02-02一文詳解C++子類(lèi)函數(shù)為什么不能重載父類(lèi)函數(shù)
這篇文章主要介紹了一文詳解C++子類(lèi)函數(shù)為什么不能重載父類(lèi)函數(shù),文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容戒殺,具有一定的參考價(jià)值,需要的朋友可以參考一下2022-09-09C++ 流插入和流提取運(yùn)算符的重載的實(shí)現(xiàn)
這篇文章主要介紹了C++ 流插入和流提取運(yùn)算符的重載的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12