C語(yǔ)言版三子棋小游戲
本文實(shí)例為大家分享了C語(yǔ)言版三子棋小游戲的具體代碼,供大家參考,具體內(nèi)容如下
①游戲效果
- 有一個(gè)3*3的棋盤(pán)
- 每次下棋后(電腦和玩家),棋盤(pán)會(huì)更新數(shù)據(jù)
- 會(huì)有菜單提示相關(guān)命令進(jìn)行相關(guān)操作
- 下棋方法是輸入坐標(biāo)
- 每一局游戲結(jié)束后,會(huì)詢問(wèn)是否繼續(xù).
②主函數(shù)邏輯搭建
任何一個(gè)項(xiàng)目的實(shí)現(xiàn),最重要的就是邏輯結(jié)構(gòu)搭建,而各個(gè)功能的實(shí)現(xiàn)就是采取函數(shù)(模塊化)進(jìn)行細(xì)分.
所以我們需要搭建邏輯,那么邏輯結(jié)構(gòu)是啥呢?
- 首先會(huì)跳出提示菜單,內(nèi)容為 0退出游戲,1開(kāi)始/繼續(xù)游戲,其他鍵提示錯(cuò)誤,并重新輸入
- 按0后提示 “成功退出游戲”
- 按1開(kāi)始游戲
#include <stdio.h>
int main()
{
int input = 0;
do
{
remind(); // 提示菜單
scanf("%d",&input); //開(kāi)始輸入命令
switch (input)
{
case 0:
printf("成功退出游戲\n");
break;
case 1:
playgame(); // 開(kāi)始游戲
printf("是否繼續(xù)游戲\n");
break;
default :
printf("命令錯(cuò)誤,請(qǐng)重新選擇\n");
break;
}
} while (input);
return 0;
}
③游戲模塊(playgame)邏輯搭建
前面的邏輯結(jié)構(gòu)已經(jīng)搭建,而我們需要實(shí)現(xiàn)的就是 playgame()模塊.
那么他的功能邏輯是啥呢??
- 棋盤(pán)內(nèi)容用二維數(shù)組存儲(chǔ)
- 初始化棋盤(pán)(即棋盤(pán)上還沒(méi)有下子).所以初始化是一個(gè)單獨(dú)模塊
- 對(duì)弈分為兩個(gè)模塊(電腦下子與玩家下子)
- 每一局對(duì)弈后,都要判斷電腦或玩家是否贏.(所以又是一個(gè)單獨(dú)的判斷輸贏模塊)
#define row 3
#define col 3
void playgame()
{
char board[row][col]; // 存儲(chǔ)下子內(nèi)容
int result = 0; //用來(lái)接收Iswin函數(shù)判斷的返回值
Initboard(board, row, col); //初始化棋盤(pán),即最開(kāi)始棋盤(pán)都沒(méi)有下子
Displayboard(board, row, col); //顯示棋盤(pán),即顯示棋盤(pán)目前的狀態(tài)
while (1) //開(kāi)始進(jìn)行對(duì)弈,直到一方贏或者平局結(jié)束循環(huán)
{
player(board, row, col); //玩家下子函數(shù)
if ((result = Iswin(board, row, col)) == 1) break; // Iswin函數(shù)的設(shè)定是如果玩家勝利,返回1
computer(board, row, col); //電腦下子函數(shù)
if ((result = Iswin(board, row, col)) == -1) break; // Iswin函數(shù)的設(shè)定是 如果電腦勝利,返回-1
if (!result) break; //返回0平局,如果既沒(méi)有輸贏也不是平局,則繼續(xù)對(duì)弈
}
if (result == 1) printf("恭喜您取得勝利!!!!!!!!!\n");
else if (result == -1) printf("你也太辣雞了吧,電腦都下不贏\n");
else printf("哎~~,你的技術(shù)不行啊,居然和電腦達(dá)成平手\n");
}
解釋:
可以清晰的明白playgame()函數(shù)的邏輯結(jié)構(gòu).
其中有一步驟是這樣的if (Iswin(board, row, col) >= 0),它的執(zhí)行是先調(diào)用函數(shù)(滿足我們需要判斷誰(shuí)贏的要求),再利用返回結(jié)果判斷是否結(jié)束循環(huán),一條程序就達(dá)到兩個(gè)效果,比較妙.
④分支模塊具體實(shí)現(xiàn)
0.remind函數(shù)實(shí)現(xiàn)
就是起到一個(gè)提示作用,直接打印就行.
void remind()
{
printf("+------------------------------------------+\n"
"+-------------- 0 結(jié)束游戲 --------------+\n"
"+----------- 1 開(kāi)始/繼續(xù)游戲 ------------+\n"
"+------------------------------------------+\n");
}
1.Initboard函數(shù)實(shí)現(xiàn)
既然是初始化函數(shù),說(shuō)明我們的要求就是把二維數(shù)組board初始化為全空格.
void Initboard(char(*board)[3],int Row,int Col )
{
int i = 0, j = 0;
for (i = 0; i < Row; i++)
{
for (j = 0; j < Col; j++)
{
board[i][j] = ' '; // 賦予空格
}
}
}
2.Displayboard函數(shù)實(shí)現(xiàn)
顯示棋盤(pán)內(nèi)容顯示的不止是二維數(shù)組board的內(nèi)容,還要加上邊界(如圖),所以Displayboard的要求是什么?

既要顯示邊界,也要顯示board的存儲(chǔ)內(nèi)容.
而顯示邊界我們可以分成小塊循環(huán)顯示,比如看成3個(gè)條形加上最后下邊界

每一個(gè)條形又可以看成三個(gè)小方塊加上小右邊界

void Displayboard(char(*board)[3], int Row, int Col)
{
int i = 0, j = 0;
for (i = 0; i < Row; i++)
{
printf("+---+---+---+\n"); //打印小條形的上邊界
for (j = 0; j < Col; j++)
{
printf("| %c ",board[i][j]); //打印小條形中的方塊內(nèi)容
}
printf("|\n"); //補(bǔ)上 小右邊界
}
printf("+---+---+---+\n"); //補(bǔ)上 下邊界
}
3.player函數(shù)實(shí)現(xiàn)
玩家下棋采用的是坐標(biāo)輸入方式
玩家輸入一個(gè)坐標(biāo),那么棋盤(pán)上的相應(yīng)位置就應(yīng)該更新.(相應(yīng)位置用 * 表示)
輸入坐標(biāo)時(shí)候還要檢驗(yàn)該位置是否已經(jīng)落子了.
void player(char(*board)[3], int Row, int Col)
{
printf("請(qǐng)分別輸入橫縱坐標(biāo)(輸入數(shù)據(jù)請(qǐng)用空格隔開(kāi)):\n");
scanf("%d%d", &Row, &Col);
while (1)
{
if (((1 <= Row) && (Row <= 3)) //邊界必須合格,且該地方無(wú)子
&& ((1 <= Col) && (Col <= 3))
&& (board[Row-1][Col-1] == ' '))
{
board[Row - 1][Col - 1] = '*'; //之所以Row - 1 Col - 1是考慮到玩家不一定是程序員,他不知道編程從0開(kāi)始數(shù)
break;
}
else
{
printf("請(qǐng)仔細(xì)堅(jiān)持你的坐標(biāo)位置,是否已經(jīng)落子或坐標(biāo)超界,然后重新輸入坐標(biāo).\n");
printf("請(qǐng)輸入坐標(biāo):\n");
scanf("%d%d", &Row, &Col);
}
}
printf("下子成功!\n");
Displayboard(board, row, col); // 無(wú)論是玩家還是電腦下子,都需要顯示出下子內(nèi)容
}
4.Iswin函數(shù)實(shí)現(xiàn)
玩家或者電腦下子后,需要判斷雙方有一方是否贏.
Iswin的作用就是判斷是否有一方贏.
其中返回值1代表玩家勝利,返回值0代表平局,返回值-1代表電腦贏
判斷勝利方法就是檢查每行每列以及斜線是否有一樣的,以及是否不輸不贏
int Iswin(char(*board)[3], int Row, int Col)
{
//怎么判斷一方贏?? 橫,豎,斜線只要都一樣,則可以知道一方贏(全是空格除外)
for (int i = 0; i < Row; i++) //每一行
{
if ((board[i][0] == board[i][1])
&& (board[i][1] == board[i][2])
&& (board[i][0] != ' '))
{
if (board[i][0] == '*') return 1; //如果一行都是*,說(shuō)明玩家勝利,否則電腦勝利
return -1;
}
}
for (int j = 0; j < Col; j++) //每一列
{
if ((board[0][j] == board[1][j])
&& (board[1][j] == board[2][j])
&& (board[0][j] != ' '))
{
if (board[0][j] == '*') return 1; //如果一列都是*,說(shuō)明玩家勝利,否則電腦勝利
return -1;
}
}
if (((board[0][0] == board[1][1]) && (board[1][1] == board[2][2]) && (board[1][1] != ' ')) //斜線
||((board[0][2] == board[1][1]) && (board[1][1] ==board[2][0]) && (board[1][1] != ' ')))
{
if (board[1][1] == '*') return 1;
return -1;
}
for (int i = 0; i < Row; i++)
{
for (int j = 0; j < Col; j++)
{
if (board[i][j] == ' ')
return -2; //如果前三者情況都沒(méi)有,只要目前棋盤(pán)上還剩下空余位置
//就說(shuō)明不輸不贏,需要繼續(xù)對(duì)弈.返回[-1,1]之外的值就行
}
}
return 0; //除去上面4種情況就是平局
}
5.computer函數(shù)實(shí)現(xiàn)
由于是電腦下載,我們無(wú)法操作,于是只有讓電腦隨機(jī)下載了.缺陷是電腦就有點(diǎn)智障了,哈哈.
#include <stdlib.h>
#include <time.h>
void computer(char(*board)[3], int Row, int Col)
{
srand(time(NULL));
while (1)
{
int i = rand() % 3;
int j = rand() % 3;
if (board[i][j] == ' ')
{
board[i][j] = '#';//#代表電腦下子
break;
}
}
printf("電腦已下子:\n");
Displayboard(board, row, col); //電腦下子后,顯示棋盤(pán)
}
⑤完整代碼
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define row 3
#define col 3
void remind()
{
printf("+------------------------------------------+\n"
"+-------------- 0 結(jié)束游戲 --------------+\n"
"+----------- 1 開(kāi)始/繼續(xù)游戲 ------------+\n"
"+------------------------------------------+\n");
}
void Initboard(char(*board)[3],int Row,int Col )
{
int i = 0, j = 0;
for (i = 0; i < Row; i++)
{
for (j = 0; j < Col; j++)
{
board[i][j] = ' '; // 賦予空格
}
}
}
void Displayboard(char(*board)[3], int Row, int Col)
{
int i = 0, j = 0;
for (i = 0; i < Row; i++)
{
printf("+---+---+---+\n");
for (j = 0; j < Col; j++)
{
printf("| %c ",board[i][j]);
}
printf("|\n");
}
printf("+---+---+---+\n");
}
void player(char(*board)[3], int Row, int Col)
{
printf("請(qǐng)分別輸入橫縱坐標(biāo)(輸入數(shù)據(jù)請(qǐng)用空格隔開(kāi)):\n");
scanf("%d%d", &Row, &Col);
while (1)
{
if (((1 <= Row) && (Row <= 3)) //邊界必須合格,且該地方無(wú)子
&& ((1 <= Col) && (Col <= 3))
&& (board[Row-1][Col-1] == ' '))
{
board[Row - 1][Col - 1] = '*'; //之所以Row - 1 Col - 1是考慮到玩家不一定是程序員,他不知道編程從0開(kāi)始數(shù)
break;
}
else
{
printf("請(qǐng)仔細(xì)堅(jiān)持你的坐標(biāo)位置,是否已經(jīng)落子或坐標(biāo)超界,然后重新輸入坐標(biāo).\n");
printf("請(qǐng)輸入坐標(biāo):\n");
scanf("%d%d", &Row, &Col);
}
}
printf("下子成功!\n");
Displayboard(board, row, col); // 無(wú)論是玩家還是電腦下子,都需要顯示出下子內(nèi)容
}
void computer(char(*board)[3], int Row, int Col)
{
srand(time(NULL));
while (1)
{
int i = rand() % 3;
int j = rand() % 3;
if (board[i][j] == ' ')
{
board[i][j] = '#';//#代表電腦下子
break;
}
}
printf("電腦已下子:\n");
Displayboard(board, row, col); //電腦下子后,顯示棋盤(pán)
}
int Iswin(char(*board)[3], int Row, int Col)
{
//怎么判斷一方贏?? 橫,豎,斜線只要都一樣,則可以知道一方贏(全是空格除外)
for (int i = 0; i < Row; i++) //每一行
{
if ((board[i][0] == board[i][1])
&& (board[i][1] == board[i][2])
&& (board[i][0] != ' '))
{
if (board[i][0] == '*') return 1; //如果一行都是*,說(shuō)明玩家勝利,否則電腦勝利
return -1;
}
}
for (int j = 0; j < Col; j++) //每一列
{
if ((board[0][j] == board[1][j])
&& (board[1][j] == board[2][j])
&& (board[0][j] != ' '))
{
if (board[0][j] == '*') return 1; //如果一列都是*,說(shuō)明玩家勝利,否則電腦勝利
return -1;
}
}
if (((board[0][0] == board[1][1]) && (board[1][1] == board[2][2]) && (board[1][1] != ' ')) //斜線
||((board[0][2] == board[1][1]) && (board[1][1] ==board[2][0]) && (board[1][1] != ' ')))
{
if (board[1][1] == '*') return 1;
return -1;
}
for (int i = 0; i < Row; i++)
{
for (int j = 0; j < Col; j++)
{
if (board[i][j] == ' ')
return -2; //如果前三者情況都沒(méi)有,只要目前棋盤(pán)上還剩下空余位置
//就說(shuō)明不輸不贏,需要繼續(xù)對(duì)弈.返回[-1,1]之外的值就行
}
}
return 0; //除去上面4種情況就是平局
}
void playgame()
{
char board[row][col]; // 存儲(chǔ)下子內(nèi)容
int result = 0; //用來(lái)接收Iswin函數(shù)判斷的返回值
Initboard(board, row, col); //初始化棋盤(pán),即最開(kāi)始棋盤(pán)都沒(méi)有下子
Displayboard(board, row, col); //顯示棋盤(pán),即顯示棋盤(pán)目前的狀態(tài)
while (1) //開(kāi)始進(jìn)行對(duì)弈,直到一方贏或者平局結(jié)束循環(huán)
{
player(board, row, col); //玩家下子函數(shù)
if ((result = Iswin(board, row, col)) == 1) break; // Iswin函數(shù)的設(shè)定是如果玩家勝利,返回1
computer(board, row, col); //電腦下子函數(shù)
if ((result = Iswin(board, row, col)) == -1) break; // Iswin函數(shù)的設(shè)定是 如果電腦勝利,返回-1
if (!result) break; //返回0平局,如果既沒(méi)有輸贏也不是平局,則繼續(xù)對(duì)弈
}
if (result == 1) printf("恭喜您取得勝利!!!!!!!!!\n");
else if (result == -1) printf("你也太辣雞了吧,電腦都下不贏\n");
else printf("哎~~,你的技術(shù)不行啊,居然和電腦達(dá)成平手\n");
}
#include <stdio.h>
int main()
{
int input = 0;
do
{
remind(); // 提示菜單
scanf("%d", &input); //開(kāi)始輸入命令
switch (input)
{
case 0:
printf("成功退出游戲\n");
break;
case 1:
playgame(); // 開(kāi)始游戲
printf("是否繼續(xù)游戲\n");
break;
default:
printf("命令錯(cuò)誤,請(qǐng)重新選擇\n");
break;
}
} while (input);
return 0;
}
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
使用C++一步步實(shí)現(xiàn)俄羅斯方塊后續(xù)
本文主要給大家分享的是作者在使用C++制作俄羅斯方塊小游戲的時(shí)候所需要的常用的函數(shù),有需要的小伙伴可以借鑒下,希望大家能夠喜歡。2017-12-12
基于C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單的掃雷游戲
windows自帶的游戲《掃雷》是陪伴了無(wú)數(shù)人的經(jīng)典游戲,本文將利用C語(yǔ)言實(shí)現(xiàn)這一經(jīng)典的游戲,文中的示例代碼講解詳細(xì),感興趣的可以學(xué)習(xí)一下2022-05-05
C++ std::unique_lock 用法實(shí)例詳解
std::unique_lock 是 C++11 提供的一個(gè)用于管理互斥鎖的類(lèi),它提供了更靈活的鎖管理功能,適用于各種多線程場(chǎng)景,這篇文章給大家介紹了C++ std::unique_lock 用法,感興趣的朋友跟隨小編一起看看吧2023-09-09
C++中實(shí)現(xiàn)隊(duì)列類(lèi)鏈?zhǔn)酱鎯?chǔ)與棧類(lèi)鏈?zhǔn)酱鎯?chǔ)的代碼示例
這篇文章主要介紹了C++中實(shí)現(xiàn)隊(duì)列類(lèi)鏈?zhǔn)酱鎯?chǔ)與棧類(lèi)鏈?zhǔn)酱鎯?chǔ)的代碼示例,通過(guò)注釋來(lái)說(shuō)明,直接上代碼,簡(jiǎn)單粗暴XD 需要的朋友可以參考下2016-03-03
C語(yǔ)言編程PAT乙級(jí)學(xué)習(xí)筆記示例分享
這篇文章主要為大家介紹了C語(yǔ)言編程PAT乙級(jí)學(xué)習(xí)筆記實(shí)現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05

