[C言語] SanbangからGobangへのアップグレード(初心者向け、非常に詳細な画像とテキスト付き)

目次

1. 実装アイデア

1. チェス盤のサイズ変更

2.勝敗判定機能の変更

(1)行

(2)列

(3) 「\」方向斜め

(4) 「/」方向斜め

2. コード+コメント解析の実装

3. 試験状況


序文

        私自身も初心者ですが、他の偉い人のコードを学ぶと、いつもいくつかの問題に遭遇します。コードは難解すぎて初心者には理解できません。そこで、「Sanziqi から Gobang をアップグレードする」問題を詳しく説明するブログを自分で書きました。


三月チェスの解説(三月チェスを習ったことがない人は先に読んでください):【C言語】三月チェスの簡易版(ソースコード付き)_Byte Link Blog-CSDN Blog

分析:サンバンからゴバンへの変更は、ボードのサイズ勝敗を判断する機能を変更するだけで済みます

1. 実装アイデア

1. チェス盤のサイズ変更

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

#define を使用して行数と列数を事前に定義する利点が反映されており、いつでも簡単に変更できます。

2.勝敗判定機能の変更

(1)行

6 行 6 列 (行 = 6、列 = 6) のチェス盤があると仮定すると、次のように 5 つの同じ駒が連続して並んでいる可能性が 2 つあります。

座標 (0, 0) と (0, 1) にあるピースを見つけたいとします。

次に、このピースを次の 4 つのピースと比較し、5 つのピースがすべて同じでスペースでない場合、誰かが勝者と宣言されます (「X」はプレーヤー、「O」はコンピューター)

ただし、これは1ラインの場合であり、実際のチェス盤の大きさに応じて、各ラインをこのように判断する必要があります。

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 列 (行 = 6、列 = 6) のチェス盤があると仮定すると、次のように、"\"方向の対角線に接続された 5 つの同一のチェスの駒の可能性が 4 つあります。

開始位置は常に左上隅の領域にあるという規則がわかります。その場合、次のようになります。

コード形式:

	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 列 (行 = 6、列 = 6) のチェス盤があると仮定すると、「/」方向の対角線上にある 5 つの同一のチェスの駒が接続されている場合、次の 4 つの可能性もあります。

今回は、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];
			}
		}
	}

グラフィック形式:

黄色のエリアが通過するエリアです

引き分けと継続の状況については、先ほどの3つなぎチェスと同じなので、ここでは詳しく説明しません。

2. コード+コメント解析の実装

//判断棋盘是否被占满
//未占满 --- 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';
}

3. 試験状況

テストしましたが、問題ないはずです。バグやその他の質問がある場合は、コメント エリアにメッセージを残してください。

おすすめ

転載: blog.csdn.net/m0_73156359/article/details/131117019