"Sea Battle" in Java for beginners. Level 1

Hello everyone!





The article is dedicated to those who are just breaking into the fascinating world of Java programming and looking for an application for their knowledge. It's great that you now know how to create variables, methods and arrays, but, of course, you want to write programs that are "useful" for humanity, and not perform numerous small exercises and tasks, although without this you can not go anywhere either. In general, we will supplement the theory with practice. Go!





First, let's discuss what the business requirements are for our application. After lengthy negotiations, the customer approved the following game scenario:





  1. The application should work from the console. Our customer turned out to be a retrograde, and he believes that his target audience really likes the console interface. Everyone has their own quirks, but okay.





  2. Only two people can participate in the game at a time.





  3. At the very beginning, the players "introduce themselves" - the program "asks" (prompts users to enter) what names they have





  4. Each player has his own field - a square of 10x10 cells





  5. The players then take turns placing their ships. As in the "paper" version - everyone can supply 4 single-deck ships, 3 double-deck, 2 three-deck and 1 four-deck.





  6. Ships can only be positioned horizontally or vertically.





  7. Players do not see the location of each other's ships.





  8. The game begins. The first player fires a shot, telling our application the coordinates of the intended target - the horizontal number of the cell and the vertical number of the cell.





  9. If the first player's shot was successful, and he hit the target, then there are two possible scenarios.



    If there is a ship in the cell indicated by the player, then if the ship is single-deck, the player "killed" the ship, if not single-deck, then wounded it. In any case, the next move is again behind the first player.



    The second option, if the player did not hit any ship, then the turn goes to the second player.





  10. , 8, , . , , - . .





    , , .





Java ( Main), , , main.





public class Main {
	public static void main(String[] args) {
  	//your code will be here
	}
}
      
      



, , " " .





1-3 , , . java.util.Scanner, .





public class Main {
    static Scanner scanner = new Scanner(System.in);

    public static void main(String[] args) {
        System.out.println("Player 1, please, input your name");
        String player1Name = scanner.nextLine();
        System.out.println("Hello, " + player1Name + "!");

        System.out.println("Player 2, please, input your name");
        String player2Name = scanner.nextLine();
        System.out.println("Hello, " + player2Name + "!");
    }
}
      
      



:





2 Main scanner.





nextLine() Scanner ( 6 11) , .





, - "Hello, {username} !"





, .





Player 1, please, input your name
Egor
Hello, Egor!
Player 2, please, input your name
Max
Hello, Max!
      
      



, . , char[][] buttlefield. . , #. *. , char ('\u0000'), # *.





public class Main {
		static final int FILED_LENGTH = 10;
    static Scanner scanner = new Scanner(System.in);

public static void main(String[] args) {
    System.out.println("Player 1, please, input your name");
    String player1Name = scanner.nextLine();
    System.out.println("Hello, " + player1Name + "!");

    System.out.println("Player 2, please, input your name");
    String player2Name = scanner.nextLine();
    System.out.println("Hello, " + player2Name + "!");
    
    char[][] playerField1 = new char[FILED_LENGTH][FILED_LENGTH];
    char[][] playerField2 = new char[FILED_LENGTH][FILED_LENGTH];

    char[][] playerBattleField1 = new char[FILED_LENGTH][FILED_LENGTH];
    char[][] playerBattleField2 = new char[FILED_LENGTH][FILED_LENGTH];
	}
}
      
      



:





2 FIELD_LENGTH, - 4 - FIELD_LENGTH 10.





14-18 char. playerFiled1 playerField2 - , . - , .





. fillPlayerField(playerField), .





public class Main {
    static final int FILED_LENGTH = 10;
    static Scanner scanner = new Scanner(System.in);

    public static void main(String[] args) {
        System.out.println("Player 1, please, input your name");
        String player1Name = scanner.nextLine();
        System.out.println("Hello, " + player1Name + "!");

        System.out.println("Player 2, please, input your name");
        String player2Name = scanner.nextLine();
        System.out.println("Hello, " + player2Name + "!");

        char[][] playerField1 = new char[FILED_LENGTH][FILED_LENGTH];
        char[][] playerField2 = new char[FILED_LENGTH][FILED_LENGTH];

        fillPlayerField(playerField1);
        fillPlayerField(playerField2);
    }
}

private static void fillPlayerField(char[][] playerField) {
	// your code will be here
}
      
      



fillPlayerField (static), main, . fillPlayerField (void). playerField .





, . , , , . (. - โ„– 6) - .





, fillPlayerField:





 4- .  : 1
Input x coord: 
1
Input y coord: 
1
1. Horizontal; 2. Vertical ?
1
      
      



- . :





private static void fillPlayerField(char[][] playerField) {
    // your code will be here
}
      
      



4 1. . for. , , - , (. โ„–5) - - for.





private static void fillPlayerField(char[][] playerField) {
		// i -     
    //    ,  4 ,      
    for (int i = 4; i >= 1; i--) {
      	// .      
    		for (int k = i; k <= 5 - i; k++) {
          	System.out.println(" " + i + "- .  : " + (q + 1));
        		// some your code here
        }
    }
}

      
      



:





5 for (int k = 0; k <= 5 - i; k++). , . - , ( ) .





, - :





int[][] shipTypeAmount = {{1, 4}, {2, 3}, {3, 2}, {4, 1}};
      
      



(. 4) , , . , , , , , - , , "" .





, - . , 1 + 2 = 5;  2 + 3 = 5;  3 + 2 = 5;  4 + 1 = 5. , ( ), , . , 5 - 1 = 4- , 4 . for 6 "" - .





- .





private static void fillPlayerField(char[][] playerField) {
        for (int i = 4; i >= 1; i--) {
            //   
            for (int k = i; k <= 5 - i; k++) {
                System.out.println(" " + i + "- .  : " + (q + 1));

                System.out.println("Input x coord: ");
                x = scanner.nextInt();

                System.out.println("Input y coord: ");
                y = scanner.nextInt();

                System.out.println("1 - horizontal; 2 - vertical ?");
                position = scanner.nextInt();

                //    
              	if (position == 1) {
                    //  '1'    ,    
                    for (int q = 0; q < i; q++) {
                        playerField[y][x + q] = '1';
                    }
                }
              
              	//    
                if (position == 2) {
                  	//     ,    
                    for (int m = 0; m < i; m++) {
                        playerField[y + m][x] = '1';
                    }
                }
              	//     ,    ,     
              	//    - . 
                printField(playerField);
            }
        }
    }
      
      



:





'1' , - , 4 - 4 '1'.





, . , - printField.





static void printField(char[][] field) {
        for (char[] cells : monitor) {
            for (char cell : t) {
              //    (  char - 0),    
              //    -   
                if (cell == 0) {
                    System.out.print(" |");
                } else {
   									//    (   ),
                  	//    ( )
                    System.out.print(cell + "|");
                }
            }
            System.out.println("");
            System.out.println("--------------------");
        }
    }
      
      



:





 | | | | | | | | | |
--------------------
 |1|1|1|1| | | | | |
--------------------
 | | | | | | | | | |
--------------------
 | | | | | | | | | |
--------------------
 | | | | | | | | | |
--------------------
 | | | | | | | | | |
--------------------
 | | | | | | | | | |
--------------------
 | | | | | | | | | |
--------------------
 | | | | | | | | | |
--------------------
 | | | | | | | | | |
--------------------
      
      



, 8-10 - .





, playGame. ( ) single responsobility - (1 - 1 , , , 100500 ) - handleShot isPlayerAlive.





/**
*    :    .
*/
private static void playGame(String player1Name, String player2Name, char[][] playerField1, char[][] playerField2) {
        // ""  -   ,    
  			//  (#)   (*)
  			char[][] playerBattleField1 = new char[FILED_LENGTH][FILED_LENGTH];
        char[][] playerBattleField2 = new char[FILED_LENGTH][FILED_LENGTH];

  			//  ,       - 
  			// ,  m  .    ,  
  			//  
        String currentPlayerName = player1Name;
        char[][] currentPlayerField = playerField2;
        char[][] currentPlayerBattleField = playerBattleField1;

  			//      , ,  .
  			//       ,  ""   -    
  			// ""  ()     
        while (isPlayerAlive(playerField1) && isPlayerAlive(playerField2)) {
          	//     
            System.out.println(currentPlayerName + ", please, input x coord of shot");
            int xShot = scanner.nextInt();
            System.out.println(currentPlayerName + ", please, input y coord of shot");
            int yShot = scanner.nextInt();

          	//        handleShot
            int shotResult = handleShot(currentPlayerBattleField, currentPlayerField, xShot, yShot);
            //   ,      ,      
          	if (shotResult == 0) {
                currentPlayerName = player2Name;
              	currentPlayerField = playerField1;
              	currentPlayerBattleField = playerBattleField2;
            }
        }
    }

		/**
    *   .   ,      -
    *     '#' (    ,     ),
    *       'Good shot!'.       1.
    *     -   battleField   '0'   [y][x], 
    *    0.
    *      ,   ,     handleShot,
    *   ,     .      , 
		*       .
    */
    private static int handleShot(char[][] battleField, char[][] field, int x, int y) {
        if ('1'.equals(field[y][x])) {
            field[y][x] = '#';
            battleField[y][x] = '#';
            System.out.println("Good shot!");
            return 1;
        }
        battleField[y][x] = '*';
        System.out.println("Bad shot!");
        return 0;
    }

		/**
		*	 ,     .      
    *  "" ,    .
    *  ,           '1',   
    * ,    -   true.  false.
		*/
    private static boolean isPlayerAlive(char[][] field) {
        for (char[] cells : field) {
            for (char cell : cells) {
                if ('1' == cell) {
                    return true;
                }
            }
        }
        return false;
    }
      
      



, . , . (x, y) - , - . , ( , ) arr[x][y]



, , . :





int[][] arr = {{1, 2}, {7, 4}, {8, 3, 5, 9}, {1}}

System.out.println(arr[0][1]); // ?
System.out.println(arr[1][0]); // ?

      
      



" " - 3 4?

, - ( ) - " " - . , - ( - ). , , . , . arr[1][2]



, 2 ( 3 ) 1 ( ). , 3 2, 4 - 7.





. ?









  1. ,





, . playGame - , while, - . , "", , , . , , - 36 - System.out.println()





/**
*    :    .
*/
private static void playGame(String player1Name, String player2Name, char[][] playerField1, char[][] playerField2) {
		// ""  -   ,    
    //  (#)   (*)
    char[][] playerBattleField1 = new char[FILED_LENGTH][FILED_LENGTH];
    char[][] playerBattleField2 = new char[FILED_LENGTH][FILED_LENGTH];

    //  ,       - 
    // ,  m  .    ,  
    //  
    String currentPlayerName = player1Name;
    char[][] currentPlayerField = playerField2;
    char[][] currentPlayerBattleField = playerBattleField1;

    //      , ,  .
    //       ,  ""   -    
    // ""  ()     
    while (isPlayerAlive(playerField1) &amp;&amp; isPlayerAlive(playerField2)) {
      	//          
      	printField(currentPlayerBattleField);
        //     
        System.out.println(currentPlayerName + ", please, input x coord of shot");
        int xShot = scanner.nextInt();
        System.out.println(currentPlayerName + ", please, input y coord of shot");
        int yShot = scanner.nextInt();

        //        handleShot
        int shotResult = handleShot(currentPlayerBattleField, currentPlayerField, xShot, yShot);
        //   ,      ,      
          if (shotResult == 0) {
            currentPlayerName = player2Name;
              currentPlayerField = playerField1;
              currentPlayerBattleField = playerBattleField2;
        }
    }
  	System.out.println(currentPlayerName + " is winner!");
}
      
      



"" - , - .





, , - - , . - .





A neighborhood with a radius of one cell.  The starting square is marked with a red circle - the beginning of the ship.
. - .

- , , , . , , "" - .





? .





The inefficiency of our simple algorithm.  We check some cells several times.
. .
private static int validateCoordForShip(char[][] field, int x, int y, int position, int shipType) {
        //      
  			if (position == 1) {
            for (int i = 0; i < shipType - 1; i++) {
								if ('1' == field[y][x + i]
                                || '1' == field[y - 1][x + i]
                                || '1' == field[y + 1][x + i]
                                || '1' == field[y][x + i + 1]
                                || '1' == field[y][x + i - 1]
																|| (x + i) > 9) {
                    return -1;
                }
            }
        } else if (position == 2) {
          	//      
            for (int i = 0; i < shipType - 1; i++) {
                if ('1' == field[y][x + i]
                        || '1' == field[y - 1][x + i]
                        || '1' == field[y + 1][x + i]
                        || '1' == field[y][x + i + 1]
                        || '1' == field[y][x + i - 1]
												|| (y + i) > 9) {
                    return -1;
                }
            }
        }
        return 0;
    }
      
      



fillPlayerField - , .





private static void fillPlayerField(char[][] playerField) {
        for (int i = 4; i >= 1; i--) {
            //  
            for (int k = i; k <= 5 - i; k++) {
                System.out.println(" " + i + "- .  : " + (q + 1));
								
              	//    
              	int validationResult = 1;
            		while (validationResult != 0) {
              			System.out.println("Input x coord: ");
            				x = scanner.nextInt();

            				System.out.println("Input y coord: ");
           		 			y = scanner.nextInt();

            				System.out.println("1 - horizontal; 2 - vertical ?");
            				position = scanner.nextInt();
                  	//      (),    
										// , ,    ,     
                  	//  
                  	validationResult = validateCoordForShip(playerField, x, y, position, i);
                }

            		//    
              	if (position == 1) {
                		//  '1'    ,    
                		for (int q = 0; q < i; q++) {
                    		playerField[y][x + q] = '1';
                		}
            		}
          
              	//    
            		if (position == 2) {
                  	//     ,    
                		for (int m = 0; m < i; m++) {
                    		playerField[y + m][x] = '1';
                		}
            		}
              	//     ,    ,     
              	//    - . 
            		printField(playerField);
        		}
    		}
}
      
      



So we wrote the game "Sea Battle" - level 1. We started with simple things - simple constructions, ideas and methods. One class, no collections - just arrays. It turns out that you can write a game on loops and arrays.





We have met all business requirements. Finishing the game to the end, we received an excellent assessment from the customer, he is completely satisfied with the application. We are waiting for him to try out the game and come back again for an upgrade. And here it will be level - 2.





Thank you all, always happy to receive feedback!








All Articles