【C语言BOSS篇】合理运用数组打造你的三子棋小游戏

🏝️专栏:《C语言BOSS篇》

🌅主页:f狐o狸x


目录

一、数组的创建和初始化

        1.1 一维数组的创建和初始化

        1.2 一维数组的使用

        1.3 二维数组的创建和初始化

        1.4 二维数组的使用

二、数组作为函数参数

        2.1 冒泡排序

三、三子棋小游戏

        3.1 目录

        3.2 打印棋盘

        3.3 玩家下棋

        3.4 电脑下棋

        3.5 判断输赢

        3.6 游戏全代码

        3.7 Ps


一、数组的创建和初始化

        数组是一组同类型元素的集合,合理运用数组可以帮我们完成一些复杂的操作

        1.1 一维数组的创建和初始化

        一维数组创建的方式:

type_t   arr_name[const_n];
//type_t 是指数组的元素类型
//const_n 是一个常量表达式,用来指定数组的大小

        一维数组创建的实例:

int arr1[10] = {1,2,3};

int arr2[] = {1,2,3,4};

int arr3[5] = {1,2,3,4,5};

char arr4[3] = {'a',98, 'c'};

char arr5[] = {'a','b','c'};

char arr6[] = "abcdef";

        需要注意的是对于下面的代码,内存如何分配

char arr1[] = "abc";
char arr2[3] = {'a','b','c'};

        这里arr1其实是有四个字符在里面的( “a” “b” “c” “\0” )

        而arr2只有三个字符在里面( “a” “b” “c” )

        1.2 一维数组的使用

        对于整型数组,使用for循环给数组的输入输出很方便

int main()
{
	int i = 0;
	int a[10] = { 0 };//不完全初始化
	for (i = 0; i < 10; i++)
	{
		a[i] = i;
	}
	for (i = 0; i < 10; i++)
	{
		printf("%d ", a[i]);

	}
	printf("\n");
	return 0;
}

        

        再补充一个知识点:

        数组的大小可以通过计算得到:

 sz = sizeo ( a[10] ) / ( a[0] );

        1.3 二维数组的创建和初始化

        一些实例:

int arr[3][4] = {1,2,3,4};
int arr[3][4] = {{1,2},{4,5}};
int arr[][4] = {{2,3},{4,5}};

        需要注意的是在arr[ ][ ]中,第一个“ [ ] ”表示行,第二个“ [ ] ”表示列,他两的下标都和一维数组一样,从0开始

        行可以省略,但是列不行,以为只写列不写行电脑可以帮我们计算出有多少行,但是不写列就无法确定

        1.4 二维数组的使用

        和一位数组类似,请看以下代码:


int main()
{
	int a[3][4] = { 0 };
	int i = 0;
	int j = 0;
	for (i = 0; i < 3; i++)
	{
		for (j = 0; j < 4; j++)
		{
			a[i][j] = i + j;
		}
	}
	for (i = 0; i < 3; i++)
	{
		for (j = 0; j < 4; j++)
		{
			printf("%d ", a[i][j]);
		}
		printf("\n");
	}

	return 0;
}

二、数组作为函数参数

        2.1 冒泡排序

        在我们写程序的过程中经常需要以一个数组为参数传给我们的函数,就以冒泡排序法为例子

        冒泡排序法(升序):第一个数和第二个数比大小,若前一个数大,则这两个数交换,否则这两个数字不变,在用第二个数字和第三个数字比大小,一直循环下去,直到最后一个数字,这样最大的一个数字就能被交换到最后一个,以此类推,第二大的数字在该数组的倒数第二个……直到排到第二个数字。

        例:将以下数组排序:6 1 2 8 4 3 0 9 5 7

void paixu(int arr[])
{
	int sz = arr[10] / arr[0];
	int i = 0;
	int j = 0;
	for (i = 0; i < sz - 1; i++)
	{
		for (j = 0; j < sz - i - 1; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int tmp = arr[i];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
	}
}

int main()
{
	int i = 0;
	int arr[10] = { 6,1,2,8,4,3,0,9,5,7 };
	paixu(arr);
	for (i = 0; i < 10; i++)
	{
		printf("%d", arr[i]);
	}
	return 0;
}

        上面这个代码我们直接把数组传给函数paixu()对吗?

        

        运行之后发现程序毛线都没有换,这是为什么呢?

        经过调试后发现:在paixu()函数中的sz的值为1,说明无法一组的数组直接传给函数

        是因为我们在传参的时候,数组名“arr”只是数组开始的第一个地址,但是数组有多少个,无法传给paixu()函数中

        所以我们现在主函数中把sz算出来,在给他和“arr”一起传给函数paixu(),就能解决这个问题


void paixu(int* arr, int sz)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < sz - 1; i++)
	{
		for (j = 0; j < sz - i - 1; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
	}
}

int main()
{
	int i = 0;
	int arr[10] = { 6,1,2,8,4,3,0,9,5,7 };
	int sz = sizeof(arr) / sizeof(arr[0]);//在这里计算函数大小
	paixu(arr, sz);//这里把函数的大小一起传过去
	for (i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
	return 0;
}


        搞定!

三、三子棋小游戏

        只要知道游戏运行的大体思路,运用选择语句、循环语句、数组、函数已经可以写出一些较为复杂的小游戏了,那么不多废话,开始写我们的第一个小游戏:三子棋

        这里我想用三个文件来实现这个游戏,使得这个游戏的代码更加通俗易懂

        在fox.c文件为游戏运行的整体逻辑,game.cgame.h分别为实现这个游戏运行的代码

        3.1 目录

        和之前猜数字游戏类似,简单的打印出一个目录就行

#define  _CRT_SECURE_NO_WARNINGS 1;
#include"game.h"

void menu()//菜单函数
{
	printf("*********************\n");
	printf("****   1.play    ****\n");
	printf("****   0.exit    ****\n");
	printf("*********************\n");

}

void test()
{
	int input = 0;


	do
	{
       	menu();
		printf("请选择:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("开始游戏\n");
			break;
		case 0:
			printf("游戏结束,下次再见!\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (input);

}

int main()
{
	test();
	return 0;
}

         程序能运行,继续下一步

        3.2 打印棋盘

        棋盘其实就只是一个3*3的格子,所以这里我们需要创建一个二维数组,先给棋盘初始化,在打印棋盘

//初始化棋盘
void init_board(char board[ROW][COL], int row, int col);

//打印棋盘
void print_board(char board[ROW][COL], int row, int col);


void init_board(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++)
		{
			board[i][j] = ' ';
		}
	}
}

void print_board(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 < col - 1)
				printf("|");
		}
		printf("\n");
		if (i < row - 1)
		{
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
					printf("|");
			}
			printf("\n");
		}
	
	}
}

        3.3 玩家下棋

        玩家下棋其实就是将制定坐标改为棋子,这里用星号*代表玩家下的棋

        注意玩家输入的坐标是1 2 3,并不是数组下标的0 1 2 ,这里需要改一下,并且判断下棋的合理性

//玩家下棋
void player_move(char board[ROW][COL], int row, int col)

void player_move(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("玩家下棋\n");
	while (1)
	{
		printf("请输入下棋坐标:");
		scanf("%d %d", &x, &y);
		if (1 <= x && x <= 3 && 1 <= y && y <= 3)
		{
			if (board[x - 1][y - 1] == ' ')
			{
				board[x - 1][y - 1] = '*';
				break;
			}
			else
			{
				printf("该格子已被占用,请重新输入\n");
			}
		}
		else
		{
			printf("非法输入,请重输\n");
		}
	}

}

fox.c中游戏运行逻辑为:


void game()
{
	char board[ROW][COL];
	init_board(board, ROW, COL);//初始化棋盘
	print_board(board, ROW, COL);//打印棋盘
	while (1)
	{
		player_move(board, ROW, COL);//玩家下棋
		print_board(board, ROW, COL);//打印棋盘

	}
}

        3.4 电脑下棋

        让电脑随机生成两个0~2数,作为坐标x y下棋,同样需要判断一下该棋格是否已经有棋子了

//电脑下棋
void computer_move(char board[ROW][COL], int row, int col);


void computer_move(char board[ROW][COL], int row, int col)
{
	while (1)
	{
		int x = rand() % 3;
		int y = rand() % 3;
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
}

        3.5 判断输赢

        这里用一个变量ret来接收判断输赢函数输出的四个信号

        若玩家赢输出:*

        若电脑赢输出;#

        若游戏继输出:C

        若平局输出:P

char is_win(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][2] != ' ')
			return board[i][0];
	}
	//判断列
	for (i = 0; i < col; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[2][i] != ' ')
			return board[0][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 = is_full(board, ROW, COL);
	if (1 == ret)
	{
		return 'P';
	}
	return 'c';
}

此时游戏运行逻辑为:

void game()
{
	char board[ROW][COL];
	char ret = 0;
	init_board(board, ROW, COL);//初始化棋盘
	print_board(board, ROW, COL);//打印棋盘
	while (1)
	{
		player_move(board, ROW, COL);//玩家下棋
		print_board(board, ROW, COL);//打印棋盘
		ret = is_win(board, ROW, COL);//判断输赢
		if (ret != 'C')
		{
			break;
		}
		computer_move(board, ROW, COL);//电脑下棋
		print_board(board, ROW, COL);//打印棋盘
		ret = is_win(board, ROW, COL);//判断输赢
		if (ret != 'C')
		{
			break;
		}
	}
	if (ret == '*')
		printf("玩家赢\n");
	else if (ret == '#')
		printf("电脑赢\n");
	else
		printf("平局\n");
}

        这样游戏就做完啦

        3.6 游戏全代码

        game.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<time.h>



#define ROW 3
#define COL 3

//初始化棋盘
void init_board(char board[ROW][COL], int row, int col);

//打印棋盘
void print_board(char board[ROW][COL], int row, int col);

//玩家下棋
void player_move(char board[ROW][COL], int row, int col);

//电脑下棋
void computer_move(char board[ROW][COL], int row, int col);

//判断输赢
char is_win(char board[ROW][COL], int row, int col);

        game.c

#define  _CRT_SECURE_NO_WARNINGS 1;
#include"game.h"

void init_board(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++)
		{
			board[i][j] = ' ';
		}
	}
}

void print_board(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 < col - 1)
				printf("|");
		}
		printf("\n");
		if (i < row - 1)
		{
			for (j = 0; j < col; j++)
			{
				printf("---");
				if (j < col - 1)
					printf("|");
			}
			printf("\n");
		}
	
	}
}

void player_move(char board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("玩家下棋\n");
	while (1)
	{
		printf("请输入下棋坐标:");
		scanf("%d %d", &x, &y);
		if (1 <= x && x <= 3 && 1 <= y && y <= 3)
		{
			if (board[x - 1][y - 1] == ' ')
			{
				board[x - 1][y - 1] = '*';
				break;
			}
			else
			{
				printf("该格子已被占用,请重新输入\n");
			}
		}
		else
		{
			printf("非法输入,请重输\n");
		}
	}

}

void computer_move(char board[ROW][COL], int row, int col)
{
	while (1)
	{
		int x = rand() % 3;
		int y = rand() % 3;
		if (board[x][y] == ' ')
		{
			board[x][y] = '#';
			break;
		}
	}
}

int is_full(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++)
		{
			if (board[i][j] == ' ')
				return 0;
		}
	}
	return 1;
}

char is_win(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][2] != ' ')
			return board[i][0];
	}
	//判断列
	for (i = 0; i < col; i++)
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[2][i] != ' ')
			return board[0][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 = is_full(board, ROW, COL);
	if (1 == ret)
	{
		return 'P';
	}
	return 'C';
}

        fox.c

#define  _CRT_SECURE_NO_WARNINGS 1;
#include"game.h"

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

}

void game()
{
	char board[ROW][COL];
	char ret = 0;
	init_board(board, ROW, COL);//初始化棋盘
	print_board(board, ROW, COL);//打印棋盘
	while (1)
	{
		player_move(board, ROW, COL);//玩家下棋
		print_board(board, ROW, COL);//打印棋盘
		ret = is_win(board, ROW, COL);//判断输赢
		if (ret != 'C')
		{
			break;
		}
		computer_move(board, ROW, COL);//电脑下棋
		print_board(board, ROW, COL);//打印棋盘
		ret = is_win(board, ROW, COL);//判断输赢
		if (ret != 'C')
		{
			break;
		}
	}
	if (ret == '*')
	{
		printf("玩家赢\n");
	}
	else if (ret == '#')
	{
		printf("电脑赢\n");
	}
	else
	{
		printf("平局\n");
	}

}

void test()
{
	srand((unsigned int)time(NULL));
	int input = 0;
	do
	{
		menu();
		printf("请选择:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			printf("开始游戏\n");
			game();
			break;
		case 0:
			printf("游戏结束,下次再见!\n");
			break;
		default:
			printf("输入错误,请重新输入\n");
			break;
		}
	} while (input);

}

int main()
{
	test();
	return 0;
}

        3.7 Ps

        这里的电脑是纯纯的人机,纯人工智障,他不会思考,如果你想让电脑聪明一点可以私信我,还有就是你可以在加一个玩家一对战玩家二的模式,想要的评论呀

        都看到这里啦,还不给个赞吗??!

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值