如何在战舰游戏中随机化舰船位置?

问题描述 投票:0回答:1

我正在为我的大学项目编写一个战舰游戏,我想在游戏开始时随机化战舰的位置。我的程序有一个 Ship 的抽象超类,它分支为四种不同类型的其他船只:

  • 承运人(占5个车位)
  • 战舰(占4个位)
  • 潜水艇(占3个位)
  • 巡逻艇(占2个位)

每艘船都有不同的“攻击类型”,因此使用子类。

我现在正处于编写代码的早期阶段,感觉我面临一些问题

  1. 如何高效地实例化船舶对象? 到目前为止,感觉好像我需要编写 4 种不同的方法来创建每个船舶对象并将其放置在板上

  2. 如何才能使船只不能位于彼此相邻的一个街区内? (这样船就不能互相接触,也不能互相重叠)

到目前为止,我只写了一个创建“航母”船的方法

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
}

这是我编写的在网格上放置一艘“航母”的代码,我编写了一个类似的方法在网格上创建一艘“战舰”,但最终发生的情况是这些船彼此重叠或相邻彼此(我不想要),但我不知道我应该如何进行错误检查以确保满足我的条件。

另外,我真的很担心,因为这个方法已经非常长了,我不想为每种类型的船舶编写多个方法。

java random subclass
1个回答
0
投票

让我们分部分来说,没有“正确”的方法来做到这一点,你没有提供太多信息(你没有做出相关决定),即便如此,我也会允许你提出建议,做一个简单的 类,类似这样:

    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”板不会产生问题,因为我们缩小了边......

© www.soinside.com 2019 - 2024. All rights reserved.