基本上我有一些类型为Ship的结构,它们将放在可以具有可变宽度和高度的板上。有关船只的信息是从文件中读取的,我只需要知道确保没有任何船只重叠的最佳方法。
这是Ship的结构:
int x // x position of first part of ship
int y // y position of first part of ship
char dir // direction of the ship, either 'N','S','E' or 'W'
int length // length of the ship
此外,处理方向的好方法是什么。比使用switch语句更清洁,并为每个方向使用不同的条件。
非常感谢任何帮助!
答案 0 :(得分:6)
您可以保留整个网格的布尔数组,最初初始化为“false”。对于每艘船,对于船舶所覆盖的每个位置,检查该位置是否为“假”。如果是, 将其设置为“true”。如果没有,那么其他一些船就在这个位置上。
该算法在所有船舶的总面积上是线性的,但也需要额外的空间 与电路板上的位置数量成正比。
答案 1 :(得分:1)
这与测试矩形是否相交是一回事,我认为如果你不认为这些船只是一个点,长度和方向而是一个矩形,你的代码会更简单。
所以转换此
int x // x position of first part of ship
int y // y position of first part of ship
char dir // direction of the ship, either 'N','S','E' or 'W'
int length // length of the ship
到此(允许负cx& cy得到N,S,E,W)
int x // x position of first part of ship
int y // y position of first part of ship
int cx // length of the ship in X
int cy // length of the ship in Y
或者
int left // x position of Eastern part of the ship
int top // y position of Northernmost part of ship
int right // x position of Westernmost part of the ship
int bottom // y position of Southernmost part of ship
bool orientation; // so we can tell East from West or North from South.
然后一个简单的函数可以确定两艘船是否相交。
bool DoShipsIntersect(Ship * a, Ship * b)
{
if ((a->right < b->left) || (b->right < a->left))
return false;
if ((a->bottom < b->top) || (b->bottom < a->top))
return false;
return true;
}
只要您没有数千艘船只,每艘船与其他船舶的强力比较应该非常快。
答案 2 :(得分:0)
除非你有很多船只,否则只需使用一个简单的强力算法,它将是两个嵌套循环,即O(n ^ 2)。
答案 3 :(得分:0)
保留电路板的位图,其中每个位指示是否有一艘船占用该区块。对于每个船舶标记它在板上占用的瓷砖,并检查是否标记了相同的位两次。
答案 4 :(得分:0)
(战舰?)
制作一个2D阵列(“板”),其中包含船舶的ID。因此,当您添加船时,您可以在O(长度)时间内检查空间是否被占用。
O(n *长度)时间,O(N ^ 2)空间。
答案 5 :(得分:0)
表示方向的一种方式是单位向量。这可以是2个整数:dirX和dirY。例如。东方dirX = 1;南方的dirY = 1。
然后,您可以使用以下符号迭代船舶占用的所有位置:
int cx = x;
int cy = y;
for(int i = 0; i < length; i++) {
cx += dirX;
cy += dirY;
}
或者根据这些值得到一个边界框:
x
y
x + dirX * (length - 1)
y + dirY * (length - 1)
答案 6 :(得分:0)
您可能希望为方向使用枚举类型。在查找重叠方面,为您的电路板创建一个初始化为false的二维布尔数组。然后,对于每艘船,在阵列中找到相应的条目,如果它们已经为真,则表示您有重叠。否则,将这些条目设置为true。如果您已经放置了所有船只并且没有遇到已经真实的条目,那么就没有重叠。