这是我为战舰游戏放置船只的代码:
static void placeShips()
{
Random r = new Random();
int[] ships = {5, 4, 3, 3, 2};
for(int i = 0; i < ships.length; i++)
{
int direction = r.nextInt(2);
loop: switch(direction)
{
//Down
case 0:
int spot1 = r.nextInt(10 - (ships[i]+1));
int spot2 = r.nextInt(10);
for(int j = 0; j < ships[i]; j++)
if(boardArray[spot1 + j][spot2] != 0)
{
i--;
break loop;
}
for(int j = 0; j < ships[i]; j++)
boardArray[spot1 + j][spot2] = 1;
break;
//Right
case 1:
spot1 = r.nextInt(10);
spot2 = r.nextInt(10 - (ships[i]+1));
for(int j = 0; j < ships[i]; j++)
if(boardArray[spot1][spot2 + j] != 0)
{
i--;
break loop;
}
for(int j = 0; j < ships[i]; j++)
boardArray[spot1][spot2 + j] = 1;
break;
}
}
}
有人知道一种可靠的测试方法吗?它尚未完成,但基本上数组是10x10(全部为0)并且它使用此公式将船放置在数组boardArray上。不断重新运行程序有点烦人,是否有更快的方式100%确定它们不会重叠?
通常情况下,如果我没有看到问题,我会测试并将其打开,但这个游戏算作我的最终版本所以我希望它尽可能接近完美
答案 0 :(得分:1)
测试它的最可靠方法是编写一些unit tests。谷歌有一句口头禅"Debugging sucks, testing rocks"。
使代码变得可测试的最重要的变化是使其具有确定性。
从根本上说,代码的输出由两件事决定:
r
; boardArray
。如果您可以控制这两件事,那么每次运行代码时,您的代码应该完全相同。这意味着每次测试时它都会完全相同。
能够控制这些的最简单方法是将两者作为方法参数传递:
static void placeShips(int[][] boardArray, Random r) {
// Don't create r inside the method.
// ... Rest of the method.
}
这样做是为了将placeShips
的工作与你所拥有的static int[][] boardArray
的静态状态以及在方法中创建Random
的非确定性分离开来
现在你处于更好的状态:你可以(并且应该)编写JUnit测试;但您现在可以从任何地方调用placeShip
,例如一个main(String[])
方法:
int[][] boardArray = new int[10][10]; // Guaranteed to be full of zeros.
Random r = new Random(0); // Seeded with 0, so it always generates the same numbers.
placeShips(boardArray, r);
// Now check the contents of boardArray are what you expect.
你应该在placeShips
中拆分逻辑以创建“测试接缝”:它目前是一个非常大的方法,你可以测试的是boardArray
在特定的地方有特定的元素。我不打算如何拆分它,但这是你应该考虑的事情。