練手必備 | C 語言快速實現五子棋
關注「實驗樓」,每天分享一個專案教程
教你用最簡單易懂的程式碼編寫一個控制檯下的五子棋!課程正在限免中,想學習的同學趕緊拿來練手!
正文共: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的任督二脈!
點選下面的連結瞭解詳情:
相關文章
- C語言實現小遊戲:五子棋C語言遊戲
- C語言練手專案--C 語言製作簡單計算器C語言
- 三種語言實現快速排序(C++/Python/Java)排序C++PythonJava
- C語言五子棋小遊戲C語言遊戲
- C語言 備份C語言
- 《明解C語言》練習題4-2的實現C語言
- 掃雷--C語言實現C語言
- c語言實現階乘C語言
- C 語言實現整數快速模除(modulo)和地板除(floordiv)
- C語言__LINE__實現原理C語言
- C語言實現檔案加密C語言加密
- c語言實現this指標效果C語言指標
- 高精度加法(C語言實現)C語言
- C語言實現TCP通訊C語言TCP
- 4個Python經典專案實戰,練手必備哦Python
- C語言練習——資料加密C語言加密
- C#語言————第二章 C#語言快速熱身C#
- 排序演算法-C語言實現排序演算法C語言
- 高精度減法(C語言實現)C語言
- C語言實現推箱子游戲C語言
- C語言實現繼承多型C語言繼承多型
- C語言實現桌面貪吃蛇C語言
- 快速認識,前端必學程式語言:JavaScript前端JavaScript
- HTTP狀態碼 — 混圈子必備”語言“HTTP
- Go語言快速安裝手冊Go
- C語言訓練之杭電OJC語言
- 冬季實戰營動手實戰-上雲必備環境準備,動手實操快速搭建LAMP環境LAMP
- Object-C語言Block的實現方式ObjectC語言BloC
- C 語言實現泛型 swap 函式泛型函式
- PID演算法的C語言實現演算法C語言
- C語言如何實現繼承及容器C語言繼承
- C語言實現矩陣螺旋輸出C語言矩陣
- C++語言菜鳥快速入門C++
- c語言快速排序(庫函式使用)C語言排序函式
- 【C語言】氣泡排序與快速排序C語言排序
- c語言實現貓吃老鼠的問題C語言
- C語言回撥日誌庫的實現C語言
- 探秘掃雷遊戲的C語言實現遊戲C語言