我感到很无聊所以我创建了一个小型的控制台扫雷游戏,在编写它时,我必须找到一个尺寸*大小矩阵中元素的邻居位置,它表示为元素向量和一个变量,用于保存大小值。我不想返回邻居元素的实际值,而是返回它们的位置,以便我可以将其用作公共函数(否则客户端可以看到地雷的位置:P)。
例如,对于字段eq 0和size eq 3,函数应返回{1,3,4}:
1 0 0 0 1 0
0 0 0 => 1 1 0
0 0 0 0 0 0
好吧,基本上它看起来像这样:
vector<int> adjecantPositions(int field, int size)
{
int row = field / size;
int col = field % size;
vector<int> result;
/*
1 0 0
1 0 0
1 0 0
*/
if (col > 0)
{
result.push_back(calcField(row, col-1, size));
if (row > 0)
result.push_back(calcField(row-1, col-1, size));
if (row < size - 1)
result.push_back(calcField(row+1, col-1, size));
}
/*
0 0 1
0 0 1
0 0 1
*/
if (col < size - 1)
{
result.push_back(calcField(row, col+1, size));
if (row > 0)
result.push_back(calcField(row-1, col+1, size));
if (row < size - 1)
result.push_back(calcField(row+1, col+1, size));
}
/*
0 1 0
0 0 0
0 1 0
*/
if (row > 0)
result.push_back(calcField(row-1, col, size));
if (row < size - 1)
result.push_back(calcField(row+1, col, size));
return result;
}
calcField(int,int,int)只是将坐标转换为字段编号(行*大小+ col)。
这是一个快速的解决方案,但它并不优雅,我打赌有更好的方法来做到这一点。有什么想法吗?
答案 0 :(得分:1)
是的,你的代码很糟糕。这是一个更好的尝试(固定,对不起):
for (int dx=-1; dx<=1; dx++)
for (int dy=-1; dy<=1; dy++)
if (dx || dy){
int x = row+dx, y=col+dy;
if (x >= 0 && x < size && y >= 0 && y < size)
result.push_back(calcField(x, y, size));
}
答案 1 :(得分:1)
为什么不使用对象作为坐标?我认为这将更具可读性:
struct Coords
{
int row;
int col;
Case(row, col) : row(row), col(col) {}
bool isValid(int size)
{
return row >= 0 && col >= 0 && row < size && col < size;
}
}
vector<Coords> adjecantPositions(const Coords & field, int size)
{
vector<Coords> result;
for( int drow = -1; drow <= 1; ++drow )
{
for( int dcol = -1; dcol <= 1; ++dcol )
{
Coords current(field.row + drow, field.col + dcol);
if( current.isValid(size) )
{
result.push_back(current);
}
}
}
return result;
}
答案 2 :(得分:0)
以下是Pavel解决方案的固定代码:
for (int drow = -1; drow <= 1; drow++)
{
int rrow = row + drow;
for (int dcol = -1; dcol <= 1; dcol++)
{
int rcol = col + dcol;
if (rrow >= 0 && rrow < size && rcol >= 0 && rcol < size
&& !(rrow == row && rcol == col))
result.push_back(calcField(rrow, rcol, size));
}
}