国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

詳解5個C語言簡單易懂小游戲

這篇具有很好參考價值的文章主要介紹了詳解5個C語言簡單易懂小游戲。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

前言

我們通過5個簡單易懂的小游戲來加強我們對C語言的認識,這五個小游戲不僅有單人,還有人機對戰(zhàn)和人人對戰(zhàn)。讓我們在學習之余來上一局緊張刺激的小游戲吧!

一、準備工作

我們要做5個小游戲,我們要分別為5個小游戲創(chuàng)建一個頭文件和一個源文件。分別為game1.h/game1.c,game2.h/game2.c,game3.h/game3.c,game4.h/game4.c,game5.h/game5.c。這樣做的目的是把每個游戲所分開構建,方便日后對我們小游戲的重構等操作。我們還須要一個main.c,用來包含這5個小游戲的頭文件。main函數(shù)只負責調(diào)用,我們把所有小游戲代碼函數(shù)在其他文件中實現(xiàn)并用static加以修飾,使用戶使用game函數(shù)間接的調(diào)用我們小游戲的代碼。

二、游戲菜單

我們先構建main.c:
1.它需要包含五個小游戲的頭文件
2.構建我們的main函數(shù)

#include"game1.h"//包含小游戲1的頭文件
#include"game2.h"//包含小游戲2的頭文件
#include"game3.h"//包含小游戲3的頭文件
#include"game4.h"//包含小游戲4的頭文件
#include"game5.h"//包含小游戲5的頭文件
#include<time.h>
int main()
{
	srand((unsigned int)time(NULL));//用來生成隨機數(shù)
	do
	{
		int optional = 0;//創(chuàng)建一個接收選擇的變量
		menu();
		printf("請輸入你的選項:\n");
		scanf("%d", &optional);
		switch (optional)
		{
		case 1:
			game1();
			break;
		case 2:
			game2();
			break;
		case 3:
			game3();
			break;
		case 4:
			game4();
			break;
		case 5:
			game5();
			break;
		case 0:
			printf("感謝你的游玩,歡迎下次使用。\n");
			exit(0);
		default:
			printf("你的選項輸入有誤,請重新輸入:\n");
			break;
		}
	} while (1);
}

我們在main函數(shù)中用了do-while循環(huán),目的是讓用戶進行選擇,直到用戶選擇退出或者搗亂才進行退出。
scanf函數(shù)有風險,當用戶搗亂輸入字母時,會造成緩沖異常。所以我們把要接收的選擇變量放在循環(huán)中,并且賦初始值為0,當用戶輸入字母時使程序退出。
srand函數(shù)用來產(chǎn)生隨機數(shù),當我們只使用rand函數(shù)時所產(chǎn)生的隨機數(shù)會不變,會使我們重復游玩的體驗感變差。
我們在為這幾個游戲的合集創(chuàng)造一個菜單,讓用戶選擇具體游玩那個游戲。

void menu()
{
	printf("*****************************\n");
	printf("*****1.猜數(shù)字   2.三子棋*****\n");
	printf("*****3.掃  雷   4.五子棋*****\n");
	printf("*****5.飛行棋   0.退  出*****\n");
	printf("*****************************\n");
}

基本菜單已經(jīng)做好了,我們進入每個小游戲的菜單。
我們先來創(chuàng)建小游戲的頭文件:

#pragma once
#include<stdio.h>
#include<stdlib.h>
void game1();

小游戲幾我們在小游戲的頭文件中就對應game幾,我以小游戲1為例,其他四個小游戲和這個差不多。
我們再為每個創(chuàng)建源文件:

#include"game1.h"
static void menu1()
{
	printf("*****************************\n");
	printf("*****      猜數(shù)字       *****\n");
	printf("***** 1.Start the game ******\n");
	printf("***** 0.Exit the game  ******\n");
	printf("*****************************\n");
}
void game1()
{
	int optional = 0;//創(chuàng)建一個接收選擇的變量
	do
	{
		optional = 0;
		menu1();
		printf("請輸入你的選項:\n");
		scanf("%d", &optional);
		switch (optional)
		{
		case 1:
			//game();
			break;
		case 0:
			printf("猜數(shù)字小游戲以退出。\n");
			break;
		default:
			printf("你的選項輸入有誤,請重新輸入:\n");
			break;
		}
	} while (optional);
}

還是以game1為例,其他的小游戲中的選項和game1相同,只把其中的菜單函數(shù)中的小游戲換一下名字。循環(huán)中的game函數(shù)用來調(diào)用這個小游戲中的組成函數(shù)。
我們現(xiàn)在來運行一下,來測試一下代碼是否是我們所期望的那樣
c語言編程小游戲,c語言,開發(fā)語言
經(jīng)測試可以按照我們的思路正常進行,現(xiàn)在就讓我們正式寫出每個小游戲吧。

三、游戲內(nèi)容

1.猜數(shù)字

思路:系統(tǒng)隨機生成一個隨機數(shù),通過我們輸入的數(shù)和生成數(shù)進行比較,給予我們提示猜大了還是猜小了。

static void game()
{
	int num = rand() % 100 + 1;//創(chuàng)建一個變量,用來存放隨機數(shù)。
	int guess = 0;//創(chuàng)建一個變量,用來存放所猜的數(shù)字。	
	//rand函數(shù)是用來生成隨機數(shù)的,我們用rand函數(shù)生成的隨機數(shù)對100取模并加1,可以產(chǎn)生1~100的隨機數(shù)
	while(1)
	{
		printf("請輸入你猜測的數(shù)字:");
		scanf("%d", &guess);
		if (guess == num)
		{
			printf("恭喜你,猜對了!\n");
			break;
		}
		else if (guess > num)
		{
			printf("你猜的數(shù)字過大,請重新猜測吧!\n");
		}
		else if (guess < num)
		{
			printf("你猜的數(shù)字過小,請重新猜測吧!\n");
		}
	}
	return;
}

我們簡單的運行一下吧!
c語言編程小游戲,c語言,開發(fā)語言
可以正常運行,且我們可以重復的游玩。

2.三子棋

思路:用數(shù)組存儲我們的棋子,并判斷是否獲勝。
1.打印棋盤
2.玩家進行下棋
3.判斷玩家是否獲勝
4.電腦進行下棋
5.判斷電腦是否獲勝
我們先定義兩個宏:用來決定我們可以設置的棋盤大小。

#define ROW 3  //行
#define COL 3  //列

我們開始構建game函數(shù),看看里面需要什么模塊來支持游戲思路:

static void game()
{
	char win;//創(chuàng)建一個變量,存放判段獲勝條件的字符。
	//我們把C代表繼續(xù),D代表平局,*代表玩家獲勝,#代表電腦獲勝
	char checkerboard[ROW][COL] = { 0 };//創(chuàng)建一個數(shù)組,用來存放棋盤信息
	initialization(checkerboard,ROW,COL);//初始化數(shù)組,把數(shù)組中的每個元素初始化為空格
	ptintinitialization(checkerboard, ROW, COL);//打印棋盤
	while(1)
	{
		Player(checkerboard, ROW, COL, '*');//玩家下棋,玩家的標志為 *
		win = Iswin(checkerboard, ROW, COL);//判斷是否獲勝
		if (win != 'C')
		{
			break;
		}
		ptintinitialization(checkerboard, ROW, COL);//打印棋盤
		Computer(checkerboard, ROW, COL, '#');//電腦下棋,電腦的標志為 #
		win = Iswin(checkerboard, ROW, COL);
		if (win != 'C')
		{
			break;
		}
		ptintinitialization(checkerboard, ROW, COL);//打印棋盤
	}
	if (win == 'D')
	{
		printf("平局\n");
		ptintinitialization(checkerboard, ROW, COL);
	}
	else if (win == '*')
	{
		printf("恭喜你獲得勝利\n");
		ptintinitialization(checkerboard, ROW, COL);
	}
	else
	{
		printf("很遺憾,你輸?shù)袅吮荣怽n");
		ptintinitialization(checkerboard, ROW, COL);
	}
}

我們先創(chuàng)建我們所用到的數(shù)組和一個可以判斷輸贏的變量,我們把數(shù)組進行初始化,并且進行打印,讓玩家知道可以下棋的位置,通過玩家下棋函數(shù)和電腦下棋函數(shù)來實現(xiàn)人機對戰(zhàn)。
初始化數(shù)組函數(shù):

static void initialization(char arr[ROW][COL],int row,int col)//初始化數(shù)組
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			arr[i][j] = ' ';//把數(shù)組中的每個元素賦值為空格
		}
	}
}

打印棋盤函數(shù):

static void ptintinitialization(char arr[ROW][COL], int row, int col)//打印棋盤
{
	int i = 0;
	for (i = 0; i < row; i++)
	{
		int j = 0;
		for (j = 0; j < col; j++)
		{
			if (j < col - 1)
			{
				printf(" %c |", arr[i][j]);//打印棋盤,如果為列中的最后一個元素,則不打印|
			}
			else
			{
				printf(" %c ", arr[i][j]);
			}
		}
		printf("\n");
		if(i < row-1)//打印棋盤,如果為行中的最后一個元素,則不打印---
		{
			for (j = 0; j < col; j++)
			{
				if (j < col)
				{
					printf("--- ");
				}
			}
		}
		printf("\n");
	}
}

c語言編程小游戲,c語言,開發(fā)語言
打印的效果如圖所示。
當我們把宏改為:

#define ROW 9  //行
#define COL 9  //列

c語言編程小游戲,c語言,開發(fā)語言
我們可以看到打印的棋盤擴大了。這是宏的好處,不需要我們在每個函數(shù)的改數(shù)值。只需要改宏定義的數(shù)值,就可以改變我們棋盤的大小。

玩家下棋函數(shù):

static void Player(char arr[ROW][COL], int row, int col, char ch)//玩家下棋函數(shù)
{
	int x = 0;
	int y = 0;
	while(1)
	{
		printf("請輸入你要下棋的坐標:");
		scanf("%d %d", &x, &y);
		if (x<1 || x>row || y<1 || y>col)//判斷坐標是否合法
		{
			printf("你輸入的坐標不合法,請重新輸入。\n");
		}
		else if (arr[x - 1][y - 1] != ' ')//判斷輸入坐標是否被占用
		{
			printf("你輸入的坐標已被占用,請重新輸入。\n");
		}
		else
		{
			arr[x - 1][y - 1] = ch;//數(shù)組下標從0開始,所以玩家的真實坐標要進行減1
			break;
		}
	}
}

電腦下棋函數(shù):

static void Computer(char arr[ROW][COL], int row, int col, char ch)
{
	while (1)
	{
		int x = rand() % 3;//產(chǎn)生0~2的數(shù)字
		int y = rand() % 3;
		if (arr[x][y] == ' ')//如果坐標未被占用,則電腦下棋,否則產(chǎn)生新的坐標進行判斷
		{
			arr[x][y] = ch;//電腦的坐標的下標和數(shù)組下標對應,不需要進行減1操作
			break;
		}
	}
}

判斷是否獲勝函數(shù):

static char Iswin(char arr[ROW][COL], int row, int col)//判斷是否獲勝
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)//判斷每一排中是否有人獲勝
	{
		if (arr[i][0] == arr[i][1] && arr[i][1] == arr[i][2] && arr[i][1] != ' ')
		{
			return arr[i][1];
		}
	}
	for (i = 0; i < col; i++)//判斷每一列中是否有人獲勝
	{
		if (arr[0][i] == arr[1][i] && arr[1][i] == arr[2][i] && arr[1][i] != ' ')
		{
			return arr[1][i];
		}
	}
	if ((arr[0][0] == arr[1][1] && arr[1][1] == arr[2][2] && arr[1][1] != ' ') || 
		(arr[0][2] == arr[1][1] && arr[1][1] == arr[2][0] && arr[1][1] != ' '))//判斷對角線上是否有人獲勝
	{
		return arr[1][1];
	}
	for (i = 0; i < row; i++)
	{
		for (j = 0; i < col; i++)
		{
			if (arr[i][j] == ' ');//判斷是否還有空位
			{
				return 'C';
			}
		}
	}
	return 'D';
}

讓我們運行一下看看結果吧!
c語言編程小游戲,c語言,開發(fā)語言
注意:
1.我們所使用的scanf是不安全的,大家可以查找一下對應的解決辦法,了解一下為什么不安全。
2.對所用的數(shù)組進行初始話是要注意間隔,數(shù)組傳參是注意形參和實參的類型是否一致,我們使用的是char類型數(shù)組,如果形參用int接受會造成什么情況呢?大家可以下去試一試。
3.大家可以對這個代碼進行重構,可以實現(xiàn)人人對戰(zhàn)。在這里只顯示了人機對戰(zhàn),重構一下加入人人對戰(zhàn)吧。
如果形參用int接受會造成數(shù)組越界,造成棧錯誤。

3.掃雷

思路:用數(shù)組存儲雷的信息,通過排查,找到?jīng)]有雷的地方。
1.打印地圖
2.玩家進行掃雷
3.判斷玩家是否踩雷
4.更新地圖
分析:
在這里插入圖片描述c語言編程小游戲,c語言,開發(fā)語言
上圖是一個9*9的掃雷地圖,當我們要判斷紅色的地方,對周邊的判斷勢必會造成越界訪問。如何解決這個問題呢?
我們把這個數(shù)組上下左右個擴充一行,這樣進行判斷就不會產(chǎn)生數(shù)組越界了。打印數(shù)組的問題我們通過代碼來分析吧。
我們設置兩個數(shù)組,一個用來存儲地圖信息,一個用來向玩家展示,向玩家展示的數(shù)組需要通過存儲地圖信息的數(shù)組來判斷地圖上的安全地方。
我們先定義五個宏:分別決定我們可以設置的地圖大小和我們打印地圖的大小,最后一個宏來存放我們地雷的個數(shù),后期也方便我們進行測試。

#define ROW 9  //顯示的行
#define COL 9  //顯示的列
#define ROWS ROW+2  //真實數(shù)組的行
#define COLS COL+2  //真實數(shù)組的列
#define MINENUM 10  //地雷的個數(shù)

然后對我們的game函數(shù)進行補充,來看看具體的思路吧:

static void game()
{
	int winnum = ROW * COL - MINENUM;//設置一個變量,用來存放還有多少個安全的地方
	char minemap[ROWS][COLS] = { 0 };//雷分布的地圖
	char showmap[ROWS][COLS] = { 0 };//向玩家展示的地圖
	Initialization(minemap, showmap, ROWS, COLS);//初始化數(shù)組,把雷分布隨機分布在地圖中,并且把向玩家展示的地圖全部替換為 * 
	//Ptintinitialization(minemap, ROW, COL);//測試代碼,用來打印地圖
	while (winnum)
	{
		int x = 0;
		int y = 0;
		Ptintinitialization(showmap, ROW, COL);//打印展示地圖
		printf("請輸入排雷坐標:");
		scanf("%d %d", &x, &y);
		if (x<1 || x>ROW || y<1 || y>COL)//判斷坐標是否合法
		{
			printf("你輸入的坐標不合法,請重新輸入。\n");
		}
		else if (showmap[x][y] != '*')//判斷坐標是否已被排查過
		{
			printf("你輸入的坐標已被排過雷了,請重新輸入。\n");
		}
		else 
		{
			if (!Determine(minemap, x, y))//!Determine(minemap, x, y)用來判斷是否踩到雷
			{
				Ptintinitialization(minemap, ROW, COL);//打印地雷地圖,讓玩家知道地雷在哪里。
				break;
			}
			Renewmap(minemap, showmap, x, y);//用來更新向玩家展示的地圖
			winnum--;//對安全的地方進行減1
		}
	}
	if(winnum == 0)//當安全地方為0時,證明排雷成功
	{
		printf("恭喜你排雷成功!\n");
		Ptintinitialization(showmap, ROW, COL);//打印展示地圖,讓玩家知道自己獲勝地圖
	}
}

初始化數(shù)組函數(shù):

static void Initialization(char minemap[ROWS][COLS], char showmap[ROWS][COLS], int rows, int cols)
{
	int count = MINENUM;//創(chuàng)建一個變量,用來計算放置的雷的數(shù)量
	int i = 0;
	int j = 0;
	for (i = 0; i < rows; i++)//把地雷地圖全部賦值為字符0
	{
		for (j = 0; j < cols; j++)
		{
			minemap[i][j] = '0';
		}
	}
	while (count)//把雷分布隨機分布在地雷地圖中
	//我們把0代表安全,1代表雷區(qū)
	{
		int x = rand() % ROW + 1;//創(chuàng)建隨機變量范圍在1~9
		int y = rand() % COL + 1;//創(chuàng)建隨機變量范圍在1~9
		if (minemap[x][y] == '0')//判斷該位置是否已有雷
		{
			minemap[x][y] = '1';//放置地雷
			count--;
		}
	}
	for (i = 0; i < rows; i++)//把展示地圖全部賦值為字符*
	{
		for (j = 0; j < cols; j++)
		{
			showmap[i][j] = '*';
		}
	}
}

c語言編程小游戲,c語言,開發(fā)語言
我們所展示的地圖行為1 ~ ROW,列為1 ~ COL,所以把生成的雷的坐標控制在這個范圍之間。
打印地圖函數(shù):

static void Ptintinitialization(char showmap[ROWS][COLS], int row, int col)//打印地圖
{
	int i = 1;
	int j = 1;
	for (i = 1; i <= row; i++)
	{
		if (i == 1)//當i為1時,需要多一個空格,目的為了和地圖對齊
		{
			printf(" ");
		}
		printf(" %d", i);
	}
	printf("\n");
	for (i = 1; i <= row; i++)//打印我們所需要的地圖
	{
		printf("%d", i);
		for (j = 1; j <= col; j++)
		{
			printf(" %c", showmap[i][j]);
		}
		printf("\n");
	}
}

我們從1開始打印,打印到ROW處,只打印我們所需要的地方。
判斷是否踩到雷:

static bool Determine(char minemap[ROWS][COLS],int x,int y)
{
	if (minemap[x][y] == '1')
	{
		printf("排雷失敗,你已死亡!\n");
		return false;
	}
	else
	{
		return true;
	}
}

更新展示的地圖:

static void Renewmap(char minemap[ROWS][COLS], char showmap[ROWS][COLS], int x, int y)
{
	showmap[x][y] = (minemap[x - 1][y - 1] + minemap[x - 1][y] + minemap[x - 1][y + 1]
				  + minemap[x][y - 1] + minemap[x][y + 1]
				  + minemap[x + 1][y - 1] + minemap[x + 1][y] + minemap[x + 1][y + 1]) - 8*'0' + '0';
}

c語言編程小游戲,c語言,開發(fā)語言
更新向玩家展示的地圖,把周圍的地雷數(shù)相加,并用相應的數(shù)字代替。我們用的是字符數(shù)組,里面存放的是字符1和字符0,所以要減去0的ASCLL碼值可以得到整形數(shù)字,把他們相加代表這個方格周圍8個地方的地雷數(shù),最后加上0的ASCLL碼值得到對應的字符數(shù)字。
讓我們測試一下:我們把測試代碼解除注釋,并把我們宏定義的地雷個數(shù)設置的大一點,我先把它設置為79,真正游玩時可以根據(jù)想要玩的難度進行更改
c語言編程小游戲,c語言,開發(fā)語言
我們看看排雷失敗會不會正常顯示:
c語言編程小游戲,c語言,開發(fā)語言
排雷失敗也會正常顯示。
注意:
1.scanf是不安全的
2.對所用的數(shù)組進行初始話是要注意間隔,對數(shù)組進行訪問時要注意是否越界。
3.重構思路:可以加入展開地圖(周圍8個地方?jīng)]有地雷時可以展開,知道一個格子周圍有地雷為止),加入小旗(把認為是地雷的地方用小旗替換,只有取消小旗改位置才可以進行掃雷),加入時間(當時間終止時未排完所有雷則游戲結束)等。

4.五子棋

思路:判斷那個玩家先進行了五子連珠(一行或一列或者對角線有連續(xù)的5顆一樣的棋子)
1.打印棋盤
2.玩家1進行下棋
3.判斷玩家1是否獲勝
4.玩家2進行下棋
5.判斷玩家2是否獲勝
我們還是先用宏定義棋盤大?。?/p>

#define ROW 9  //棋盤的行
#define COL 9  //棋盤的列

再來看game思路:

static void game()
{
	char win;//創(chuàng)建一個變量,存放判段獲勝條件的字符。
	//我們把C代表繼續(xù),D代表平局,白棋(@)代表玩家1獲勝,黑棋(O)代表玩家2獲勝
	char checkerboard[ROW][COL] = { 0 };//棋盤數(shù)組
	Initialization(checkerboard, ROW, COL);//初始化數(shù)組,把棋盤的所有位置都賦值為 *
	Ptintinitialization(checkerboard, ROW, COL);//打印棋盤
	while (1)
	{
		Player(checkerboard, ROW, COL, '@');//玩家1下棋,玩家1的標志為 @
		win = Iswin(checkerboard, ROW, COL);//判斷是否獲勝
		if (win != 'C')
		{
			break;
		}
		Ptintinitialization(checkerboard, ROW, COL);//打印棋盤
		Player(checkerboard, ROW, COL, 'O');//玩家2下棋,玩家2的標志為 O
		win = Iswin(checkerboard, ROW, COL);//判斷是否獲勝
		if (win != 'C')
		{
			break;
		}
		Ptintinitialization(checkerboard, ROW, COL);//打印棋盤
	}
	if (win == 'D')
	{
		printf("平局\n");
		Ptintinitialization(checkerboard, ROW, COL);
	}
	else if (win == '@')
	{
		printf("玩家1獲勝\n");
		Ptintinitialization(checkerboard, ROW, COL);
	}
	else
	{
		printf("玩家2獲勝\n");
		Ptintinitialization(checkerboard, ROW, COL);
	}
}

五子棋的思路和三子棋的思路一模一樣,只是把電腦換成了另一個玩家。所以game函數(shù)代碼基本沒有太大變化。而玩家下棋思路一致,所以我們只需要一個函數(shù)就可以解決兩個玩家下棋的思路。
初始化數(shù)組函數(shù):

static void Initialization(char arr[ROW][COL], int row, int col)//初始化數(shù)組,把棋盤的所有位置都賦值為 *
{
	int i = 0;
	int j = 0;
	for (i = 0; i < row; i++)//把展示地圖全部賦值為字符*
	{
		for (j = 0; j < col; j++)
		{
			arr[i][j] = '*';
		}
	}
}

對數(shù)組進行初始化和掃雷中向玩家展示的地圖的思路一模一樣。
打印地圖函數(shù):

static void Ptintinitialization(char arr[ROW][COL], int row, int col)//打印棋盤
{
	int i = 0;
	int j = 0;
	for (i = 1; i <= row; i++)
	{
		if (i == 1)//當i為1時,需要多兩個空格,目的為了和地圖對齊
		{
			printf("  ");
		}
		if (i < 9)//當i小于9時,需要多一個個空格,目的為了和地圖對齊
		{
			printf(" %d ", i);
		}
		else//當i大于于9時,不需要多一個個空格
		{
			printf(" %d", i);
		}
	}
	printf("\n");
	for (i = 0; i < row; i++)//打印我們所需要的地圖
	{
		printf("%2d", i + 1);
		for (j = 0; j < col; j++)
		{
			printf(" %c ", arr[i][j]);//需要多一個個空格,目的為了和地圖對齊
		}
		printf("\n");
	}
}

五子棋的地圖可以隨便放大縮小,一定要注意地圖是否和上面的行和列進行了對齊。
玩家下棋函數(shù):

int x = 0;//用來接收玩家下棋的坐標
int y = 0;//用來接收玩家下棋的坐標
static void  Player(char arr[ROW][COL], int row, int col, char ch)//玩家下棋函數(shù),通過ch來判斷是玩家1還是玩家2
{
	int player = 0;//創(chuàng)建一個變量來確定是玩家?guī)?/span>
	if (ch == '@')//如果ch為白棋(@),則代表玩家1
	{
		player = 1;
	}
	else//反之則為玩家2
	{
		player = 2;
	}
	while (1)
	{
		printf("請玩家 %d 輸入要下棋的坐標:",player);
		scanf("%d %d", &x, &y);
		if (x<1 || x>row || y<1 || y>col)//判斷坐標是否合法
		{
			printf("你輸入的坐標不合法,請重新輸入。\n");
		}
		else if (arr[x - 1][y - 1] != '*')//判斷輸入坐標是否被占用
		{
			printf("你輸入的坐標已被占用,請重新輸入。\n");
		}
		else
		{
			arr[x - 1][y - 1] = ch;//數(shù)組下標從0開始,所以玩家的真實坐標要進行減1
			break;
		}
	}
}

我們把玩家下棋的坐標設置為全局變量,方便我們判斷是否是五子連珠的情況。
判斷是否獲勝函數(shù):
c語言編程小游戲,c語言,開發(fā)語言

enum Direction
{
	LEFT,
	RIGHT,
	UP,
	DOWN,
	LEFTUP,
	RIGHTDOWN,
	RIGHTUP,
	LEFTDOWN
};
static char Iswin(char arr[ROW][COL], int row, int col)//判斷是否獲勝
{
	static chessnum = 0;//創(chuàng)建一個靜態(tài)變量,用來存放棋盤中使用的格數(shù)
	chessnum++;//每進行一次判斷調(diào)用就對棋盤使用格數(shù)進行+1
	int winnum1 = 1 + Wincount(arr, ROW, COL, LEFT) + Wincount(arr, ROW, COL, RIGHT);
	//確定左和右共計多少相同個棋子,需要加上自身的棋子
	int winnum2 = 1 + Wincount(arr, ROW, COL, UP) + Wincount(arr, ROW, COL, DOWN);
	//確定上和下共計多少相同個棋子,需要加上自身的棋子
	int winnum3 = 1 + Wincount(arr, ROW, COL, LEFTUP) + Wincount(arr, ROW, COL, RIGHTDOWN);
	//確定左上和右下共計多少相同個棋子,需要加上自身的棋子
	int winnum4 = 1 + Wincount(arr, ROW, COL, RIGHTUP) + Wincount(arr, ROW, COL, LEFTDOWN);
	//確定右上和左下共計多少相同個棋子,需要加上自身的棋子
	if (winnum1 >= 5 || winnum2 >= 5 || winnum3 >= 5 || winnum4 >= 5)//判斷是否獲勝
	{
		return arr[x - 1][y - 1];//返回獲勝棋子的字符
	}
	else
	{
		if (chessnum == ROW * COL)//如果棋盤使用格數(shù)等于棋盤的格數(shù),證明平局
		{
			return 'D';
		}
		else//如果棋盤使用格數(shù)不等于棋盤的格數(shù),證明還有空位,繼續(xù)進行比賽
		{
			return 'C';
		}
	}
}

我們需要統(tǒng)計這8個方向的棋子相同個數(shù)。不會產(chǎn)生5個連著 * 的情況,我們保存的地址永遠是上一個玩家落子的地址。我們把8個方向用menu類型進行表示。

static int Wincount(char arr[ROW][COL], int row, int col, enum Direction dir)
{
	int count = 0;//記錄相同棋子個數(shù)
	int _x = x - 1;//要對坐標進行減1,因為我們的棋盤從1開始,數(shù)組下標從0開始
	int _y = y - 1;//要對坐標進行減1,因為我們的棋盤從1開始,數(shù)組下標從0開始
	//用局部變量保存,避免在這里修改全局變量的值
	while (1)
	{
		switch (dir)
		{
		case LEFT:
			_y--;//對中心坐標的列坐標進行減1
			break;
		case RIGHT:
			_y++;//對中心坐標的列坐標進行加1
			break;
		case UP:
			_x++;
			break;
		case DOWN:
			_x--;
			break;
		case LEFTUP:
			_y--;
			_x++;
			break;
		case RIGHTDOWN:
			_y++;
			_x--;
			break;
		case RIGHTUP:
			_y++;
			_x++;
			break;
		case LEFTDOWN:
			_y--;
			_x--;
			break;
		default:
			break;
		}
		if (_x < 0 || _x > ROW || _y < 0 || _y>COL)//判斷位置是否合法
		{
			return count;
		}
		else if(arr[_x][_y] != arr[x-1][y-1])//判斷是否和上一個玩家的棋子相同
		{
			return count;
		}
		else
		{
			count++;
		}
	}
}

我們設置為死循環(huán),用來判斷相同方向中具體棋子個數(shù)。menu類型更具我們傳的參數(shù)不同,在switch分支中走不同的路線。
注意:
數(shù)組的越界。
對五子連珠的判斷
重構思路:可以加入網(wǎng)絡,實現(xiàn)網(wǎng)路對戰(zhàn),可以加入悔棋功能等

5.飛行棋

玩法:1.除了起始位置是一樣的,其余時間當一名玩家位置和另一名玩家位置相同時發(fā)生踩踏。
2.當玩家踩到道具時,進行相應的道具操作
3.那個玩家先到終點即為獲勝
思路:
1.用數(shù)組來存儲地圖信息
2.用一個結構體來構造玩家信息
3.用一個結構體數(shù)組來存儲玩家信息
4.用隨機函數(shù)模擬篩子操作
我們先對game思路進行構造:

int map[100];//創(chuàng)建一個地圖大小為100的地圖。并且把地圖元素全部初始化為0
//為了對數(shù)組進行方便的操作,我們把數(shù)組設置為全局變量,使每個函數(shù)可以直接訪問數(shù)組
static void game()
{
	struct Player play[2];//創(chuàng)建一個玩家數(shù)組,里面存放玩家信息
	Initializationmap();//初始化地圖數(shù)組,把地圖相應位置填上道具元素,
	//我們把地圖數(shù)組設置為了全局函數(shù),所以不要需要傳參
	Initializationplay(play);//初始化玩家數(shù)組,加入玩家信息,并把玩家位置置于地圖開始位置
	Ptintinitialization(play);//打印棋盤,地圖數(shù)組為全局函數(shù),所以不要對地圖傳參。
	//需要玩家信息來判斷地圖要填的字符,所以要對玩家進行傳參
	while (1)//使玩家交替進行游玩,直到產(chǎn)生勝利者
	{
		if (play[0].flags == false)//判斷玩家1是否處于暫停回合。
		{
			Play(&play[0], &play[1],play);//玩家1進行游戲
			Ptintinitialization(play);//打印棋盤
		}
		else//處于暫?;睾?,把暫停回合改為繼續(xù)
		{
			play[0].flags = false;
		}
		if (play[0].position >= 99)//判斷玩家1是否獲勝
		{
			printf("%s僥幸贏了%s\n", play[0].name, play[1].name);
			break;
		}
		if (play[1].flags == false)//判斷玩家2是否處于暫?;睾?。
		{
			Play(&play[1], &play[0],play);//玩家2進行游戲
			Ptintinitialization(play);//打印棋盤
		}
		else
		{
			play[1].flags = false;//更改暫停選項
		}
		if (play[1].position >= 99)//判斷玩家2是否獲勝
		{
			printf("%s僥幸贏了%s\n", play[1].name, play[0].name);
			break;
		}
	}
}

我們?yōu)榱朔奖惆训貓D數(shù)組設置位全局數(shù)組,這樣減少傳參。并且數(shù)組在初始化后是不需要改變的。我們另外設置了一個結構體數(shù)組用來存放玩家信息(位置,是否處于暫停位)。
初始化地圖函數(shù):

static void Initializationmap()//初始化地圖數(shù)組
//地圖數(shù)組中
//0代表什么都沒有
//1代表道具1(幸運輪盤),2代表道具2(地雷),3代表道具3(暫停),4代表道具4(時空隧道)
{
	int luckyturn[] = {1, 20, 45, 60, 75, 90};//在相應的位置放入 幸運輪盤
	for (int i = 0; i < sizeof(luckyturn) / sizeof(luckyturn[0]); i++)
	//sizeof(luckyturn) / sizeof(luckyturn[0])用來求出數(shù)組元素的個數(shù)
	{
		map[luckyturn[i]] = 1;
	}
	int Landmine[] = { 3, 6, 19, 25, 36, 49, 69, 70, 80 };//在相應的位置放入 地雷
	for (int i = 0; i < sizeof(Landmine) / sizeof(Landmine[0]); i++)
	{
		map[Landmine[i]] = 2;
	}
	int puse[] = { 2, 11, 26, 35, 44, 59, 71, 88 };//在相應的位置放入 暫停
	for (int i = 0; i < sizeof(puse) / sizeof(puse[0]); i++)
	{
		map[puse[i]] = 3;
	}
	int timetunnel[] = { 5, 15, 30, 50, 77 };//在相應的位置放入 時空隧道
	for (int i = 0; i < sizeof(timetunnel) / sizeof(timetunnel[0]); i++)
	{
		map[timetunnel[i]] = 4;
	}
}

初始化地圖操作使我們在想要的位置放置合適的道具,道具的位置可以根據(jù)自己的喜歡而改變。
初始化玩家函數(shù):

static void Initializationplay(struct Player *play)
{
	printf("請輸入玩家A的姓名\n");
	scanf("%s", &(play[0].name));
	while (!strcmp(play[0].name,""))//判斷玩家A的姓名是否為空
	{
		printf("玩家姓名不能為空,請重新輸入玩家A的姓名\n");
		scanf("%s", &(play[0].name));
	}
	printf("請輸入玩家B的姓名\n");
	scanf("%s", &(play[1].name));
	while (1)
	{
		if (!strcmp(play[1].name, ""))//判斷玩家B的姓名是否為空
		{
			printf("玩家姓名不能為空,請重新輸入玩家B的姓名\n");
			scanf("%s", &(play[1].name));
		}
		else if(!strcmp(play[1].name, play[0].name))//判斷玩家B的姓名和玩家A是否相同
		{
			printf("玩家姓名不能一致,請重新輸入玩家B的姓名\n");
			scanf("%s", &(play[1].name));
		}
		else
		{
			break;
		}
	}
	play[0].position = 0;//把玩家A的位置置于0位置(地圖開始位置)
	play[0].flags = false;//把玩家A的暫停條件置為假。
	play[1].position = 0;//把玩家B的位置置于0位置(地圖開始位置)
	play[1].flags = false;//把玩家B的暫停條件置為假。
}

在這個函數(shù)中我們進行了字符串比較,字符串比較不可以直接用 ==,必須要用strcmp函數(shù)
展示地圖函數(shù):

extern char Drawstrmap(const struct Player* play, int i);//對Drawstrmap函數(shù)進行聲明
static void Ptintinitialization(const struct Player* play) //打印棋盤
//由于不會對玩家信息進行更改,我們把參數(shù)設置為const,防止在函數(shù)中誤改
{
		printf("圖例:幸運輪盤:#    地雷:@    暫停:I     時空隧道:>     \n");//向玩家展示道具信息
		//第一段
		for (int i = 0; i < 30; i++)
		{
			printf("%c ", Drawstrmap(play, i));
		}
		printf("\n");
		//第一豎列
		for (int i = 30; i < 35; i++)
		{
			for (int j = 0; j <= 28; j++)
			{
				printf("  ");
			}
			printf("%c ", Drawstrmap(play, i));
			printf("\n");
		}
		//第二段
		for (int i = 64; i >= 35; i--)//地圖為從前向后打打印
		{
			printf("%c ", Drawstrmap(play, i));
		}
		printf("\n");
		//第二數(shù)列
		for (int i = 65; i <= 69; i++)
		{
			printf("%c ", Drawstrmap(play, i));
			printf("\n");
		}
	    //第三行豎列
		for (int i = 70; i <= 99; i++)
		{
			printf("%c ", Drawstrmap(play, i));
		}
		printf("\n");//畫完地圖換行
}

static char Drawstrmap(const struct Player* play, int i)//打印地圖元素
{
	char ch;
	if (play[0].position == play[1].position && play[0].position == i)
	//當玩家1和玩家2的位置處于起始位置時
	{
		ch = 'M';
	}
	else if (play[0].position == i)//當玩家1位于當前位置時
	{
		ch = 'A';
	}
	else if (play[1].position == i)//當玩家2位于當前位置時
	{
		ch = 'B';
	}
	else
	{
		switch (map[i])
		{
		case 0://地圖數(shù)組元素為0時
			ch = 'O';
			break;
		case 1:
			ch = '#';
			break;
		case 2:
			ch = '@';
			break;
		case 3:
			ch = 'I';
			break;
		case 4:
			ch = '>';
			break;
		}
	}
	return ch;
}

c語言編程小游戲,c語言,開發(fā)語言
這里我們構造了一個Drawstrmap函數(shù),目的是把地圖數(shù)組中的整形元素構造為我們所需要的字符元素,我們傳入地圖的位置,來判斷具體打印什么字符,且不對我們地圖數(shù)組進行更改。
游玩函數(shù):

static void Play(struct Player *play1, struct Player* play2, struct Player* play)
//play1為當前玩家,play2為另一名玩家,play為玩家數(shù)組,傳玩家數(shù)組方便進行位置判斷
{
	int points = rand() % 6 + 1;//設置隨機變量,范圍為1~6
	printf("%s請按任意鍵開始致篩子\n", play1->name);
	system("pause");//暫停屏幕
	printf("%s篩到了%d,前進%d格,", play1->name, points, points);
	system("pause");
	play1->position += points;//對玩家位置進行更新
	Weizhi(play);//判斷玩家位置是否在合法的范圍內(nèi)
	if (play1->position == play2->position)//現(xiàn)在玩家的位置和另一名玩家位置相同時
	{
		printf("%s踩到了%s,%s退6格,", play1->name, play2->name, play2->name);
		system("pause");
		play2->position -= 6;//對另一名玩家位置進行更新
		Weizhi(play);//判斷玩家位置是否在合法的范圍內(nèi)
		printf("%s已退6格,", play2->name);
		system("pause");
	}
	else
	{
		switch (map[play1->position])//檢查本位玩家是否進行到道具位置
		{
		case 0:
			printf("%s踩到了方塊,安全,", play1->name);
			system("pause");
			break;
		case 1:
		{
			printf("%s踩到了幸運轉(zhuǎn)盤,1————交換位置,2————轟炸對方,請選擇按鍵\n", play1->name);
			int a = 0;//用來接收用戶的選擇
			scanf("%d", &a);
			while (1)
			{
				if (a == 1)
				{
					printf("%s選擇了交換位置,", play1->name);
					system("pause");
					int b = play1->position;
					play1->position = play2->position;
					play2->position = b;
					Weizhi(play);//判斷玩家位置是否在合法的范圍內(nèi)
					printf("交換完成,");
					system("pause");
					break;
				}
				else if (a == 2)
				{
					printf("%s選擇了轟炸對方,%s向后退6格,", play1->name, play2->name);
					system("pause");
					play2->position -= 6;
					Weizhi(play);
					printf("執(zhí)行成功,\n");
					system("pause");
					break;
				}
				else
				{
					printf("輸入不正確,請重新輸入");
					int ch;
					while ((ch = fgetc(stdin)) != EOF && ch != '\n');
					//清除緩沖區(qū),防止緩沖區(qū)問題使程序不能正常進行
					scanf("%d", &a);
				}
			}
		}
			break;
		case 2:
			printf("%s踩到了地雷,退6格,", play1->name);
			system("pause");
			play1->position -= 6;
			Weizhi(play);
			break;
		case 3:
			printf("%s踩到了暫停,下一回合禁止行動", play1->name);
			system("pause");
			play1->flags = true;
			break;
		case 4:
			printf("%s踩到了時空隧道,前進十格", play1->name);
			system("pause");
			play1->position += 10;
			Weizhi(play);
			break;
		}
	}
	Weizhi(play);
	system("cls");//清除屏幕
}

我們在游玩函數(shù)中來進行篩子的模擬和道具的使用。我們設置清除緩沖區(qū)是為了解決scanf函數(shù)緩沖區(qū)問題,避免出現(xiàn)死循環(huán)。
注意:
數(shù)組的越界。我們要確保每個玩家的位置處于地圖中。
字符串的比較
重構思路:1.可以加入網(wǎng)絡,實現(xiàn)網(wǎng)路對戰(zhàn),2.把幸運輪盤單獨封裝為一個函數(shù)。3.加入更多道具。4.加入其他玩家。5可以加入積分,用積分換取道具。

總結

我們的五個小游戲已經(jīng)全部做完。下面是做小游戲要注意的點:
scanf函數(shù)是不安全,我們可以尋找一個安全的函數(shù)進行替代,或者解決scanf的安全問題
謹防數(shù)組越界,我們好幾個小游戲都用了數(shù)組進行存儲,有字符型數(shù)組,還有整形數(shù)組,要謹防數(shù)組越界,注意數(shù)組傳參。
把經(jīng)常使用的代碼構造為函數(shù),減少代碼冗余。文章來源地址http://www.zghlxwxcb.cn/news/detail-520686.html

到了這里,關于詳解5個C語言簡單易懂小游戲的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • C語言經(jīng)典小游戲之掃雷(超詳解釋+源碼)

    C語言經(jīng)典小游戲之掃雷(超詳解釋+源碼)

    “少年氣,是歷盡千帆舉重若輕的沉淀,也是樂觀淡然笑對生活的豁達!” 今天我們學習一下掃雷游戲怎么用C語言來實現(xiàn)! 一個掃雷盤面由許多方格(cell)組成,方格中隨機分布著一定數(shù)量的雷(mine),一個格子中至多只有1雷。勝利條件是打開所有安全格(非雷格,saf

    2024年02月12日
    瀏覽(96)
  • C語言經(jīng)典小游戲之三子棋(超詳解釋+源碼)

    C語言經(jīng)典小游戲之三子棋(超詳解釋+源碼)

    “縱有疾風來,人生不言棄,風乍起,合當奮意向此生?!?今天我們一起來學習一下三子棋小游戲用C語言怎么寫出來? 《三子棋》是一款古老的民間傳統(tǒng)游戲,又被稱為黑白棋、圈圈叉叉棋、井字棋、一條龍、九宮棋等。游戲分為雙方對戰(zhàn),雙方依次在9宮格棋盤上擺放棋子

    2024年02月14日
    瀏覽(19)
  • python超簡單小游戲代碼,python簡單小游戲代碼

    python超簡單小游戲代碼,python簡單小游戲代碼

    大家好,小編來為大家解答以下問題,python超簡單小游戲代碼,python簡單小游戲代碼,今天讓我們一起來看看吧! 大家好,我是辣條。 今天給大家?guī)?0個py小游戲,一定要收藏! 目錄 有手就行 1、吃金幣 2、打乒乓 3、滑雪 4、并夕夕版飛機大戰(zhàn) 5、打地鼠 簡簡單單 6、小恐

    2024年03月14日
    瀏覽(102)
  • python簡單小游戲代碼教程,python編程小游戲簡單的

    python簡單小游戲代碼教程,python編程小游戲簡單的

    大家好,小編來為大家解答以下問題,一些簡單好玩的python編程游戲,python編寫的入門簡單小游戲,今天讓我們一起來看看吧! 哈嘍鐵子們 表弟最近在學Python,總是跟我抱怨很枯燥無味,其實,他有沒有認真想過,可能是自己學習姿勢不對? 比方說,可以通過打游戲來學編

    2024年04月23日
    瀏覽(30)
  • python簡單小游戲代碼10行,python超簡單小游戲代碼

    python簡單小游戲代碼10行,python超簡單小游戲代碼

    大家好,小編為大家解答python編寫的入門簡單小游戲代碼大全的問題。很多人還不知道python編寫的入門簡單小游戲代碼,現(xiàn)在讓我們一起來看看吧! 玩法:上下控制起跳躲避 玩法:三個相連就能消除 玩法:童年經(jīng)典,普通模式?jīng)]啥意思,小時候我們都是玩加速的。 玩法:童

    2024年02月08日
    瀏覽(21)
  • python簡單小游戲代碼100行,python超簡單小游戲代碼

    python簡單小游戲代碼100行,python超簡單小游戲代碼

    大家好,小編為大家解答python簡單小游戲代碼100行的問題。很多人還不知道python超簡單小游戲代碼,現(xiàn)在讓我們一起來看看吧! Source code download: 本文相關源碼 大家好,小編來為大家解答以下問題,一些簡單好玩的python編程游戲,python編寫的入門簡單小游戲,今天讓我們一起

    2024年01月19日
    瀏覽(29)
  • python簡單小游戲代碼10行,簡單的python小游戲代碼

    python簡單小游戲代碼10行,簡單的python小游戲代碼

    本篇文章給大家談談python簡單小游戲代碼200行,以及python簡單小游戲代碼20行,希望對各位有所幫助,不要忘了收藏本站喔。 大家好,小編來為大家解答以下問題,python編程一個最簡單游戲代碼,python編程游戲代碼大全,今天讓我們一起來看看吧! 大家好,我是辣條。 今天

    2024年01月22日
    瀏覽(34)
  • python簡單小游戲代碼100行,簡單的python小游戲代碼

    python簡單小游戲代碼100行,簡單的python小游戲代碼

    大家好,給大家分享一下python簡單小游戲代碼100行,很多人還不知道這一點。下面詳細解釋一下。現(xiàn)在讓我們來看看! Source code download: 本文相關源碼 大家小時候都玩過貪吃蛇吧?小編小時候可喜歡拿爸媽的手機玩了,厲害著呢!今天,小編就來用100行代碼實現(xiàn)一個簡易版的

    2024年04月14日
    瀏覽(31)
  • python簡單小游戲代碼200行,python簡單的小游戲代碼

    python簡單小游戲代碼200行,python簡單的小游戲代碼

    大家好,小編為大家解答python簡單小游戲代碼200行的問題。很多人還不知道python簡單的小游戲代碼,現(xiàn)在讓我們一起來看看吧! 貪吃蛇游戲是有史以來最受歡迎的街機游戲之一。在這個游戲中,玩家的主要目標是在不撞墻或不撞墻的情況下抓住最大數(shù)量的水果python基礎知識點

    2024年02月02日
    瀏覽(25)
  • python簡單小游戲代碼教程,python編程小游戲代碼

    python簡單小游戲代碼教程,python編程小游戲代碼

    大家好,本文將圍繞一些簡單好玩的python編程游戲展開說明,python編寫的入門簡單小游戲是一個很多人都想弄明白的事情,想搞清楚python簡單小游戲代碼教程需要先了解以下幾個事情。 Source code download: 本文相關源碼 大家好,我是辣條。 今天給大家?guī)?0個py小游戲,一定要

    2024年02月03日
    瀏覽(109)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包