C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單的控制臺(tái)三子棋游戲
用C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單的控制臺(tái)三子棋游戲
首先,確定一局游戲的基本流程:
1、創(chuàng)建棋盤(pán)并初始化。(將棋盤(pán)看作一個(gè)二維數(shù)組)
2、打印顯示出棋盤(pán)。
3、玩家落子(玩家通過(guò)輸入行列坐標(biāo)的方式來(lái)落子)。
4、判定勝負(fù)關(guān)系。(如果玩家勝出,則退出游戲。)
5、電腦落子(隨機(jī)位置落子) 。
6、判定勝負(fù)關(guān)系(如果電腦勝出,退出游戲。否則,回到步驟 2 繼續(xù)執(zhí)行。)
第一步,此處通過(guò)構(gòu)造menu()函數(shù)搭建一個(gè)簡(jiǎn)單的交互菜單和玩家交互,用來(lái)判斷是否開(kāi)始進(jìn)行一局游戲。
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> int menu() { printf("====================\n"); printf("1.開(kāi)始游戲\n"); printf("0.結(jié)束游戲\n"); printf("====================\n"); printf(" 請(qǐng)輸入您的選擇: "); int choice = 0; scanf("%d", &choice); return choice; } int main() { while (1) { int choice = menu(); if (choice == 1) { //game();//此處調(diào)用了一個(gè)game函數(shù)。 } else if (choice == 0) { printf("goodbye!\n"); break; } } system("pause"); return 0; }
第二步,對(duì)第一步中調(diào)用的game()函數(shù)進(jìn)行構(gòu)造。game()函數(shù)為核心功能函數(shù),其主要任務(wù)是完成基本流程。
1.構(gòu)建初始化init()函數(shù)。初始化一個(gè)3*3的二維數(shù)組,將它當(dāng)做棋盤(pán),并將數(shù)組元素全部初始化為0。
void init(char chessBoard[MAX_ROW][MAX_COL]) { // 把數(shù)組中的每個(gè)元素都設(shè)=初始化為“空格”。 for (int row = 0; row < MAX_ROW; row++) { for (int col = 0; col < MAX_COL; col++) { chessBoard[row][col] = ' '; } } }
2.構(gòu)建棋盤(pán)打印printChessBoard()函數(shù)。運(yùn)用for循環(huán)打印出3*3的棋盤(pán)。
void printChessBoard(char chessBoard[MAX_ROW][MAX_COL]) { //把棋盤(pán)打印出來(lái)。 printf("+---+---+---+\n"); for (int row = 0; row < MAX_ROW; row++) { printf("| %c | %c | %c |\n", chessBoard[row][0], chessBoard[row][1], chessBoard[row][2]); printf("+---+---+---+\n"); } }
3.構(gòu)建玩家落子playerMove()函數(shù),玩家通過(guò)輸入行列坐標(biāo)的方式來(lái)落子。此過(guò)程中需要判斷:1.玩家輸入的行列坐標(biāo)是否在棋盤(pán)的合理位置。2.玩家輸入的行列坐標(biāo)位置是否已經(jīng)有棋子。
void playerMove(char chessBoard[MAX_ROW][MAX_COL]) { // 讓玩家落子. 通過(guò)控制臺(tái)輸入行列坐標(biāo)的方式來(lái)實(shí)現(xiàn)。 while (1) { printf(" 請(qǐng)玩家輸入坐標(biāo)(row col): "); int row = 0; int col = 0; scanf("%d %d", &row, &col); // 校驗(yàn)玩家輸入的坐標(biāo)是否合法(是否在棋盤(pán)合理范圍內(nèi))。 if (row < 0 || row >= MAX_ROW || col < 0 || col >= MAX_COL) { // 若出現(xiàn)非法情況,此時(shí)應(yīng)該讓玩家重新輸入。 printf("您的坐標(biāo)不在合法范圍[0, 2]內(nèi) \n"); continue; } // 校驗(yàn)玩家落子位置是否已經(jīng)有子了。 if (chessBoard[row][col] != ' ') { printf("您的坐標(biāo)位置已經(jīng)有子了!\n"); continue; } // 真正落子。用“X”表示玩家落子。 chessBoard[row][col] = 'x'; break; } }
4.構(gòu)建一個(gè)computerMove()函數(shù)來(lái)控制電腦落子。通過(guò)電腦產(chǎn)生一系列隨機(jī)數(shù)來(lái)控制棋子落在棋盤(pán)坐標(biāo)范圍內(nèi)。
void computerMove(char chessBoard[MAX_ROW][MAX_COL]) { // 電腦落子,讓電腦隨機(jī)產(chǎn)生一組行列坐標(biāo)。 while (1) { int row = rand() % MAX_ROW; int col = rand() % MAX_COL; if (chessBoard[row][col] != ' ') { // 需要保證隨機(jī)數(shù)不能是已經(jīng)有棋子的位置。 continue; } chessBoard[row][col] = 'o'; break; } }
在該函數(shù)模塊中,電腦落子隨機(jī)位置的生成通過(guò)rand()函數(shù)控制,需要注意的是,我們需要通過(guò)設(shè)置隨機(jī)種子來(lái)避免“偽隨機(jī)”的出現(xiàn)。
srand((unsigned int)time(0));//以當(dāng)前時(shí)間戳作為隨機(jī)種子。
5.構(gòu)建isWin()函數(shù)判斷是否勝利。此處人為約定該函數(shù)的返回結(jié)果的含義: ‘x' 表示玩家獲勝?!畂' 表示電腦獲勝。 ' ' 表示勝負(fù)未分。 ‘q' 表示和棋。
char isWin(char chessBoard[MAX_ROW][MAX_COL]) { // 判定所有的行。 for (int row = 0; row < MAX_ROW; row++) { if (chessBoard[row][0] != ' ' && chessBoard[row][0] == chessBoard[row][1] && chessBoard[row][0] == chessBoard[row][2]) { return chessBoard[row][0]; } } // 判定所有的列。 for (int col = 0; col < MAX_COL; col++) { if (chessBoard[0][col] != ' ' && chessBoard[0][col] == chessBoard[1][col] && chessBoard[0][col] == chessBoard[2][col]) { return chessBoard[0][col]; } } // 判定兩個(gè)對(duì)角線。 if (chessBoard[0][0] != ' ' && chessBoard[0][0] == chessBoard[1][1] && chessBoard[0][0] == chessBoard[2][2]) { return chessBoard[0][0]; } if (chessBoard[2][0] != ' ' && chessBoard[2][0] == chessBoard[1][1] && chessBoard[2][0] == chessBoard[0][2]) { return chessBoard[2][0]; } // 判定是否和棋??雌灞P(pán)中是否有剩余空間。 //調(diào)用了isFull函數(shù)。 if (isFull(chessBoard)) { return 'q'; } return ' '; }
6.構(gòu)造isFull()函數(shù)用來(lái)判斷棋盤(pán)中是否有剩余空間供玩家落子,以便判斷是否是和棋。
int isFull(char chessBoard[MAX_ROW][MAX_COL]) { // 找”空格“. 如果找不到, 說(shuō)明棋盤(pán)滿了。 for (int row = 0; row < MAX_ROW; row++) { for (int col = 0; col < MAX_COL; col++) { if (chessBoard[row][col] == ' ') { // 如果找到“空格”說(shuō)明棋盤(pán)沒(méi)滿。 return 0; } } } return 1; }
最后,根據(jù)組合調(diào)用上面的幾個(gè)功能函數(shù),我們可以獲得最終的game()函數(shù)的整體架構(gòu)。
void game() { // 1. 創(chuàng)建棋盤(pán)并初始化 char chessBoard[MAX_ROW][MAX_COL] = { 0 }; init(chessBoard);//調(diào)用初始化函數(shù) char winner = ' '; while (1) { // 2. 打印棋盤(pán) printChessBoard(chessBoard); // 3. 玩家落子(玩家輸入行列坐標(biāo)的方式來(lái)落子) playerMove(chessBoard); // 4. 判定勝負(fù)關(guān)系 winner = isWin(chessBoard); if (winner != ' ') { break; } // 5. 電腦落子(隨機(jī)位置落子) computerMove(chessBoard); // 6. 判定勝負(fù)關(guān)系 winner = isWin(chessBoard); if (winner != ' ') { break; } } printChessBoard(chessBoard); if (winner == 'x') { printf("恭喜您, 您贏了!\n"); } else if (winner == 'o') { printf("很遺憾, 您輸了!再接再厲!\n"); } else { printf("您棋逢對(duì)手,這一局是平局!\n"); } }
運(yùn)行截圖如下:
勝利啦!
失敗了!
此處有棋子!
更多有趣的經(jīng)典小游戲?qū)崿F(xiàn)專題,分享給大家:
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單的三子棋
- C語(yǔ)言實(shí)現(xiàn)三子棋小游戲詳解
- C語(yǔ)言代碼實(shí)現(xiàn)三子棋游戲
- C語(yǔ)言實(shí)現(xiàn)三子棋游戲(初級(jí)版)
- C語(yǔ)言實(shí)現(xiàn)簡(jiǎ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)三子棋小游戲
- C語(yǔ)言三子棋小游戲的實(shí)現(xiàn)代碼
相關(guān)文章
C++多線程實(shí)現(xiàn)TCP服務(wù)器端同時(shí)和多個(gè)客戶端通信
通訊建立后首先由服務(wù)器端發(fā)送消息,客戶端接收消息;接著客戶端發(fā)送消息,服務(wù)器端接收消息,實(shí)現(xiàn)交互發(fā)送消息。本文主要介紹了C++多線程實(shí)現(xiàn)TCP服務(wù)器端同時(shí)和多個(gè)客戶端通信,感興趣的可以了解一下2021-05-05C++實(shí)現(xiàn)bmp格式圖像讀寫(xiě)
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)bmp格式圖像讀寫(xiě),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10C++中關(guān)于Crt的內(nèi)存泄漏檢測(cè)的分析介紹
本篇文章介紹了,在C++中關(guān)于Crt的內(nèi)存泄漏檢測(cè)的分析說(shuō)明。需要的朋友參考下2013-04-04C語(yǔ)言實(shí)現(xiàn)bmp圖像對(duì)比度擴(kuò)展
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)bmp圖像對(duì)比度擴(kuò)展,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10C語(yǔ)言中獲取和改變目錄的相關(guān)函數(shù)總結(jié)
這篇文章主要介紹了C語(yǔ)言中獲取和改變目錄的相關(guān)函數(shù)總結(jié),包括getcwd()函數(shù)和chdir()函數(shù)以及chroot()函數(shù)的使用方法,需要的朋友可以參考下2015-09-09c++中#include <>與#include""的區(qū)別詳細(xì)解析
<>先去系統(tǒng)目錄中找頭文件,如果沒(méi)有在到當(dāng)前目錄下找。所以像標(biāo)準(zhǔn)的頭文件 stdio.h、stdlib.h等用這個(gè)方法2013-10-10