C語言實(shí)現(xiàn)井字棋小游戲
C語言實(shí)現(xiàn)簡單的“井字棋游戲”,供大家參考,具體內(nèi)容如下
總體構(gòu)造:
1.游戲菜單的邏輯實(shí)現(xiàn)
2.游戲本體的代碼實(shí)現(xiàn)
part 1:游戲菜單的整體邏輯
①簡單的通過一個(gè)輸入0和1的switch函數(shù)實(shí)現(xiàn)判斷是玩游戲還是退出游戲的邏輯
輸入1則進(jìn)入游戲,而且打完game()即游戲本體之后因?yàn)閐o…while函數(shù)輸入1會(huì)繼續(xù)循環(huán)詢問是否玩游戲
輸入0則break退出游戲,且退出do…while循環(huán),程序結(jié)束。
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do
{
menu();
printf("請輸入>--");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("游戲退出...exit...\n");
break;
default:
printf("輸入錯(cuò)誤,請重新輸入\n");
}
} while (input);
return 0;
}
②簡單粗暴的菜單打印函數(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]作為棋盤,
char Board[ROW][COL] = { 0 };
定義全局變量ROW和COL也就是行數(shù)和列數(shù)為3
#define ROW 3 #define COL 3
2.棋盤創(chuàng)建好了之后對這個(gè)棋盤初始化(構(gòu)建函數(shù))
給這個(gè)函數(shù)傳參需要傳行與列和二維數(shù)組(棋盤)
initBoard(Board, ROW, COL);
用兩層for循環(huá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è)棋盤打印出來,定義一個(gè)打印函數(shù)
showBoard(Board,ROW,COL);
用簡單的豎線和空格打印一個(gè)棋盤
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)是否在棋盤內(nèi)
2:玩家輸入的坐標(biāo)是不是已經(jīng)被下過子了
用簡單的for循環(huán)遍歷和if語句判斷就可以完成
并且每一次需要重新輸入的情況中都打印一次棋盤作為參考
void PlayerMove(char Board[ROW][COL], int row, int col)
{
while (1)
{
int r = 0;
int c = 0;
char input = '0';
printf("請輸入您要下子的坐標(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),請重新輸入!\n");
showBoard(Board, ROW, COL);
}
else if (Board[r - 1][c - 1] == 'x' || Board[r - 1][c - 1] == '0')
{
system("cls");
printf("這里已經(jī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ù)簡單的為電腦下棋 ( scand()和rand() )
也要判斷電腦的坐標(biāo)是否已經(jīng)被下過了
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分別對應(yīng)我們贏和電腦贏以及平局
ret = win(Board, ROW, COL);
井字棋獲勝的規(guī)則是三行三豎或者對角線相同則獲勝,依次判斷即可
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.游戲邏輯
游戲的邏輯是:玩家走和電腦走之后都要判斷一次輸贏,下棋我們可以寫成一個(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("電腦都打不過?\n");
showBoard(Board, ROW, COL);
}
}
總結(jié):
1.理順游戲的邏輯
比如每一次玩家走和電腦走之后都要判斷一次輸贏平局
比如游戲菜單的do…while和switch循環(huán)的作用
2.游戲函數(shù)實(shí)現(xiàn)中的陷阱
不能忽略比如說如果一個(gè)坐標(biāo)已經(jīng)被占用了需要重新輸入坐標(biāo)的情況
或者是輸贏函數(shù)中三種不同輸贏條件的判斷問題
總體來說游戲沒有太大的難點(diǎn),關(guān)鍵的邏輯方面弄懂了就能寫出來,但是不能粗心,很容易錯(cuò)過一些容易被錯(cuò)過的點(diǎn)。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Qt 實(shí)現(xiàn)畫線筆鋒效果詳細(xì)原理及示例代碼
這篇文章主要介紹了Qt 實(shí)現(xiàn)畫線筆鋒效果詳細(xì)原理及示例代碼。文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04
一文詳解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ì)也退出呢?通過下面這個(gè)小實(shí)驗(yàn),我們能夠很好的看出來2014-02-02
一文詳解C++子類函數(shù)為什么不能重載父類函數(shù)
這篇文章主要介紹了一文詳解C++子類函數(shù)為什么不能重載父類函數(shù),文章圍繞主題展開詳細(xì)的內(nèi)容戒殺,具有一定的參考價(jià)值,需要的朋友可以參考一下2022-09-09
C++ 流插入和流提取運(yùn)算符的重載的實(shí)現(xiàn)
這篇文章主要介紹了C++ 流插入和流提取運(yùn)算符的重載的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12

