欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

用C語(yǔ)言實(shí)現(xiàn)三子棋游戲

 更新時(shí)間:2021年07月30日 12:02:23   作者:倉(cāng)笙  
這篇文章主要為大家詳細(xì)介紹了用C語(yǔ)言實(shí)現(xiàn)三子棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文實(shí)例為大家分享了C語(yǔ)言實(shí)現(xiàn)三子棋游戲的具體代碼,供大家參考,具體內(nèi)容如下

初始工作,通過(guò)#define 定義一個(gè)標(biāo)識(shí)符來(lái)表示一個(gè)常量(棋盤(pán)的橫縱坐標(biāo))
(因?yàn)樵诖a的編寫(xiě)中,會(huì)有多處需要用到坐標(biāo)。那么,在閱讀代碼時(shí)就可能會(huì)導(dǎo)致讀者疲于理解當(dāng)前的值到底是代表什么,即會(huì)對(duì)代碼的解讀造成困擾。所以,在該代碼中通過(guò)使用宏定義解決了這個(gè)問(wèn)題,同時(shí)也方便后續(xù)更改棋盤(pán)的大小。)

#define MAX_ROW 3
#define MAX_COL 3

游戲創(chuàng)建流程

1. 創(chuàng)建棋盤(pán)

創(chuàng)建棋盤(pán)(二維數(shù)組),并將其初始化(空白,無(wú)子狀態(tài))。

//1. 棋盤(pán)初始化
void init(char chessBoard[MAX_ROW][MAX_COL]) {
 for (int row = 0; row < MAX_ROW; row++) {
  for (int col = 0; col < MAX_COL; col++) {
   //將這個(gè)棋盤(pán)(二維數(shù)組)每個(gè)位置都初始化為空
   chessBoard[row][col] = '   ';
  }
 }
}

2. 打印棋盤(pán)

打印棋盤(pán),令玩家能夠看到此時(shí)棋盤(pán)的狀態(tài)。

//2. 打印棋盤(pán)
void printChessBoard(char chessBoard[MAX_ROW][MAX_COL]) {
 printf("+---+---+---+\n");
 for(int row = 0; row < MAX_ROW; row++) {
  printf("|");
  for (int col = 0; col < MAX_COL; col++) {
   printf(" %c |", chessBoard[row][col]);
  }
  printf("\n+---+---+---+\n");
 }
}

3. 玩家落子

玩家將通過(guò)輸入坐標(biāo)(row, col)落子。
注意:在玩家選擇坐標(biāo)后需要做合法性檢驗(yàn),即判斷玩家落子的位置是否已經(jīng)有子,如果有,則玩家需要重新輸入坐標(biāo)落子。

//3. 玩家落子
void playMove(char chessBoard[MAX_ROW][MAX_COL]) {
 while (1) {
  int row = 0, col = 0;
  printf("請(qǐng)玩家通過(guò)輸入坐標(biāo)落子:");
  scanf("%d %d", &row, &col);
      //檢驗(yàn)玩家是否輸入錯(cuò)誤
   if (row < 0 || col < 0 || row >= MAX_ROW || col >= MAX_COL) {
    printf("輸入錯(cuò)誤!請(qǐng)重新輸入");
    continue;
   }
         // 檢驗(yàn)玩家輸入的位置 是否已經(jīng)有子(判斷位置是否為空,不為空即有子)
   else if (chessBoard[row][col] != ' ') {
    printf("該位置已經(jīng)有子,請(qǐng)重新輸入");
    continue;
   }
   else {
    //沒(méi)問(wèn)題,落子,標(biāo)記為'x',并退出當(dāng)前循環(huán)
    chessBoard[row][col] = 'x';
    break;
   }
 }
}

4. 判定此時(shí)勝負(fù)情況

4.1 判斷當(dāng)前勝負(fù)情況,有四種獲勝的方式:

1)橫著3個(gè)都是一樣的字符;
2)豎著3個(gè)都是一樣的字符;
3)1,3象限對(duì)角線的3個(gè)位置都是一樣的字符;
4)2,4象限對(duì)角線的3個(gè)位置都是一樣的字符。

//4. 判定勝負(fù)情況,檢查棋盤(pán)的所有位置,是否符合勝利的4種情況
//玩家獲勝,返回x; 電腦獲勝,返回o; 和棋返回p; 
char chessWin(char chessBoard[MAX_ROW][MAX_COL]) {
 //判斷橫著的3個(gè)位置
 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];
  }
 }
 //判斷豎著的3個(gè)位置
 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];
  }
 }
 //判斷2,4象限對(duì)角線的3個(gè)位置
 if (chessBoard[0][0] != ' ' && chessBoard[0][0] == chessBoard[1][1] && chessBoard[0][0] == chessBoard[2][2]) {
  return chessBoard[0][0];
 }
 //判斷1,3象限對(duì)角線的3個(gè)位置
 if (chessBoard[2][0] != ' ' && chessBoard[2][0] == chessBoard[1][1] && chessBoard[2][0] == chessBoard[0][2]) {
  return chessBoard[2][0];
 }
 if (isFull(chessBoard)) {
  return 'p';
 }
 return ' ';
}

4.2 勝負(fù)情況判斷后有4種情況,分別是:

1)玩家獲勝,返回 ‘x' ;
2)電腦獲勝,返回 ‘o' ;
3)和棋,棋盤(pán)下滿(mǎn)了,但是沒(méi)有分出勝負(fù),返回 ‘p' ;
4)棋盤(pán)還有位置是空著的,下棋繼續(xù),返回 ‘ ' ;

我們?cè)谥骱瘮?shù)中定義一個(gè)字符變量,用來(lái)判斷程序結(jié)束返回的是什么,繼而判斷是玩家獲勝、電腦獲勝、和棋還是游戲未結(jié)束。
根據(jù)字符型變量的值得知游戲的結(jié)果(具體過(guò)程如后主函數(shù)內(nèi)容所示)。

4.3 判斷是否和棋的函數(shù)為:

//4.3 判斷是否和棋(棋盤(pán)滿(mǎn)了,但未分勝負(fù)),返回1表示棋盤(pán)滿(mǎn)了,返回0表示棋盤(pán)未滿(mǎn)
int isFull(char chessBoard[MAX_ROW][MAX_COL]) {
 for (int row = 0; row < MAX_ROW; row++) {
  for (int col = 0; col < MAX_COL; col++) {
   if (chessBoard[row][col] == ' ') {
    return 0;
   }
  }
 }
 return 1;
}

5. 電腦落子(電腦隨機(jī)落子)

通過(guò) rand() 函數(shù)實(shí)現(xiàn)電腦的隨機(jī)落子。
(取余運(yùn)算是很好的截短方法,在這里,我們通過(guò)取余運(yùn)算將橫縱坐標(biāo)的值控制在了[0,2]之間。)

//5. 電腦落子(隨機(jī))
void computerPlayMove(char chessBoard[MAX_ROW][MAX_COL]) {
 while (1) {
  //控制落子的坐標(biāo) x,y 在[0,2]之間
  int row = rand() % MAX_ROW;
  int col = rand() % MAX_COL;
  //判斷電腦想落子的位置是否為空(即是否已經(jīng)有子),如若已經(jīng)有子,繼續(xù)循環(huán)
  if (chessBoard[row][col] != ' ') {
   continue;
  }
  //如果電腦想落子的位置為空,則將 ‘o' 賦給該位置,并結(jié)束循環(huán)
  chessBoard[row][col] = 'o';
  break;
 }
}

6. 判定此時(shí)勝負(fù)情況

同過(guò)程4。

7. 主函數(shù)

注意,我們將 字符型二維數(shù)組棋盤(pán) 寫(xiě)在了主函數(shù)中,而非整個(gè)程序的開(kāi)頭。
原因是:如果寫(xiě)在開(kāi)頭,那么這個(gè)變量就是全局變量了。
全局變量的生命周期是整個(gè)程序,會(huì)占用更多的內(nèi)存,而且如果在程序中間已經(jīng)使用完畢這個(gè)變量,也是不能釋放內(nèi)存的。
此外,全局變量的作用域是整個(gè)工程。如果在哪里將它改動(dòng)后,整體都會(huì)受到影響,在查問(wèn)題出在哪里的時(shí)候會(huì)很麻煩。
所以,本著盡量不使用全局變量的原則,將這個(gè)變量寫(xiě)在了主函數(shù)中。當(dāng)其他函數(shù)需要這個(gè)參數(shù)的時(shí)候,再進(jìn)行傳參使用即可。

int main() {
 char chessBoard[MAX_ROW][MAX_COL];
 char winner = ' ';
 //1. 棋盤(pán)初始化
 init(chessBoard);

 while (1) {
  //2. 打印棋盤(pán),令玩家觀察此時(shí)棋盤(pán)的狀態(tài)
  printChessBoard(chessBoard);
  //3. 玩家落子
  playMove(chessBoard);
  //4. 判斷勝負(fù)情況
  winner = chessWin(chessBoard);
  if (winner != ' ') {
   //已經(jīng)有非空返回值,游戲結(jié)束
   break;
  }
  //5. 電腦落子
  computerPlayMove(chessBoard);
  //4. 判斷勝負(fù)情況
  winner = chessWin(chessBoard);
  if (winner != ' ') {
   //已經(jīng)有非空返回值,游戲結(jié)束
   break;
  }
 }
 if (winner == 'x') {
  printChessBoard(chessBoard);
  printf("恭喜玩家獲勝!");
 }
 else if (winner == 'o') {
  printChessBoard(chessBoard);
  printf("惜敗,電腦獲勝了哦~");
 }
 else {
  printChessBoard(chessBoard);
  printf("哎呀,你和電腦打成平手了呢~");
 }

 system("pause");
 return 0;
}

以上就是我在寫(xiě)三子棋游戲的思路、代碼以及一些需要注意的點(diǎn)。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 聊一聊OpenCV相機(jī)標(biāo)定

    聊一聊OpenCV相機(jī)標(biāo)定

    這篇文章主要為大家詳細(xì)介紹了OpenCV相機(jī)標(biāo)定的相關(guān)資料,即獲得相機(jī)參數(shù)的過(guò)程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • C++面試題之結(jié)構(gòu)體內(nèi)存對(duì)齊計(jì)算問(wèn)題總結(jié)大全

    C++面試題之結(jié)構(gòu)體內(nèi)存對(duì)齊計(jì)算問(wèn)題總結(jié)大全

    這篇文章主要給大家總結(jié)了關(guān)于C++面試題中結(jié)構(gòu)體內(nèi)存對(duì)齊計(jì)算問(wèn)題的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),通過(guò)這些介紹的內(nèi)容對(duì)大家在面試C++工作的時(shí)候,會(huì)有一定的參考幫助,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-08-08
  • C/C++語(yǔ)言中全局變量重復(fù)定義問(wèn)題的解決方法

    C/C++語(yǔ)言中全局變量重復(fù)定義問(wèn)題的解決方法

    這篇文章主要給大家介紹了關(guān)于C/C++語(yǔ)言中全局變量重復(fù)定義問(wèn)題的解決方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-01-01
  • OpenCV3實(shí)現(xiàn)車(chē)牌識(shí)別(C++版)

    OpenCV3實(shí)現(xiàn)車(chē)牌識(shí)別(C++版)

    這篇文章主要為大家詳細(xì)介紹了OpenCV3實(shí)現(xiàn)車(chē)牌識(shí)別功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • C語(yǔ)言枚舉(enum)和聯(lián)合(union)實(shí)例分享

    C語(yǔ)言枚舉(enum)和聯(lián)合(union)實(shí)例分享

    在本篇文章里小編給大家整理了關(guān)于C語(yǔ)言枚舉(enum)和聯(lián)合(union)實(shí)例內(nèi)容,需要的朋友們可以學(xué)習(xí)下。
    2020-03-03
  • 老生常談C++中實(shí)參形參的傳遞問(wèn)題

    老生常談C++中實(shí)參形參的傳遞問(wèn)題

    下面小編就為大家?guī)?lái)一篇老生常談C++中實(shí)參形參的傳遞問(wèn)題。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-03-03
  • linux C 打印錯(cuò)誤信息和標(biāo)準(zhǔn)輸入輸出詳細(xì)介紹

    linux C 打印錯(cuò)誤信息和標(biāo)準(zhǔn)輸入輸出詳細(xì)介紹

    這篇文章主要介紹了linux C 打印錯(cuò)誤信息和標(biāo)準(zhǔn)輸入輸出詳細(xì)介紹的相關(guān)資料,需要的朋友可以參考下
    2016-12-12
  • c語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之并查集 總結(jié)

    c語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之并查集 總結(jié)

    一種用于管理分組的數(shù)據(jù)結(jié)構(gòu)。它具備兩個(gè)操作:(1)查詢(xún)?cè)豠和元素b是否為同一組 (2) 將元素a和b合并為同一組,需要的朋友可以參考下
    2018-08-08
  • C語(yǔ)言實(shí)現(xiàn)求解素?cái)?shù)的N種方法總結(jié)

    C語(yǔ)言實(shí)現(xiàn)求解素?cái)?shù)的N種方法總結(jié)

    哈嘍各位友友們,今天又學(xué)到了很多有趣的知識(shí),現(xiàn)在迫不及待的想和大家分享一下!本文將手把手帶領(lǐng)大家探討利用試除法、篩選法求解素?cái)?shù)的n層境界!都是精華內(nèi)容,可不要錯(cuò)過(guò)喲
    2023-01-01
  • C++實(shí)現(xiàn)LeetCode(86.劃分鏈表)

    C++實(shí)現(xiàn)LeetCode(86.劃分鏈表)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(86.劃分鏈表),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07

最新評(píng)論