我正在为我的大学项目编写一个战舰游戏,我想在游戏开始时随机化战舰的位置。我的程序有一个 Ship 的抽象超类,它分支为四种不同类型的其他船只:
每艘船都有不同的“攻击类型”,因此使用子类。
我现在正处于编写代码的早期阶段,感觉我面临一些问题
如何高效地实例化船舶对象? 到目前为止,感觉好像我需要编写 4 种不同的方法来创建每个船舶对象并将其放置在板上
如何才能使船只不能位于彼此相邻的一个街区内? (这样船就不能互相接触,也不能互相重叠)
到目前为止,我只写了一个创建“航母”船的方法
private void placeCarrier(char[][] selfGrid, int shipOrientation) {
int xCor, yCor;
boolean isShipPlaced = false;
do {
// Randomize starting coordinates
xCor = (int) (Math.random() * 9) + 1;
yCor = (int) (Math.random() * 9) + 1;
// Checking ship orientation and ensuring that the end value is not out of bounds
if (shipOrientation == VERTICAL && yCor + Carrier.CARRIER_LENGTH < BattleshipSystem.GRID_LENGTH) {
playerShips[0] = new Carrier(xCor, yCor, xCor, yCor + Carrier.CARRIER_LENGTH);
// Updates the char array
for (int y = yCor; y < yCor + Carrier.CARRIER_LENGTH; y++) {
selfGrid[y][xCor] = SHIP;
}
isShipPlaced = true;
}
else if (shipOrientation == HORIZONTAL && xCor + Carrier.CARRIER_LENGTH < BattleshipSystem.GRID_LENGTH) {
playerShips[0] = new Carrier(xCor, yCor, xCor + Carrier.CARRIER_LENGTH, yCor);
for (int x = xCor; x < xCor + Carrier.CARRIER_LENGTH; x++) {
selfGrid[yCor][x] = SHIP;
}
isShipPlaced = true;
}
}
while (!isShipPlaced);
// Use of "do-while" loop in order to continuously randomize coordinates until they are valid and in bounds of the grid array
}
这是我编写的在网格上放置一艘“航母”的代码,我编写了一个类似的方法在网格上创建一艘“战舰”,但最终发生的情况是这些船彼此重叠或相邻彼此(我不想要),但我不知道我应该如何进行错误检查以确保满足我的条件。
另外,我真的很担心,因为这个方法已经非常长了,我不想为每种类型的船舶编写多个方法。
让我们分部分来说,没有“正确”的方法来做到这一点,你没有提供太多信息(你没有做出相关决定),即便如此,我也会允许你提出建议,做一个简单的船 类,类似这样:
class Ship {
int size;
int id;
static int number = 0;
Atack atackType;
public Ship() {
id = number ++;
}
// getters and setters
}
class Carrier extends Ship {
int size = 5;;
Atack atackType = Atack.airAtack;
public Ship() {
super();
}
}
并将船舶的管理和位置留给 Board 类(在我的示例中是一个数组),因为攻击可能会针对 Cell 对象。
要知道它是否可以被放置在确定的位置,我们必须验证它要占据的所有位置以及周围的所有位置都是空的,图形上是这样的:
// #######
// #55555#
// #######
是船的“5”部分和“#”周围的方块
第一个方法负责将船只放置在棋盘上,其他方法是辅助的。
// get the size of the board and an array with the ships
String[][] locateBoats( int side, String ships[][] ) {
String board[][] = new String[ side ][ side ];
fill( board );
int which = 0;
Random Ram = new Random();
int size = board[ 0 ].length;
// each row of the matrix, represents a boat
while( which < ships.length ) {
// we determine if it goes horizontally or vertically
int direction = Ram.nextInt( 2 );
int sizeBoat = ships[ which ].length;
// we generate the initial position within the allowed range
int x = Ram.nextInt( size - sizeBoat +1 );
int y = Ram.nextInt( size - sizeBoat +1 );
// “sizeI” and “sizeK” take the value of the side of the rectangle we
// need to verify, for height and width respectively.
// “upI” and “upK” are used to know (at the time of printing the ship,
// in which direction to go, “k” and “i” are the positions from which to // start iterating.
// it starts iterating
int sizeI = 3, sizeK = 3, k = x -1, i = y -1, upK = 0, upI = 0;
// this part of the code is in charge of instantiating the values of the variables,
// depending on the direction, if we are in horizontal, the height
// should be “3”, unless “y” is zero, in which case it should be “2”,
// the width should be equal to the length of the ship plus “2”, unless “x”
// is “0” in which case it should be ship length + “1”.
if( direction == 0 ) { // horizontal
sizeK += boat size - 1;
upK = 1;
}
else {
sizeI += sizeBoat - 1;
upI = 1;
}
if( x == 0 ) {
k = x;
sizeK -= 1;
}
if( y == 0 ) {
i = y;
sizeI -= 1;
}
boolean reset = false;
// we use this variable as memory to store the value of “k”.
int mem = k;
// we create the stopping conditions of the for
int conditionI = i + sizeI;
int conditionK = k + sizeK;
for( ; i < conditionI && i < size; i++ ) {
k = mem;
for( ; k < conditionK && k < size; k++ ) {
// if the position is not empty, we set “reset” to “true” to
// prevent it from recording the ship and exit the internal for.
if( ! board[ i ][ k ].equals( “ ” )) {
restart = true;
break;
}
}
}
// if it did not find occupied positions, it enters the if, takes the value of
// the letter of the ship, and modifies the value contained in the positions
if( !restart ) {
String letter = ships[ which ][ 0 ];
for( i = y, k = x; i < y + sizeBoat && k < x + sizeBoat; i += subei, k += subek ) {
board[ i ][ k ] = letter;
}
which++;
}
}
return board;
}
void fill( String array[][] ) {
for( int i = 0; i < array.length; i++ ) {
for( int j = 0; j < array.length; j++ ) {
array[ i ][ j ] = “ ”;
}
}
}
String ships[][] = {
{ “5”, “5”, “5”, “5”, “5” }, { “4”, “4”, “4”, “4”, },
{ “4”, “4”, “4”, “4”, }, { “3”, “3”, “3” }, { “3”, “3”, “3” },
{ “3”, “3”, “3” }, { “2”, “2” }, { “2”, “2” }, { “2”, “2” }, { “2”, “2” }
};
注意:如果你使用较小的棋盘尺寸(相对于船只的数量和长度),你很可能会进入无限循环......小心,或者为 while 的迭代添加一个限制,用我们上面的船舶矩阵,“15x15”板不会产生问题,因为我们缩小了边......