C语言之井字棋

井字棋

  • 什么是井字棋
  • 井字棋所要包含的内容
        • 基本框架
        • 菜单的实现;
        • 初始化棋盘
        • 打印棋盘
        • 玩家下棋
        • 电脑无脑下棋
        • 判断输赢
        • 完整代码

什么是井字棋

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

C语言之井字棋_第1张图片

井字棋所要包含的内容

基本框架

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

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函数就可以轻松搞定

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

`

初始化棋盘

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

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循环,而要注意的是我们为了方便玩家观看应该”画“上格子,| —,

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");

	}
}

玩家下棋

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

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");
		}
	}
}

电脑无脑下棋

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


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判断就行了。除此之外便是平局。

//我希望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';
}

完整代码

完整代码gitee

你可能感兴趣的:(c语言,开发语言)