【C语言】三子棋升级五子棋(适合初学者,图文并茂超详细)

目录

一、实现思路

1.棋盘大小的改动

2.判断输赢函数的改动

(1)行

(2)列

(3)“\”方向对角线

(4)“/”方向对角线

二、实现代码+注释解析

三、测试情况


前言

        我自己就是一个初学者,但是在我学习其他大佬的代码时,总会遇到一些问题:代码太深奥初学者难以理解;程序有问题没有解决;讲解不细致只是单纯把代码贴上来。所以我自己写了一篇博客来仔细讲解一下《三子棋升级五子棋》这个问题。


三子棋的讲解(没有学过三子棋的同学可以先看这个):【C语言】简易版三子棋(附源码)_字节连结的博客-CSDN博客

分析:三子棋改为五子棋只需改动棋盘大小判断输赢函数即可。

一、实现思路

1.棋盘大小的改动

#define ROW 10	//棋盘的行数
#define COL 10	//棋盘的列数

之前用#define定义行数列数的好处就体现出来了,可以很方便的随时修改。

2.判断输赢函数的改动

(1)行

假设有一个6行6列(row=6,col=6)的棋盘,那么一行中有五个相连且相同棋子的可能性有以下两种:

我们要找到坐标(0,0)和(0,1)上的棋子

然后拿这个棋子跟后面四个棋子作比较,如果五个棋子全部相同且不是空格,则宣布有人获胜(“X”是玩家,“O”是电脑)

然而这只是一行的情况,根据实际棋盘的大小,每一行都要用这种方式判断

若把 i 当作行 j 当作列,那么 i 的范围就是0~5,而 j 的范围是0~1

写成代码的形式:

    //假设棋盘是6行6列,row=6,col=6
	for (i = 0; i < row; i++)    //0~5
	{
		for (j = 0; j < col - 4; j++)    //0~1
		{
			if (board[i][j] == board[i][j + 1] &&
				board[i][j + 1] == board[i][j + 2] &&
				board[i][j + 2] == board[i][j + 3] &&
				board[i][j + 3] == board[i][j + 4] &&
				board[i][j] != ' ')
			{
				return board[i][j];
			}
		}
	}

图形形式:

黄色区域就是被遍历的区域

(2)列

原理同上,只需修改一下 for 循环中 i 和 j 的范围和循环内的判断条件即可。

代码形式:

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

图形形式:

黄色区域即被遍历的区域

(3)“\”方向对角线

假设有一个6行6列(row=6,col=6)的棋盘,那么“\”方向的斜对角线中有五个相连且相同棋子的可能性有以下四种:

可以发现一个规律,他们的起始位置总是在左上角的一片区域中,那么:

代码形式:

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

图形形式: 

黄色区域即被遍历的区域

(4)“/”方向对角线

假设有一个6行6列(row=6,col=6)的棋盘,那么“/”方向的斜对角线中有五个相连且相同棋子的可能性同样有以下四种:

这次五颗棋子的起始位置总是在右上角,则:

代码形式:

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

图形形式:

黄色区域即被遍历的区域

至于平局和继续的情况,跟之前的三子棋是一样的,在这里就不多赘述。

二、实现代码+注释解析

//判断棋盘是否被占满
//未占满 --- 0
//占  满 --- 1
int IsFull(char board[ROW][COL], int row, int col)
{
	int i, j;
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col; j++)
		{
			if (board[i][j] == ' ')
				return 0;
		}
	}
	return 1;
}

//判断输赢 --- 五子棋的判断
char IsWin(char board[ROW][COL], int row, int col)
{
	int i, j;
	//判断每行有五个相同的棋子
	//假设有6列,COL=col=6,每行五子相同有以下两种可能性
	// 0 1 2 3 4 5 (列的下标)
	// X X X X X		(把“X”当作棋子)
	//   X X X X X
	//我们要拿五个棋子中的【第一个棋子】去跟【后面的四个棋子】比较一下是否相同
	//可以看到j的范围在0~1之间,也就是:for (j = 0; j < col - 4; j++)
	for (i = 0; i < row; i++)
	{
		for (j = 0; j < col - 4; j++)
		{
			if (board[i][j] == board[i][j + 1] &&
				board[i][j + 1] == board[i][j + 2] &&
				board[i][j + 2] == board[i][j + 3] &&
				board[i][j + 3] == board[i][j + 4] &&
				board[i][j] != ' ')
			{
				return board[i][j];
			}
		}
	}
	//判断每列有五个相同的棋子
	//原理同上,i的范围:for (i = 0; i < row - 4; i++)
	for (j = 0; j < col; j++)
	{
		for (i = 0; i < row - 4; i++)
		{
			if (board[i][j] == board[i + 1][j] &&
				board[i + 1][j] == board[i + 2][j] &&
				board[i + 2][j] == board[i + 3][j] &&
				board[i + 3][j] == board[i + 4][j] &&
				board[i][j] != ' ')
			{
				return board[i][j];
			}
		}
	}
	//判断\方向有五个相同的棋子
	//假设有6行6列,有以下四种可能性
	//   0 1 2 3 4 5  |    0 1 2 3 4 5
	// 0 X X          |  0
	// 1   X X        |  1 X X
	// 2     X X      |  2   X X
	// 3       X X    |  3     X X
	// 4         X X  |  4       X X
	// 5              |  5         X X
	//由于我们要拿五个棋子中的【第一个棋子】去跟【后面的四个棋子】比较
	//所以(i,j)的可能取值:(0,0) (0,1) (1,0) (1,1)
	for (i = 0; i < row - 4; i++)
	{
		for (j = 0; j < col - 4; j++)
		{
			if (board[i][j] == board[i + 1][j + 1] &&
				board[i + 1][j + 1] == board[i + 2][j + 2] &&
				board[i + 2][j + 2] == board[i + 3][j + 3] &&
				board[i + 3][j + 3] == board[i + 4][j + 4] &&
				board[i][j] != ' ')
			{
				return board[i][j];
			}
		}
	}
	//判断/方向有五个相同的棋子
	//假设有6行6列,同样有以下四种可能性
	//   0 1 2 3 4 5  |    0 1 2 3 4 5
	// 0         X X  |  0
	// 1       X X    |  1         X X
	// 2     X X      |  2       X X
	// 3   X X        |  3     X X
	// 4 X X          |  4   X X
	// 5              |  5 X X
	//(i,j)的可能取值:(0,4) (0,5) (1,4) (1,5)
	for (i = 0; i < row - 4; i++)
	{
		for (j = 4; j < col; j++)
		{
			if (board[i][j] == board[i + 1][j - 1] &&
				board[i + 1][j - 1] == board[i + 2][j - 2] &&
				board[i + 2][j - 2] == board[i + 3][j - 3] &&
				board[i + 3][j - 3] == board[i + 4][j - 4] &&
				board[i][j] != ' ')
			{
				return board[i][j];
			}
		}
	}
	//平局(棋盘被占满还未分出胜负)
	if (IsFull(board, row, col) == 1)
	{
		return 'Q';
	}
	//继续
	return 'C';
}

三、测试情况

我测试下来应该是没问题的,有bug或其他问题请在评论区留言。

猜你喜欢

转载自blog.csdn.net/m0_73156359/article/details/131117019