練手必備 | C 語言快速實現五子棋

實驗樓v發表於2018-05-18

關注「實驗樓」,每天分享一個專案教程   

教你用最簡單易懂的程式碼編寫一個控制檯下的五子棋!課程正在限免中,想學習的同學趕緊拿來練手!

正文共:2618 字 

預計閱讀時間:7 分鐘

五子棋大家一定都玩過,想不想試著用 C 語言來實現一個簡易版的五子棋呢?下面就讓我們現在開始,用最簡單易懂的程式碼來編寫一個控制檯下的五子棋,並逐步完善它,每個人都能輕鬆學會哦!

知識點

  • 遊戲的邏輯

  • 判斷結果的演算法

  • 介面的設計

實驗環境

  • vim編輯器

  • Xfce終端

  • gcc編譯器

適合人群

本課程比較簡單,沒有複雜的語法和邏輯,適合具有C基礎的使用者,一起探索和發現C語言可以做一些有趣的事情。

原始碼下載:

點選「 閱讀原文 」進入課程,即可找到全部原始碼的下載地址。

效果截圖:

( 大家看了截圖,有沒有一種想拍死我的衝動Σ( ° △ °|||)︴ )別急,看起來似乎很醜,實際上……確實很醜。不過沒關係,這次的專案課,主要是給大家介紹一個小專案的開發流程,同時幫大家複習 C 語言基礎知識,讓大家輕鬆實現一個功能比較齊全的小遊戲,後續我還會繼續開設這一系列的專案課,帶大家完善遊戲功能和介面。廢話有點多了,下面就讓我們開始吧!

二、實驗步驟

2.1 設計棋盤

注:實驗樓環境無法輸入中文,可以用O和X來代替棋子

我們首先需要一個棋盤(15 * 15),記錄棋盤中每一個位置的“情況”。那麼我們可以定義一個 chessboard[16][16] 的陣列,為什麼不是 [15][15] 呢?因為這樣我們就可以讓陣列的座標正好對應棋盤的行和列,方便後面程式碼的編寫。

#include <stdio.h>

#define N   15

//定義一個陣列併為每一個元素賦初值0
int chessboard[N + 1][N + 1] = { 0 };

2.2 main函式的編寫

開始編寫主函式之前,我們先簡單的考慮一下,一個遊戲通常的流程是怎麼樣的 (⊙o⊙?)首 先肯定是進入遊戲的一個主介面,然後點選開始按鈕進入遊戲,接著顯示遊戲畫面,判斷輸贏,遊戲結束。那麼一個五子棋遊戲的流程呢?

//用來記錄輪到玩家1還是玩家2,奇數表示輪到玩家1,偶數輪到玩家2
int whoseTurn = 0;

int main(void)
{
//自定義函式,用來初始化遊戲,也就是顯示歡迎介面並且進入遊戲顯示棋盤
initGame();

//這個迴圈就是用來讓兩個玩家輪流落子的
while (1)
{
//每次迴圈自增1,這樣就可以做到2人輪流
whoseTurn++;

//自定義函式,用來執行落子操作
playChess();
}

return 0;
}

主函式大概就是這樣了,是不是很簡單明瞭呢?附一張用gedit編輯main函式的圖:

2.3 initGame函式

在這個函式中,我們要實現的功能是

  • 顯示一個簡單的歡迎介面

  • 要求輸入Y之後顯示出棋盤

下面,我們就開始吧!

void initGame(void)
{
char c;

printf("歡迎^_^請輸入y進入遊戲:");
c = getchar();
if ('y' != c && 'Y' != c)
exit(0);

//清屏,windows下為system("cls")
system("clear");

//這裡我們又呼叫了一個自定義函式,函式的功能是列印出棋盤
printChessboard();
}

我們在 initGame 函式中使用了 exit 以及 system 這兩個函式,所以要在程式的最上面包含 stdlib.h 這個標頭檔案

#include <stdlib.h>

2.4 printChessboard 函式

功能:

  • 列印出行號和列號,並列印出棋盤

  • 陣列元素的值為0,列印出星號(*),表示該位置沒有人落子

  • 陣列元素的值為1,列印實心圓(X,玩家1的棋子)

  • 陣列元素的值為2,列印空心圓(O,玩家2的棋子)

void printChessboard(void)
{
int i, j;

for (i = 0; i <= N; i++)
{
for (j = 0; j <= N; j++)
{
if (0 == i) //這樣可以列印出列號
printf("%3d", j);
else if (j == 0) //列印出行號
printf("%3d", i);
else if (1 == chessboard[i][j])
//windows下●佔2列,前面只需加一個空格
printf("  X");
else if (2 == chessboard[i][j])
printf("  O");
else
printf("  *");
}
printf("\n");
}
}

2.5  playChess 函式

函式功能:

  • 要求玩家輸入準備落子的位置

  • 如果當前是玩家1落子,就將1賦值給陣列中對應位置的元素

  • 如果當前是玩家2落子,就將2賦值給陣列中對應位置的元素

  • 每次落子完畢,判斷當前玩家是否獲勝

void playChess(void)
{
int i, j, winner;

//判斷輪到玩家1還是玩家2,然後把值賦給陣列中對應的元素
if (1 == whoseTurn % 2)
{
printf("輪到玩家1,請輸入棋子的位置,格式為行號+空格+列號:");
scanf("%d %d", &i, &j);
chessboard[i][j] = 1;
}
else
{
printf("輪到玩家2,請輸入棋子的位置,格式為行號+空格+列號:");
scanf("%d %d", &i, &j);
chessboard[i][j] = 2;
}

//重新列印一次棋盤
system("clear");
printChessboard(); //再次呼叫了這個函式

/*
   *下面這段呼叫了自定義函式(judge函式)
   *用來判斷當前玩家下完這步棋後,他有沒有獲勝
   *具體怎麼判斷的,馬上就給大家解釋哦
   */
if (judge(i, j, whoseTurn))
{
if (1 == whoseTurn % 2)
printf("玩家1勝!\n");
else
printf("玩家2勝!\n");
}
}

2.6 judge函式

函式引數:

  • x:當前落子的行號

  • y:當前落子的列號

返回值:

  • 1或0。1表示當前玩家落子之後出現五子連一線,也就是當前玩家獲勝

//看了之後是不是想吐血,其實一點也不復雜,詳解在最後
int judge(int x, int y)
{
int i, j;
int t = 2 - whoseTurn % 2;
const int step[4][2]={{-1,0},{0,-1},{1,1},{1,0}};
for(int i=0;i<4;++i)
{
const int d[2]={-1,1};
int count=1;
for(int j=0;j<2;++j)
for(int k=1;k<=4;++k){
int row=x+k*d[j]*step[i][0];
int col=y+k*d[j]*step[i][1];
if( row>=1 && row<=N && col>=1 && col<=N &&
chessboard[x][y]==chessboard[row][col])
count+=1;
else
break;
}
if(count>=5)
return 1;
}
return 0;
}

judge 這個函式中,有 3 個巢狀的 for 迴圈,這 3 個迴圈的目的在於判斷是否有五子連城一條線。

五子連線,無非是在一行上,一列或者斜方向上有連續的五個子。在這裡,我們將採取一種試探的方法,即沿著水平,豎直,傾斜等方向分別尋找是否有五子連線。下面舉一個例子:

在上面的對局中,我們以(9,10)來講解判斷五子是否成線的演算法。

首先判斷(9,10)的傾斜方向是否出現五子連線,判斷方式如下:

  • 以(9,10)為起點,向左上方向依此尋找,滿足條件的座標分別是(8,9),(7,8),(6,7)。因為(5,6)不滿足條件,所以進入下一步

  • 然後在向右下方尋找,找到(10,11),僅有一個滿足條件的點。

  • 然後一共找到五個在同一直線上的點,所以玩家二取得勝利,

如果傾斜方向不滿足取勝的條件,就再判斷豎直方向,水平方向,如果均不成立,這意味著當前玩家無法取得勝利,對局將會繼續。

三、修復 BUG


到這裡,我們的五子棋遊戲就基本上完成了。不過,我們的專案課並沒有結束,這個遊戲還有兩個明顯的BUG:

  • 已經落子的地方,依然可以落子,並“吃掉”原棋子。

  • 比賽結束後,仍提示下一個人落子,此時新增一個勝利的判定和提示即可。


如何修復這兩個BUG及獲取專案的全部原始碼請點選閱讀文件~課程正在限免中歡迎大家用電腦登陸實驗樓親手把這個專案實現~


學習更多


樓+「 Python實戰 」、「 Linux運維與Devops實戰 」優惠報名中——來自騰訊、Intel、IBM等網際網路大廠的一線大牛,帶你12周內打通Python、Linux的任督二脈!

點選下面的連結瞭解詳情:

一個暑假打通Python任督二脈!12周特訓再次開啟~

11周打通 Linux 任督二脈,實驗樓技術天團帶你飛!

他在一線網際網路大廠研發PHP數年,用6周時間帶你打通“全宇宙最好的語言”

相關文章