我想检查C#中3x3 2D矩阵在井字游戏中的获胜情况。我有以下结构:
public struct GridCoordinates {
public int row;
public int column;
}
为了检查板上的所有行,行和对角线,我可以执行以下操作。我可以创建一个预先计算的
List<List<GridCoordinates>>
,其中内部列表是3个坐标的集合,每个坐标代表行,列或对角线。但是,当我考虑使用List<List<GridCoordinates>>
初始化new
多长时间时,我开始认为在C#中应该有更好的方法。请建议如何优雅地填充该预先计算的坐标。我的BG来自C++,在这里我可以做这样的事情:
#include <iostream>
#include <vector> using namespace std;
struct GridCoordinates {
int i;
int j;
};
vector<vector<GridCoordinates>> vec{
{{0,0}, {0,1}, {0, 2}}
};
int main() { std::cout << vec[0][2].j; }
优雅吧?
最佳答案
您可以将(X,Y)元组的二维数组声明为类中的字段,如下所示:
static readonly (int X, int Y)[,] winningLines =
{
{(0, 0), (0, 1), (0, 2)},
{(0, 0), (1, 1), (2, 2)},
{(0, 0), (1, 0), (2, 0)},
{(0, 1), (1, 1), (2, 1)},
{(0, 2), (1, 2), (2, 2)},
{(1, 0), (1, 1), (1, 2)},
{(2, 0), (1, 2), (2, 2)},
{(0, 2), (1, 1), (2, 0)}
};
这使得声明数组非常简洁。但是,访问它仍然很冗长,例如:
using System;
namespace Demo
{
class Program
{
static void Main()
{
Console.WriteLine(isWinFor('X')); // false
Console.WriteLine(isWinFor('O')); // false
board[0, 0] = 'X';
board[1, 1] = 'X';
board[2, 2] = 'X';
Console.WriteLine(isWinFor('X')); // true
Console.WriteLine(isWinFor('O')); // false
}
static bool isWinFor(char player)
{
for (int line = 0; line < winningLines.GetUpperBound(0); ++line)
{
bool won = true;
for (int coord = 0; coord < 3; ++coord)
{
var p = winningLines[line, coord];
if (board[p.X, p.Y] != player)
won = false;
}
if (won)
return true;
}
return false;
}
static readonly char[,] board = new char[3,3];
static readonly (int X, int Y)[,] winningLines =
{
{(0, 0), (0, 1), (0, 2)},
{(0, 0), (1, 1), (2, 2)},
{(0, 0), (1, 0), (2, 0)},
{(0, 1), (1, 1), (2, 1)},
{(0, 2), (1, 2), (2, 2)},
{(1, 0), (1, 1), (1, 2)},
{(2, 0), (1, 2), (2, 2)},
{(0, 2), (1, 1), (2, 0)}
};
}
}
(注意:元组支持需要C#7.0或更高版本。)