C語言----小游戲三子棋-創(chuàng)新互聯(lián)

相信大家或多或少都聽說過五子棋,三子棋也是類似,即達(dá)成每行或每列中有三顆連續(xù)棋子,亦或是在對角線上有三顆連續(xù)的棋子即為勝利。今天,我們就來實(shí)現(xiàn)一下。

目前創(chuàng)新互聯(lián)建站已為1000多家的企業(yè)提供了網(wǎng)站建設(shè)、域名、虛擬主機(jī)成都網(wǎng)站托管、企業(yè)網(wǎng)站設(shè)計(jì)、安岳網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。

目錄

一、文件的準(zhǔn)備

二、功能的實(shí)現(xiàn)

1.菜單與用戶的選擇

2.游戲的函數(shù)

3.棋盤的初始化

4.打印棋盤

5.下棋->玩家下棋

6.下棋->電腦下棋

7.判斷結(jié)果

a.當(dāng)一行中三個(gè)相等時(shí)

b.當(dāng)一列中三個(gè)相等時(shí)

c.當(dāng)對角線上相等時(shí)

d.判斷平局

8.程序補(bǔ)全


一、文件的準(zhǔn)備

為了后期代碼的封裝,我們將測試代碼,函數(shù)代碼和函數(shù)的聲明分開存放到不同的文件中。如下:

test.c????????——??????? 用于存放測試游戲功能實(shí)現(xiàn)的代碼

game.c???? ——??????? 用于存放游戲相關(guān)的函數(shù)的具體內(nèi)容

game.h??? ? ——??????? 用于存放游戲中功能函數(shù)的聲明以及相關(guān)類型的定義

為了便于區(qū)分,將在后文的代碼演示處首行以注釋方式寫明所屬文件。

二、功能的實(shí)現(xiàn) ??????? 1.菜單與用戶的選擇

市面上的游戲的選項(xiàng)有很多,我們只完成最基礎(chǔ)的玩游戲和退出。

我們創(chuàng)建無返回值的menu作為菜單,由于只用來測試,寫在test.c中。

// test.c
void menu()
{
	printf("****************\n");
	printf("**** 1.play ****\n");
	printf("**** 0.exit ***\n");
	printf("****************\n");
}

為了使用戶有較好的游戲體驗(yàn),我們使用循環(huán)來判斷,只有當(dāng)用戶選擇退出游戲才會退出,選擇的不是玩游戲或者退出就提示錯(cuò)誤并重新輸入。

// test.c
int main()
{
	int input = 0;
	do
	{
		menu();
		printf("請選擇:>");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			Game();
			break;
		case 0:
			printf(*"退出游戲\n");
			break;
		default:
			printf("選擇錯(cuò)誤,請重新選擇\n");
			break;
		}
	} while (input);
	return 0;
}
2.游戲的函數(shù)

當(dāng)用戶輸入1選擇進(jìn)入游戲后,就需要進(jìn)入具體的游戲程序中,我們在play的選項(xiàng)后創(chuàng)建Game函數(shù)用來存放游戲代碼。Game的使用在上文的代碼段中已有體現(xiàn),接下來只講聲明與定義。

我們將Game函數(shù)也存放在test.c中,基礎(chǔ)代碼如下:

// test.c
void Game()
{
	char board[ROW][COL] = { 0 };

	InitBoard(board, ROW, COL);

	PrintBoard(board, ROW, COL);

	...

}

下棋,必不可少的就是棋盤。

我們創(chuàng)建一個(gè)二維數(shù)組來存放棋盤,棋盤的大小就設(shè)定為3X3,在二維數(shù)組中即為每行3個(gè)元素,共3行。

為了方便后期代碼的維護(hù),我們使用#define自定義行和列,并存放在我們編寫的game.h中,方便調(diào)用。

// game.h

#include#include#include#include#define ROW 3
#define COL3

為了方便,已經(jīng)后文需要引用的頭文件一起添加,后文有關(guān)內(nèi)容將僅做提示。

特別注意:由于自定義類型在別的文件中需要引用,也為了減少代碼內(nèi)容,另外兩個(gè).c需要引用頭文件game.h,如下:

// test.c        game.c
#include "game.h"

創(chuàng)建字符類型二維數(shù)組board作為棋盤,行和列分別使用已定義的ROW和COL,Game函數(shù)中已有體現(xiàn)。

3.棋盤的初始化

在開始下棋之前,需要先清理棋盤,程序中也是一樣,我們需要對棋盤進(jìn)行初始化,創(chuàng)建InitBoard用于實(shí)現(xiàn)初始化。

由于自此之后絕大部分函數(shù)都涉及到具體的游戲內(nèi)功能,故函數(shù)的使用均在Game函數(shù)中,有使用方式特別的會單獨(dú)指出;函數(shù)的聲明存放到頭文件game.h中;函數(shù)的具體內(nèi)容存放到game.c中,在此僅作演示,之后的聲明和定義將省略。

聲明:

// game.h
void InitBoard(char board[ROW][COL], int row, int col);

定義:

// game.c
void InitBoard(char board[ROW][COL], int row, int col)
{
	;
}

具體的內(nèi)容在之后會有體現(xiàn)。

我們將棋盤上的落棋點(diǎn),也就是二維數(shù)組中的元素初始化為空格字符,即' ',可以使用嵌套的for循環(huán)來實(shí)現(xiàn),具體如下:

// game.c
void InitBoard(char board[ROW][COL], int row, int col)
{
    int i = 0;
	    int j = 0;
	    for (i = 0; i< row; i++)
	    {
		    for (j = 0; j< col; j++)
		    {
			    board[i][j] = ' ';
		    }
	    }
}
4.打印棋盤

在下棋之前,必須要能看到棋盤的內(nèi)容,所以在初始化后就需要打印出來,方便觀察。

都初始化為空格,直接打印肯定不方便觀察,而且下棋也需要使用其他符號作為每個(gè)格子的分界,我們使用“-”和”|“作為分界,且分隔符與單元格并不是一一對應(yīng),而是只在兩個(gè)各自之間才需要分割,所以循環(huán)的條件就是行數(shù)/列數(shù) 減去1,這里類似于數(shù)組元素和下標(biāo)的關(guān)系。

代碼如下:

// contact.c

void PrintBoard(char board[ROW][COL], int row, int col)
{
	int i = 0;
	for (i = 0; i< row; i++)
	{
		int j = 0;
		for (j = 0; j< col; j++)
		{
			printf(" %c ", board[i][j]);
			if(j

打印出來的棋盤樣式如圖:

5.下棋->玩家下棋

我們創(chuàng)建PlayMove函數(shù)用作玩家下棋,并將玩家可以出的棋子定義為'*':

給出玩家下棋的提示,使用printf打印。

在二維數(shù)組中行和列的下標(biāo)均是從0開始,但是玩家并不一定知道下標(biāo)這個(gè)概念,進(jìn)而輸入為從1開始的任意數(shù)值,我們就需要判斷輸入玩家輸入的坐標(biāo)是否在現(xiàn)有的棋盤內(nèi),使用if判斷,由于有多個(gè)條件,我們使用C語言邏輯運(yùn)算符中的與&&連接判斷條件。

程序設(shè)計(jì)為人機(jī)對戰(zhàn),當(dāng)用戶輸入的坐標(biāo)是處于棋盤上的時(shí)候,我們還需要對所輸入的坐標(biāo)是否已有用戶或者電腦使用過此坐標(biāo)。若為我們初始化的' '就是沒有被使用過,就將'*'置入該坐標(biāo)中。代碼如下:

// game.c
void PlayerMove(char board[ROW][COL], int row, int col) 
{
	int x = 0;
	int y = 0;

	printf("玩家走:>\n");

	while (1)
	{
		printf("請輸入下棋的坐標(biāo):>");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x<= row && y >= 1 && y<= col)
		{
			if (board[x - 1][y - 1] == ' ')
			{
				board[x - 1][y - 1] = '*';
				break;
			}
			else
			{
				printf("坐標(biāo)已被占用, 請重新輸入\n");
			}
		}
		else
		{
			printf("坐標(biāo)非法, 請重新輸入\n");
		}
	}
}
6.下棋->電腦下棋

我們創(chuàng)建ComMove函數(shù)來表示電腦下棋,使用'#'作為電腦所下的棋子:

電腦下棋無法像玩家一樣輸入自己要下的,我們需要使用隨機(jī)數(shù)來獲取行和列。

C語言中,一般使用rand()函數(shù)來生成隨機(jī)數(shù),但隨機(jī)數(shù)的范圍太大,且多次連續(xù)運(yùn)行時(shí)產(chǎn)生的結(jié)果相近或?yàn)榻y(tǒng)一結(jié)果,不適用于直接生成想要的隨機(jī)數(shù)。

我們使用srand()函數(shù)對隨機(jī)范圍進(jìn)行指定,在srand中則使用time函數(shù)獲取每時(shí)每刻都在變化的時(shí)間(精確到秒)。

用獲取得到的隨機(jī)數(shù)在求與行/列的模,求出的隨機(jī)數(shù)即在二維數(shù)組的范圍內(nèi),只需判斷所隨機(jī)得到的坐標(biāo)是否有棋子即可,為空表示可以將棋子落下,有內(nèi)容則重新進(jìn)行隨機(jī)。

關(guān)于time函數(shù)僅作使用,不做過多描述,可自行查閱。

srand即為以下內(nèi)容:

// test.c
srand((unsigned int)time(NULL));

rand函數(shù)需要引用頭文件,time函數(shù)需要引用頭文件

函數(shù)內(nèi)容如下:

// game.c
void ComputerMove(char board[ROW][COL], int row, int col)
{
	printf("電腦走:>\n");

	while (1)
	{
		int x = rand() % row;
		int y = rand() % col;

		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
}
7.判斷結(jié)果

是比賽就有勝利、失敗以及平局。

三子棋中當(dāng)一方棋子連成三點(diǎn)一線(包括對角線)時(shí),即為勝利,另一方失敗;

當(dāng)棋盤下滿仍無三顆同一方棋子連線時(shí),即為平局

我們創(chuàng)建IsFull函數(shù)用來判斷期盼是否已滿,并返回1或0作為滿或未滿。

只需要對二維數(shù)組進(jìn)行遍歷,逐個(gè)判斷是否為' ',即可確定棋盤是否已滿。

如下:

// game.c
int IsFull(char board[ROW][COL], int row, int col)
{
	int i = 0;
	int j = 0;
	for (i = 0; i< row; i++)
	{
		for (j = 0; j< col; j++)
		{
			if (board[i][j] == ' ')
			{
				return 0;
			}
		}
	}
	return 1;
}

然后就是判斷棋盤上的棋子是否有一方滿足勝利條件,創(chuàng)建IsWin函數(shù)來進(jìn)行判斷

a.當(dāng)一行中三個(gè)相等時(shí)

使用for循環(huán)判斷當(dāng)棋盤中行數(shù)不變時(shí),每一列的格子內(nèi)的棋子都相同且不為空時(shí),就返回相同的那種棋子;

b.當(dāng)一列中三個(gè)相等時(shí)

與上一種判定方法類似,不同之處在于列不變,每一行相同且不為空,返回相同的棋子

c.當(dāng)對角線上相等時(shí)

對角線相同有兩種情況,一種是從左上到右下,即[0][0],[1][1],[2][2]相同且不為空;另一種是從右上到左下,即[0][2],[1][1],[2][0]相同且不為空。兩種情況滿足一種即返回相同的棋子。這里同樣使用邏輯或&&對判斷條件進(jìn)行連接

d.判斷平局

在創(chuàng)建判斷棋盤是否已滿的函數(shù)時(shí),我們定義為了int類型,設(shè)定了返回值為0或1,在IsWin中,我們創(chuàng)建變量ret對IsFull的結(jié)果進(jìn)行判斷,若為1(表示棋盤已滿)就返回'D',表示平局;若為0(棋盤未滿)就返回'N'

函數(shù)代碼如下:

// game.c
char IsWin(char board[ROW][COL], int row, int col)
{
	int i = 0;

	for (i = 0; i< row; i++)
	{
		if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][1] != ' ')
		{
			return  board[i][1];//
		}
	}

	for (i = 0; i< col; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ')
		{
			return board[1][i];
		}
	}
	if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')
	{
		return board[1][1];
	}

	if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')
	{
		return board[1][1];
	}

	int ret = IsFull(board, row, col);
	if (ret == 1)
	{
		return 'D';
	}
	return 'N';
}
8.程序補(bǔ)全

函數(shù)的功能和定義已經(jīng)完成,接下來回到測試文件對邏輯進(jìn)行補(bǔ)全。

下棋需要多次的玩家和電腦進(jìn)行落子,故使用while循環(huán)進(jìn)行輪流下棋,逐步顯示當(dāng)前棋盤的內(nèi)容并判斷是否滿足勝利或者平局,有一方勝利或者棋盤已滿便退出循環(huán),不再落子。

然后就可以對返回值進(jìn)行判斷:

?????如果返回的是表示玩家的棋子'*',就輸出玩家勝利并打印棋盤;

???? 如果返回的是表示電腦的棋子'#',就打印電腦勝利并打印棋盤;

?????若返回其他內(nèi)容則表示棋盤已滿,打印平局并打印棋盤。

代碼如下:

// test.c
void Game()
{
	// 一個(gè)存放棋盤的3x3的二維數(shù)組
	char board[ROW][COL] = { 0 };
	// 初始化棋盤
	InitBoard(board, ROW, COL);

	// 打印棋盤
	PrintBoard(board, ROW, COL);

	char ret = 0;

	while (1)
	{
		//玩家下棋
		PlayerMove(board, ROW, COL);
		PrintBoard(board, ROW, COL);
		//判斷玩家是否贏得游戲
		ret = IsWin(board, ROW, COL);
		if (ret != 'N')
			break;
		//電腦下棋
		ComMove(board, ROW, COL);
		PrintBoard(board, ROW, COL);
		//判斷電腦是否贏得游戲
		ret = IsWin(board, ROW, COL);
		if (ret != 'N')
			break;
	}
	if (ret == '*')
	{
		printf("玩家贏了\n");
	}
	else if (ret == '#')
	{
		printf("電腦贏了\n");
	}
	else
	{
		printf("平局\n");
	}
	PrintBoard(board, ROW, COL);
}

至此,簡單的三子棋游戲已經(jīng)完成,具體的代碼文件已上傳,可點(diǎn)擊下方鏈接進(jìn)行查看:

GitCode-shiwuqing-game1

Gitee-shiwuqing-game1

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧

文章題目:C語言----小游戲三子棋-創(chuàng)新互聯(lián)
網(wǎng)址分享:http://muchs.cn/article42/ddddhc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供標(biāo)簽優(yōu)化、企業(yè)網(wǎng)站制作、營銷型網(wǎng)站建設(shè)微信公眾號、微信小程序、網(wǎng)站營銷

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)