C语言之井字棋

2024-01-22 21:34:44 浏览数 (2)

什么是井字棋

井字棋,英文名叫Tic-Tac-Toe,是一种在3*3格子上进行的连珠游戏,和五子棋类似,由于棋盘一般不画边框,格线排成井字故得名。游戏需要的工具仅为纸和笔,然后由分别代表O和X的两个游戏者轮流在格子里留下标记(一般来说先手者为X),任意三个标记形成一条直线,则为获胜。

井字棋所要包含的内容

基本框架

我们把该游戏分为逻辑的测试和游戏的实现,分别用两个源文件和一个同文件来实现。 作为一个游戏起码要玩家来决定游戏的开始或结束一直按f5显然不够优雅所以我们使用一个do while循环来实现这一功能 也就是

代码语言:javascript复制
void text()
{
	
	int a = 0;
	do {
		//1,游戏开始
		//0:游戏结束
		scanf("%d", &a);
		switch (a)
		{
		case 1:
			game();
			break;
		case 0:
			printf("游戏结束");
			break;
		default:
			printf("输入错误,请重新输入n");
			break;
		}
	} while (a);
}
菜单的实现;

通知玩家1,游戏开始 0:游戏结束,其实就是菜单函数应该有的功能使用printf函数就可以轻松搞定

代码语言:javascript复制
void menu()
{
	printf("*****************************n");
	printf("********   1. play     ******n");
	printf("********   0. eixt     ******n");
	printf("*****************************n");
}

`

初始化棋盘

存放棋盘数据很明显是一个二维数组所以我们先创建一个二维数组int board[ROW][COL];这里的行数和列数我们采用全局变量的形式定义在game.h中,方便日后对与棋盘大小的修改。然后将board的数组,行数,列数传入初始化棋盘的函数之中,

代码语言:javascript复制
void init_board(char board[ROW][COL], int row, int col)
{
	int i;
	for (i = 0; i < row; i  )
	{
		int j;
		for (j = 0; j < col; j  )
		{
			board[i][j] = ' ';
		}
	}

注:ROW,COL是我们定义的全局变量,而函数声明中要写的应该是变量。

打印棋盘

打印棋盘和初始化其实差不多,都是两个for循环,而要注意的是我们为了方便玩家观看应该”画“上格子,| —,

代码语言:javascript复制
void print_board(char board[ROW][COL], int row, int col)
{
	int i;
	for (i = 0; i < row; i  )
	{
		int j;
		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");

	}
}
玩家下棋

在这里我们要考虑的是所下坐标是否有效,及是否是重复下棋或是下到棋盘外,而在下错后我们应该重新进行下棋

代码语言:javascript复制
void player_move(char board[ROW][COL], int row, int col)
{
	printf("玩家下棋:n");
	while (1)
	{
		printf("请输入你要下的棋的坐标n");
		int x = 0;
		int y = 0;
		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("该坐标被占用,请重新输入n");
			}
		}
		else//坐标非法
		{
			printf("坐标非法n");
		}
	}
}
电脑无脑下棋

为什么说是无脑呢因为电脑下的棋是随机的,随机数的生成可以观看我之前的猜数字文章

代码语言:javascript复制
void computer_move(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;
		}
	}

}
判断输赢

三子棋的判断方式无非竖,横,斜三种方式只需要if判断就行了。除此之外便是平局。

代码语言:javascript复制
//我希望is_full这个函数只是为了支持is_win函数的,只是在is_win函数内部使用
//那我们就没必要在头文件中声明
// 
//判断棋盘是否满了
static int is_full(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;
}

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][0] != ' ')
		{
			return board[i][0];
		}
	}
	//判断三列
	for (i = 0; i < col; i  )
	{
		if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][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];
	}

	//平局?
	if (is_full(board, row, col) == 1)
	{
		return 'Q';
	}

	//继续
	//没有玩家或者电脑赢,也没有平局,游戏继续
	return 'C';
}

0 人点赞