1. 程式人生 > 程式設計 >C語言實現三子棋程式

C語言實現三子棋程式

本文例項為大家分享了C語言實現三子棋的具體程式碼,供大家參考,具體內容如下

先直接上程式碼:

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>     //2.實現三子棋遊戲。
#include<Windows.h>    //Sleep() RAND_MAX 的標頭檔案

void menu()            //列印選單
{
  printf("****************************\n");
  printf("**** 歡迎來到三子棋遊戲 ****\n");
  printf("**** 1、  進入遊戲   ****\n");
  printf("**** 0、  退出遊戲   ****\n");
  printf("****************************\n");
  printf("請輸入:->");
}

void print_chessboard(char coord[][3])  //列印棋盤函式
{    //多維陣列在傳參時,接收陣列的形參最多隻能是第一個方括號裡沒有數字(下標範圍)
     //否則就會出錯(因為此時編譯器不知道你要把傳過來的陣列的元素劃分成幾行幾列,
     //但是當除第一個方括號的其他方括號都有值時,就可以經過計算知道第一個方括號的值是多少
  int i = 0;
  int index_x = 0;
  int index_y = 0;
  for (i = 1; i <= 153; i++)
  {        
    char out_ch = ' ';
    if ((i % 51 == 20) || (i % 51 == 26) || (i % 51 == 32) )
    {
      out_ch = coord[index_x][index_y];
      index_x++;
      if (index_x < 3)
      {
        index_x = 0;
        index_y++;
      }
    }
    else if ((i % 17 == 6) || (i % 17 == 12))
    {
      out_ch = '|';
    }
    else if( (i >= 35 && i <= 51 && i != 40 && i != 46) || \
         (i >= 86 && i <= 102 && i != 91 && i != 97))
    {
      out_ch = '_';
    }
    putchar(out_ch);
    if (i % 17 == 0)         //每輸出 17 個字元換下一行輸出
    {
      printf("\n");
    }
  }
}

void winer(char coord[][3],int *flag);   //贏家判斷函式的宣告

int computer(char coord[][3])                //電腦下棋
{
  int flag = 0;
  int index_x2 = 0;
  int index_y2 = 0;
  srand((unsigned)time(NULL));
  while (1)
  {
    index_x2 = 2 * rand() / RAND_MAX;         //產生 0--2 的隨機數
    index_y2 = 2 * rand() / RAND_MAX;
    if ((coord[index_x2][index_y2] != '*') && (coord[index_x2][index_y2] != 'o'))
    {                         //判斷該位置是否已有落子
      coord[index_x2][index_y2] = 'o';
      winer(coord,&flag);
      if (flag == 1)
      {
        return 1;
      }
      return 0;
    }
  }
}

int player(char coord[][3],int index_x1,int index_y1) //玩家下棋
{
  int flag = 0;
  int ret = 0;
  if ((coord[index_x1][index_y1] == '*') || (coord[index_x1][index_y1] == 'o'))
  {                           //判斷該位置是否已有落子
    printf("此位置已有棋子,請重下!\n");
    return 0;
  }
  else
  {
    coord[index_x1][index_y1] = '*';
    winer(coord,&flag);
    if (flag == 1)
    {
      return 1;
    }
    ret = computer(coord);
    if (ret == 1)
    {
      return 1;
    }
    print_chessboard(coord);    //把列印棋盤放在是因為想在兩人都走完一次後再列印當前棋盤狀態
  }
  return 0;
}

void winer(char coord[][3],int *flag)      //判斷是否產生贏家,贏家是誰
{
  char line_ch[8][4] = { { coord[0][0],coord[1][1],coord[2][2] },{ coord[0][0],coord[0][1],coord[0][2] },\
              { coord[0][0],coord[1][0],coord[2][0] },{ coord[0][1],coord[2][1] },\
              { coord[0][2],coord[1][2],{ coord[1][0],coord[1][2] },\
              { coord[2][0],coord[2][1],{ coord[0][2],coord[2][0] } };
              //把所有能贏的情況定義成一個字串陣列
  int i = 0;
  for (i = 0; i < 8; i++)
  {
    if (strcmp(line_ch[i],"***") == 0)  //判斷此時玩家已輸入的落子能不能組成一個使玩家能贏的字串
    {
      print_chessboard(coord);     //先列印棋盤,再判斷誰勝誰負
      printf("\n恭喜您贏了!\n");
      *flag = 1;           //玩家贏,使最開始設定的贏的標誌位為1,結束此次遊戲
      return;
    }
    else if (strcmp(line_ch[i],"ooo") == 0)
    {
      print_chessboard(coord);
      printf("\n很遺憾,您輸了!\n");
      *flag = 1;
      return;
    }
    else
    {
      ;
    }
  }
}

int main()
{
  while (1)
  {
    int num = 0;      //決定開始或退出遊戲
    int x = 0;
    int y = 0;
    int i = 4;       //一次遊戲最多的內層while迴圈可迴圈的次數
    int ret = 0;      //是否結束此次遊戲的標誌位
    int is_play = 0;    //是否再次玩遊戲的標誌位
    char coordinate[3][3] = { ' ',' ',' ' };
                //為了拓展遊戲比較方便,可以把行和列定義成巨集定義
    menu();         
    scanf("%d",&num);
    if (num == 0)
    {
      printf("5秒後退出程式!\n");
      Sleep(5000);
      exit(0);
    }
    computer(coordinate);   //因為設計電腦智商低,所以遊戲開始前先讓電腦落一子
    print_chessboard(coordinate);
    while ((i))        //因為總共有九個位置可以落子,已用一個,還剩八個,每次迴圈不結束的話會用掉兩個
                  //所以最多迴圈四次
    {
      printf("請輸入 X、Y 的座標(0--2)來確定你下棋的位置:");  //也可以加一個判斷輸入是否合法
      scanf("%d %d",&x,&y);
      ret = player(coordinate,x,y);
      if (ret == 1)
      {
        break;
      }
      i--;
    } 
    printf("\n");
    printf("請選擇接下來的操作:\n");
    printf("1、 再玩一次遊戲  0、退出遊戲系統\n");
    scanf("%d",&is_play);
    if(is_play == 0)
    {
      printf("5秒後退出程式!\n");
      Sleep(5000);
      exit(0);
    }
    else
    {
      system("cls");
    }
  }
  system("pause");
  return 0;
}

C語言實現三子棋程式

C語言實現三子棋程式

程式一共設計了六個函式,一個主函式,五個自定義函式— 選單列印函式、棋盤列印函式、電腦下棋函式、玩家下棋函式、贏家判斷函式。

其中最難設計的就是棋盤列印函式和贏家判斷函式。這兩個函式需要完成的任務多,計算量大,邏輯設計麻煩。

下面來分析一下幾個函式的設計思路:

1.選單列印函式

這個函式很簡單,一看就能明白,這兒就不多說了。

2.棋盤列印函式

首先得構思一下三子棋的棋盤應該是什麼樣

C語言實現三子棋程式

簡單點,上圖就可以作為三子棋棋盤(其實就是利用 putchar() 函式和 printf() 把顯示在螢幕上的字元一個個,一行行列印上去)。設計時可把其分成四部分來看,(1) 短豎槓 ; (2) 短橫槓 ; (3) 棋子(用一個二維字元陣列來定義每一個棋子,用二維是因為方便輸入的 X 和 Y 值與陣列下標對應) ; (4) 空格(一開始列印的時候,因為還沒有落子,所以把棋子也設計成空格)。 先確定要輸入幾行幾列字元,以確定迴圈輸出的次數,還有確定每個位置該輸出的字元,這樣就可以依靠迴圈和判斷打印出棋盤了。

3 . 贏家判斷函式

在每次落子後都要先進行一次判斷,看是否已經產生贏家了。
因為會出現贏家的情況就八種———–

{ coord[0][0],
{ coord[0][0],
{ coord[2][0],coord[2][0] }

定義一個字串陣列,裡面共有八個字串,每一個字串就是上面的一個花括弧裡的內容,當某個字串的內容與 * 或 ooo 相等,那麼說明產生贏家了,否則不會產生贏家,那麼就用一個迴圈,遍歷字串數組裡的每一個字串,判斷是否會產生贏家。

4. 玩家下棋函式

玩家通過輸入 x,y 座標來確定落子的位置, x,y 對應的就是 定義的棋子二維字元陣列的下標,每次先判斷輸入的 x,y 值對應陣列下標的元素是否是 * 或 o ,是的話就說明此處已有落子,得重新輸入,不是的話就落下該棋子,接著判斷是否產生贏家,是的話就結束此次遊戲,不是的話就判斷棋盤上是否還有空位置沒落子,有的話就輪到電腦繼續落子,沒有的話就結束此次遊戲。

5. 電腦下棋函式

因為電腦是自動落子,所以得為電腦產生一個隨機的 棋子二維陣列下標值,使電腦隨機落子,這個用srand((unsigned)time(NULL)); index_x2 = 2 * rand() / RAND_MAX; index_y2= 2 * rand() / RAND_MAX;來實現把它們放在一個while 死迴圈裡,因為可能產生的兩個隨機下標那兒已經有棋子了,需要重新產生一次隨機下標,當下標值與已落棋子不衝突時,就落下該棋子,接著判斷是否產生贏家,是的話,就結束此次遊戲,不是的話就判斷棋盤上是否還有空位置沒落子,有的話就輪到玩家繼續落子,沒有的話就結束此次遊戲。

6. 主函式

在主函式裡適當呼叫以上定義的幾個函式,實現正確的邏輯功能。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。