目次
序文
私自身も初心者ですが、他の偉い人のコードを学ぶと、いつもいくつかの問題に遭遇します。コードは難解すぎて初心者には理解できません。そこで、「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. 試験状況
テストしましたが、問題ないはずです。バグやその他の質問がある場合は、コメント エリアにメッセージを残してください。