Naval fight. How is it right to untie ships?



  • Trying to write a simple sea fight on Java. Everything was almost done, except for the right algorithm of the ship's place on the map. The code describes where the problem is.

    public class Main {
    public static void main(String[] args) {
        Random rand = new Random();
        Field field = new Field();
        Player player = new Player();
        player.getName();
        field.init();
        final int NUMBEROFSHIPS =10;
        Ship [] ships = new Ship[NUMBEROFSHIPS];
        for (int i = 0; i < NUMBEROFSHIPS; i++) {
            boolean isShipSettedUp = false;
            do { //вот здесь проблемы
                 //корабли расставляются рандомно на свободное место на карте
                // получается так, что для последних кораблей не хватает 
               //места и идет зацикливание 
               //Ship(координата Х, координата У,  размер, вертикален ли)
                if (i <=3) ships[i] = new Ship(rand.nextInt(10), rand.nextInt(10), 1, false);
                if (i >3 && i <=6) ships[i] = new Ship(rand.nextInt(10), rand.nextInt(10), 2, false);
                if (i >6 && i <= 8) ships[i] = new Ship(rand.nextInt(10), rand.nextInt(10), 3, false);
    
            if (i &gt; 8 &amp;&amp; i &lt;=9) ships[i] = new Ship(rand.nextInt(10), rand.nextInt(10), 4, false);
            if (field.isCanSetShip(ships[i])) {
                field.setShip(ships[i]);
                isShipSettedUp =true;
           }
        } while(!isShipSettedUp);
    }
    System.out.println("Game start!");
    do {
        field.show();
        System.out.println("Where to shoot?");
        System.out.println("Enter column: ");
        int shootX = player.getShoot();
        System.out.println("Enter row: ");
        int shootY = player.getShoot();
        Shoot shoot = new Shoot(shootX,shootY);
        field.doShoot(shoot);
    } while (field.isNotGameOver());
    

    }
    }

    Field:

    public class Field {
    final int FIELDSIZE = 10;
    char[][] cells = new char[FIELDSIZE][FIELDSIZE];
    Ship ship;
    void init() {
    for (int i = 0; i < FIELDSIZE; i++) {
    for (int j = 0; j < FIELDSIZE; j++) {
    cells[i][j] = '.';
    }
    }
    }
    void setShip(Ship ship) { //помечаю ячейку в массиве, что здесь корабль
    this.ship = ship;
    if (ship.isVertical) {
    for (int i = 0; i < ship.size; i++) {
    cells[ship.positionX + i][ship.positionY] = 'X';
    }
    } else {
    for (int i = 0; i < ship.size; i++) {
    cells[ship.positionX][ship.positionY + i] = 'X';
    }
    }
    }

    void doShoot(Shoot shoot) {
    switch (cells[shoot.xCoord][shoot.yCoord]) {
    case '.':
    System.out.println("MISS");
    cells[shoot.xCoord][shoot.yCoord] = '';
    break;
    case 'X':
    System.out.println("GOAL");
    cells[shoot.xCoord][shoot.yCoord] = '_';
    show();
    break;
    case '
    ':
    System.out.println("You already shoot here...");
    break;
    default:
    System.out.println("Error!");
    }
    }

    void show() {
    for (int i = 0; i < FIELDSIZE; i++) {

        if (i == 0) {
            for (int k = 0; k &lt; FIELDSIZE; k++) {
                System.out.print("\t" + k);
            }
            System.out.println();
        }
        System.out.print(i);
        for (int j = 0; j &lt; FIELDSIZE; j++) {
            System.out.print("\t" + cells[i][j]);
        }
        System.out.println();
    }
    

    }

    boolean isShipPresent(int positionX, int positionY) {
    return cells[positionX][positionY] == 'X';
    }

    boolean isNotGameOver() {
    boolean isPresent = false;
    for (int i = 0; i < FIELDSIZE; i++) {
    for (int j = 0; j < FIELDSIZE; j++) {
    if (cells[i][j] == 'X') isPresent = true;
    }
    }
    return isPresent;
    }
    //Проверка на то, можно ли в данном участке поставить корабль
    //Написано не очень правильно, только учусь 😞
    boolean isCanSetShip(Ship ship) {
    boolean canSet = true;
    if (ship.positionX + ship.size > FIELDSIZE - 1 || ship.positionY + ship.size > FIELDSIZE - 1)
    canSet = false;
    else {

        //Если корабль стоит горизонтально
        if (!ship.isVertical) {
            if (ship.positionX == 0 &amp;&amp; ship.positionY &gt; 0) {
                for (int i = 0; i &lt;= ship.size; i++) {
                    for (int j = -1; j &lt;= 1; j++) {
                        if (ship.positionY + j &lt; FIELDSIZE &amp;&amp; ship.positionY + j &gt;= 0) {
                            if (isShipPresent(ship.positionX + i, ship.positionY + i)) canSet = false;
                        } else canSet = false;
                    }
                }
            }
            if (ship.positionY == 0 &amp;&amp; ship.positionX &gt; 0) {
                for (int i = -1; i &lt;= ship.size; i++) {
                    for (int j = 0; j &lt;= 1; j++) {
                        if (ship.positionX + i &lt; FIELDSIZE &amp;&amp; ship.positionX + i &gt;= 0) {
                            if (isShipPresent(ship.positionX + i, ship.positionY + j)) canSet = false;
                        } else canSet = false;
                    }
                }
            }
            if (ship.positionX == 0 &amp;&amp; ship.positionY == 0) {
                for (int i = 0; i &lt;= ship.size; i++) {
                    for (int j = 0; j &lt;= 1; j++) {
                        if (isShipPresent(ship.positionX + j, ship.positionY + i)) canSet = false;
                    }
                }
            }
            if (ship.positionX &gt; 0 &amp;&amp; ship.positionY &gt; 0) {
                for (int i = -1; i &lt;= ship.size; i++) {
                    for (int j = -1; j &lt;= 1; j++) {
                        if (ship.positionX + j &gt;= 0 &amp;&amp; ship.positionY + i &gt;= 0 &amp;&amp; ship.positionX + j &lt; FIELDSIZE &amp;&amp; ship.positionY + i &lt; FIELDSIZE) {
                            if (isShipPresent(ship.positionX + j, ship.positionY + i)) canSet = false;
                        } else canSet = false;
                    }
                }
            }
        } else {
            //если корабль вертикально
            //пока не использую. На данный момент все корабли с горизонтальным положением
        }
    }
    return canSet;
    

    }
    }

    How is it right to organize an algorithm?



  • The proscribed zone around the ship is a rectangle within which there should be no other ship. Knowing the upper left and lower right point, you can check all points inside. In order not to deal with private cases, you can just cut the area under review.

    public boolean canSetShip( Ship ship ) {
        // проверяем, что наш корабль попадает в поле
        if ( ship.positionX < 0 || ship.positionY < 0 || FIELDSIZE <= ship.positionX || FIELDSIZE <= ship.positionY ) return false;
        if ( ship.isVertical && FIELDSIZE <= ship.positionY + ship.size ) return false;
        if ( !ship.isVertical && FIELDSIZE <= ship.positionX + ship.size ) return false;
    
    // проверяем, что в зоне вокруг корабля никого нет
    // обрезаем зону
    int minX = Math.max( 0, ship.positionX - 1 );
    int minY = Math.max( 0, ship.positionY - 1 );
    int maxX = Math.min( FIELDSIZE - 1, ship.positionX + 1 + (ship.isVertical ? 0 : ship.size) );
    int maxY = Math.min( FIELDSIZE - 1, ship.positionY + 1 + (ship.isVertical ? ship.size : 0) );
    
    // сама проверка
    for ( int x = minX; x &lt;= maxX; x++ ) {
        for ( int y = minY; y &lt;= maxY; y++ ) {
            if ( isShipPresent( x, y ) ) return false;
        }
    }
    return true;
    

    }

    You, too, should redesign the ship's installation (invasively that the "vertical" ship is located on X axis) and the decommissioning of the field (now you have cells[positionX][positionY] at positionX = 5; positionY = 3 It'll be like the 4th cell in line 6.




Suggested Topics

  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2