1. 程式人生 > >用C語言編寫簡單遊戲——三子棋

用C語言編寫簡單遊戲——三子棋

   

  先簡單介紹一下三子棋的規則,方便我們接下來的程式設計和理解。規則如下:

  在九宮格棋盤上,只要將自己的三個棋子走成一條線(橫、豎、對角線),對方就算輸了。

  規則很簡單,但是我們應該從哪裡入手完成這個三子棋程式呢?   首先,我們的遊戲程式應該先有個選單頁面,這個選單頁面用來讓使用者操作選擇玩遊戲,或是退出。

介面可以很簡單,只需要幾條 printf 語句即可:

這就是一個簡單的操作介面,效果如下:

既然選單中有選項,我們就必須要設計一個變數用來接收使用者的選擇。

而且遊戲程式本身應該允許使用者反覆進行玩耍,所以在主函式中,我們需要用一個迴圈來完成這個功能。

do-while迴圈在呼叫時會先執行迴圈體,而後在進行判斷,所以這裡我們選擇使用do-while迴圈;

由於使用者選擇選項1時我們需要為使用者啟動遊戲程式,所以這裡我們使用一個switch語句來接受使用者的選擇。

選擇0時退出程式,所以我們只需要跳出迴圈,即可退出。

而輸入0、1之外的值時,我們應該向使用者報輸入錯誤,所以在default中輸出一條報錯資訊。


接下來,就是三子棋遊戲本身了:

在game.h標頭檔案中放入函式名,在game.c原始檔中放入實現函式。 由於長和寬我們要經常用到,為了後續修改方便,我們採用巨集定義方式:

接下來在game()函式中建立陣列:

並將這個陣列進行初始化,因為這個陣列在後續需要輸出展示在使用者面前,所以我們將值初始化為空格“ ”。

初始化用函式進行完成:

接下來,我們應該輸出這個陣列棋盤,來檢查一下是否初始化完成,

但我們沒有展示棋盤的函式,所以我們需要完成這個顯示棋盤函式:

這裡需要利用迴圈來輸出我們棋盤的格式,格式不統一,可以根據自己的喜好進行修改。

下面展示一下我這個程式碼所輸出的棋盤:

上面已經看出我的棋盤初始化已經完成,所以接下來我們需要考慮如何讓電腦或使用者進行下棋操作了。

電腦走需要讓電腦產生隨機座標,然後在陣列的這個座標位置放入一個“X”作為電腦的棋子。

所以程式碼如下:

電腦下完棋後,需要輪到我們的使用者進行下棋操作,這個函式和電腦下棋大同小異,

但是要注意人的習慣不會輸入(0,0)這個座標,而是輸入(1,1)。

所以這裡我們要給傳過去的引數-1。

解決這個問題後的程式碼如下:

在雙方走完後,我們需要判斷是否勝利,也就是判斷之前我們提到的規則,

這時我們需要編寫一個checkwin()函式來檢測並返回一個值表示誰獲勝。

程式碼如下:

由於可能出現棋盤下滿,卻沒人獲勝的情況,
所以我們需要在其中判斷一下平局的情況: 完整程式碼如下:

標頭檔案game.h: #define _CRT_SECURE_NO_WARNINGS 1 
#ifndef __GAME_H__
#define __GAME_H__
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <string.h>
#define ROW 3
#define COL 3
void game ();
void InitBoard(char arr[ROW][COL],int row,int col);
void DisplayBoard(char arr[ROW][COL],int row,int col);
void PlayerChess (char arr[ROW][COL],int row,int col);
void ComputerChess (char arr[ROW][COL],int row,int col);
char CheckWin (char arr[ROW][COL],int row,int col);
int CheckFull(char arr[ROW][COL],int row,int col);
#endif//__GAME_H__ 原始檔game.c:

#define _CRT_SECURE_NO_WARNINGS 1 
#include "game.h"
void InitBoard (char arr[ROW][COL],int row,int col)
{
 memset(arr,' ',row*col*sizeof(arr[0][0]));
}
void DisplayBoard(char arr[ROW][COL],int row,int col)
{
 int i = 0;
 printf (" -----------\n");
 for (i = 0;i < ROW;i++)
 {
  printf ("| %c | %c | %c |\n",arr[i][0],arr[i][1],arr[i][2]);
  if (i < 2)
  {
   printf (" ---|---|---");
   
  }
  else
   printf (" -----------");
  printf ("\n");
 }
}
void PlayerChess (char arr[ROW][COL],int row,int col)
 { 
 int x = 0;
    int y = 0;
    while (1)
 {
  printf ("玩家走:\n");
     scanf_s ("%d %d",&x,&y);
     x--;
     y--;
     if (arr[x][y] == ' ')
     {
     arr[x][y] = 'X';
     break;
     }
  else
  {
   printf ("輸入非法,請重輸\n");
   continue;
  }
 }
}
void ComputerChess (char arr[ROW][COL],int row,int col)
{
 while (1)
 {
  int x = 0;
  int y = 0;
  srand((unsigned)time(NULL));
  x = rand() % 3;
  y = rand() % 3;
  if (arr[x][y] == ' ')
  {
   arr[x][y] = '0';
         break;
  }
 }
}
static int CheckFull(char arr[ROW][COL],int row,int col)
{
 int i, j;
    for (i = 0; i < row; i++)
    {
        for (j = 0; j < col; j++)
        {
            if (arr[i][j] == ' ')
                return 0;
        }
    }
    return 1; } char CheckWin (char arr[ROW][COL],int row,int col)
{
 int i = 0;
 int ret = 0;
 for (i = 0;i < row;i++)
 {
  if ((arr[i][0] == arr[i][1]) && (arr[i][1] == arr[i][2])&& (arr[i][0] != ' '))
  {
   return arr[i][0];
  }
 }

 for (i = 0;i < COL;i++)
 {
  if ((arr[0][i] == arr[1][i]) && (arr[1][i] == arr[2][i]) && (arr[0][i]))
  {
   return (arr[0][i]);
  }
 }
 if ((arr[0][0] == arr[1][1]) && (arr[1][1] == arr[2][2]) && (arr[0][0] != ' '))
 {
  return (arr[0][0]);
 }
 if ((arr[0][2] == arr[1][1]) && (arr[1][1] == arr[2][0] && (arr[0][2] != ' ')))
 {
  return (arr[0][2]);
 }
 ret = CheckFull(arr,row,col);
 if (ret = 1)
 {
  return 'q';
 }
 return ' ';
}
原始檔test.c:

#define _CRT_SECURE_NO_WARNINGS 1 
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "game.h"
void menu()
{
 printf ("***********************\n");
 printf ("*****1.play 0.exit*****\n");
 printf ("***********************\n");
}
int main()
{
 int input = 0;
 do
 {
  menu();
  scanf("%d",&input);
  switch (input)
  {
  case 1:
   game();
   break;
  case 0:
   break;
  default:
   printf ("輸入錯誤\n");
   break;
  }  }while (input);
 getchar();
 return 0;
}
void game()
{
 int ret = 0;
 char arr[ROW][COL] ={0};
 InitBoard(arr,ROW,COL);
 DisplayBoard(arr,ROW,COL);
 srand((unsigned int)time(NULL));
 while (1)
 {
  PlayerChess(arr,ROW,COL);
  if((ret = CheckWin(arr,ROW,COL)) != ' ')
   break;
  DisplayBoard(arr,ROW,COL);
  ComputerChess(arr,ROW,COL);
  if((ret = CheckWin(arr,ROW,COL)) != ' ')
   break;
  DisplayBoard(arr,ROW,COL);
 }
 if(ret = 'X')
 {
  printf ("玩家勝\n");
 }
 else if(ret = '0')
 {
  printf ("電腦勝\n");
 }
 else if(ret = 'q')
 {
  printf ("平局\n");
 }
 DisplayBoard(arr,ROW,COL);
} 優化電腦:

只需在void ComputerChess (char arr[ROW][COL],int row,int col)中加入: while (1)
 { if (arr[1][1] == ' ')
 {
  arr[1][1] = '0';
 }
 int i = 0;
 int j = 0;
 int x = 0;
 int y = 0;
 for (i = 0;i < row;i++)
 {
  if ((arr[0][j] ==arr[1][j]) && (arr[2][j] == ' '))
  {
   arr[2][j] = '0';
  }
  else if ((arr[0][j] ==arr[2][j]) && (arr[1][j] == ' '))
  {
   arr[1][j] = '0';
  }
  else if ((arr[1][j] == arr[2][j]) && (arr[0][j] == ' '))
  {
   arr[0][j] = '0';
  }
 }
 for (j = 0;j < col;j++)
 {
  if ((arr[i][0] == arr[i][1]) && (arr[i][2] == ' '))
  {
   arr[i][2] = '0';
  }
  else if ((arr[i][0] == arr[i][2]) && (arr[i][1] == ' '))
  {
   arr[i][1] = '0';
  }
  else if((arr[i][1] == arr[i][2]) && (arr[i][0] == ' '))
  {
   arr[i][0] = '0';
  }
 }
 if ((arr[0][0] == arr[1][1]) && (arr[2][2] == ' '))
 {
  arr[2][2] = '0';
 }
 else if ((arr[0][0] == arr[2][2]) && (arr[1][1] == ' '))
 {
  arr[1][1] = '0';
 }
 else if ((arr[1][1] == arr[2][2]) && (arr[0][0] == ' '))
 {
  arr[0][0] = '0';
 }
 if ((arr[0][2] == arr[1][1]) && (arr[2][0] == ' '))
 {
  arr[2][0] = '0';
 }
 else if ((arr[0][2] == arr[2][0]) && (arr[1][1] == ' '))
 {
  arr[1][1] = '0';
 }
 else if ((arr[1][1] == arr[2][0]) && (arr[0][2] == ' '))
 {
  arr[0][2] = '0';
 }
 x = rand() % row;  y = rand() % col; 
 if (arr[x][y] == ' ')
 {
  arr[x][y] = '0';
 }
 }