Naval Battle

Following game has been created as a project work for the course “Tik-76.030 Basic Course in Programming Y1” in Helsinki University of Technology. Game allows human player to challenge computer. During setting-up phase built-in logic assures that ships are not touching each other. When ship is sunk all squares around it are marked and neither human player nor computer can choose those squares to shoot anymore. Computer AI is rudimentary. It shoots randomly but never at the same square twice.

Game.java:

https://www.stotski.com/img/misc/naval_battle/Game.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/////////////////////////////////////////////////////////////////////////////
//
//  Naval Battle - Game class
//  version 1.0, build 29
//
//  Copyright 2000 Juri Stotski
//
/////////////////////////////////////////////////////////////////////////////
 
public class Game {
 
  public static boolean hit = false;                 // determines if ship was shot or not
  public static boolean end = false;                 // determines the end of a game
 
  public static void main(String args[]) {
   
    Player human = new Player("Human");              // sets size of the game field and creates human player object
    Player robot = new Player("Robot");              // creates computer player object
 
    human.setShipHuman(4, 1);                        // builds human ships
    human.setShipHuman(3, 2);
    human.setShipHuman(2, 3);
    human.setShipHuman(1, 4);
 
    robot.setShipRobot(4, 1);                        // builds computer ships
    robot.setShipRobot(3, 2);
    robot.setShipRobot(2, 3);
    robot.setShipRobot(1, 4);
     
    do {                                                           // executes game
 
      do {                                                         // "human" player move
 
        if (robot.alive() && human.alive()) hit = robot.moveHuman();
                            
      } while (hit == true && robot.alive() && human.alive());     // will continue until first shot into an empty field or the end of the game
 
      do {                                                         // "computer" player move
 
        if (robot.alive() && human.alive()) hit = human.moveRobot();
                            
      } while (hit == true && robot.alive() && human.alive());     // will continue until first shot into an empty field or the end of the game
 
    } while (robot.alive() && human.alive());                      // when all the ships of either of players are sank game ends
 
    if (!robot.alive()) human.end();
    if (!human.alive()) robot.end();
 
  }
 
}

Player.java:

https://www.stotski.com/img/misc/naval_battle/Player.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
/////////////////////////////////////////////////////////////////////////////
//
//  Naval Battle - Player class
//  version 1.0, build 29
//
//  Copyright 2000 Juri Stotski
//
/////////////////////////////////////////////////////////////////////////////
 
class Player {
 
  public static final String ALPHA = "ABCDEFGHIJKLMNOPQRST";       // english alphabet from A to T, here can be also multi-national alphabets if they are supported by JAVA
  public static final String SPACE = "YES";                        // screen buffer spacing, corrects screen fonts that may be too narrow, can have "YES and "NO" values
  public static final int    SHIPS = 20;                           // number of all points under ships: 1x4 + 2x3 + 3x2 + 4x1
  public static final int    ROUND = 120;                          // number of all points under ships and around them
 
  public static final char lineX         = '-';                    // here can be pseudo-graphics for better UI look under Windows OS
  public static final char lineY         = '|';
  public static final char lineCornerUpL = '+';
  public static final char lineCornerUpR = '+';
  public static final char lineCornerDoL = '+';
  public static final char lineCornerDoR = '+';
 
  public static final char shipShips = 'S';                        // how ships will look like on screen during construction and battle
  public static final char shipRound = '*';
  public static final char shipShoot = 'X';
  public static final char shipEmpty = ' ';
 
  public static int      boardSize = 0;                            // the size of the game board
  public static char[][] boardBuff;                                // screen buffer with all screen data
  public static String   errorLine = "";                           // error message status bar
  public static String   orderLine = "";                           // orders bar
 
  private int[][] ships;                                           // points with ships
  private int[][] round;                                           // points with ships and around ships
  private int[][] shoot;                                           // shot points during the game
  private int     shift = 0;                                       // "computer" relative to "human" game board shift, helps determine who-is-who and to update "boardBuff" array properly
 
  public Player(String name) {                                     // creates player objects
 
    if (name.equals("Human")) {
 
      this.setBoardSize(9, 15);                                    // asks user for the game board size, 9 is the minimun possible value, because at 8 there is no enough space on the board to build all the ships
      this.setBoardBuff();                                         // creates screen buffer
 
    } else shift = boardSize + 5;
 
    this.ships = new int[SHIPS][3];                                // creates all arrays needed for ships construction and game
    this.round = new int[ROUND][3];
    this.shoot = new int[boardSize][boardSize];
 
  }
 
  public static void setBoardSize(int begin, int end) {            // sets game board size in the beginning of the game
 
    errorLine = "No errors";
    orderLine = "Set battle field size" + " [" + begin + "-" + end + "]: ";
 
    do {
 
      for (int i = 0; i < 50; i++) System.out.print("\n");         // clears screen
 
      System.out.print("NAVAL BATTLE\n");
      System.out.print("COPYRIGHT BY JURI STOTSKI, 2000\n\n");
      System.out.print("ERRORS: " + errorLine + "\n");
      System.out.print("ORDERS: " + orderLine);
 
      boardSize = Read.integer();                                  // uses rewrited Lue.java code for better look and performance
      errorLine = "You entered wrong data, try again...";
 
    } while (boardSize < begin || boardSize > end);
 
  }
 
  public static void setBoardBuff() {                              // creates screen buffer array that contains all the data about ships that can be shown to the user
 
    boardBuff = new char[boardSize * 2 + 8][boardSize + 3];
                                                                                                          
    for (int i = 2; i < (2 + boardSize); i++) boardBuff[i][0] = ALPHA.charAt(i - 2);        // horizontal and vertical lines of alphabet characters
    for (int j = 2; j < (2 + boardSize); j++) boardBuff[0][j] = ALPHA.charAt(j - 2);
 
    for (int i = 2; i < (2 + boardSize); i++) boardBuff[i][1] = lineX;                      // horizontal and vertical lines of borders
    for (int i = 2; i < (2 + boardSize); i++) boardBuff[i][2 + boardSize] = lineX;
    for (int j = 2; j < (2 + boardSize); j++) boardBuff[1][j] = lineY;
    for (int j = 2; j < (2 + boardSize); j++) boardBuff[2 + boardSize][j] = lineY;
 
    boardBuff[1][1] = lineCornerUpL;                                                        // corners, can be easily upgraded to use pseudo-graphics under Windows OS
    boardBuff[2 + boardSize][1] = lineCornerUpR;
    boardBuff[1][2 + boardSize] = lineCornerDoL;
    boardBuff[2 + boardSize][2 + boardSize] = lineCornerDoR;
 
    for (int i = 0; i < (3 + boardSize); i++) {                                             // creates second ("computer") field by coping first
 
      for (int j = 0; j < (3 + boardSize); j++) {
 
        boardBuff[i + 5 + boardSize][j] = boardBuff[i][j];
 
      }
 
    }
 
  }
 
  public void setShipHuman(int size, int quantity) {               // creates "human" ships
 
    String  tempCoord;                                             // temp variable for user input
    boolean ok;
 
    for (int i = 0; i < quantity; i++) {
 
      errorLine = "No errors";
      orderLine = "Set " +  buildShipName(size) + " " + (i + 1) + ", size " + size + " on the field [" + buildShipExample(size) + "]: ";
 
      do {
 
        ok = true;
 
        this.putBoardBuff();
 
        tempCoord = Read.string().toUpperCase();                   // can process mixed case strings
 
        if (ok == true) ok = buildCheckFormat(tempCoord);          // checks the quality of the input coordinates
        if (ok == true) ok = buildCheckBended(tempCoord);          // checks if coordinates represent bended ship
        if (ok == true) ok = buildCheckLength(tempCoord, size);    // checks if coordinates represent ship that is longer or shorter than allowed "size"
        if (ok == true) ok = buildCheckRounds(tempCoord, size);    // checks if coordinates represent ship that cannot be build on this place
 
        if (ok == true) {
                                                                    
          buildAddRound(tempCoord, size);                          // adds denied points to "round" variable array
          buildAddShips(tempCoord, size);                          // adds ship to "ships" variable array
 
        } else {
         
          errorLine = "Your coordinates are wrong, try again...";
 
        }
 
      } while (!ok);
 
      if (size == 1 && i == 3) buildShipClear();
 
    }   
 
  }
 
  public void setShipRobot(int size, int quantity) {               // automatic routine for "computer" ships construction, obeys all the rules
 
    int X1 = 0;                                                    // "X1" and "Y1" are random numbers, "X2" and "Y2" depend on "size" and "dir" variables' values
    int X2 = 0;
    int Y1 = 0;
    int Y2 = 0;
 
    int dir = 0;                                                   // random number, can have values from 0 to 3, which mean "up", "down", "right" and "left" directions of ship construction
 
    boolean ok;
    boolean ob;
 
    char[] tempArray = new char[5];                                // simulates human player's input style [AA-AB] so the same check methods can be used
 
    for (int i = 0; i < quantity; i++) {
 
      do {
 
        ok = true;
 
        X1 = (int) (boardSize * Math.random());                    // gets random number from "0" to "boardSize - 1"
        Y1 = (int) (boardSize * Math.random());                    // gets random number from "0" to "boardSize - 1"
 
        do {
 
          ob = true;
 
          dir = (int) (4 * Math.random());
 
          if (dir == 0) { X2 = X1; Y2 = Y1 - size - 1; }
          if (dir == 1) { Y2 = Y1; X2 = X1 + size - 1; }
          if (dir == 2) { X2 = X1; Y2 = Y1 + size - 1; }
          if (dir == 3) { Y2 = Y1; X2 = X1 - size - 1; }
 
          if (X2 < 0 || X2 > (boardSize - 1)) ob = false;
          if (Y2 < 0 || Y2 > (boardSize - 1)) ob = false;
 
        } while (!ob);
 
        tempArray[0] = ALPHA.charAt(X1);
        tempArray[1] = ALPHA.charAt(Y1);
        tempArray[2] = '-';
        tempArray[3] = ALPHA.charAt(X2);
        tempArray[4] = ALPHA.charAt(Y2);
 
        String tempCoord = new String(tempArray);
 
        if (ok == true) ok = buildCheckFormat(tempCoord);          // a couple of simple rules that will not let user input data that looks bad
        if (ok == true) ok = buildCheckBended(tempCoord);          // checks if coordinates represent bended ship
        if (ok == true) ok = buildCheckLength(tempCoord, size);    // checks if coordinates represent ship that is longer or shorter than allowed "size"
        if (ok == true) ok = buildCheckRounds(tempCoord, size);    // checks if coordinates represent ship that cannot be build on this place
 
        if (ok == true) {
                                                                    
          buildAddRound(tempCoord, size);                          // adds denied points to "round" variable array
          buildAddShips(tempCoord, size);                          // adds ship to "ships" variable array
 
        }
 
      } while (!ok);
 
    }
 
  }
 
  public String buildShipName(int size) {                          // returns ship's name based on its size
 
    if (size == 1) return "submarine";
    if (size == 2) return "cruiser";
    if (size == 3) return "destroyer";
 
    return "battleship";
 
  }
 
  public String buildShipExample(int size) {                       // interractive help, supports multi-national ALPHAs
 
    if (size == 1) return "" + ALPHA.charAt(0) + ALPHA.charAt(0) + "-" + ALPHA.charAt(0) + ALPHA.charAt(0);   // "" + at the beginning needed to avoid interpretation of ALPHA.charAt(0) as a numeric (0-255) value
    if (size == 2) return "" + ALPHA.charAt(0) + ALPHA.charAt(0) + "-" + ALPHA.charAt(0) + ALPHA.charAt(1);
    if (size == 3) return "" + ALPHA.charAt(0) + ALPHA.charAt(0) + "-" + ALPHA.charAt(0) + ALPHA.charAt(2);
 
    return "" + ALPHA.charAt(0) + ALPHA.charAt(0) + "-" + ALPHA.charAt(0) + ALPHA.charAt(3);
 
  }
 
  public boolean buildCheckFormat(String tempCoord) {              // a couple of simple rules that will not let user input data that looks bad
 
    if (tempCoord.length() != 5) return false;
 
    if (ALPHA.indexOf(tempCoord.charAt(0)) == -1) return false;
    if (ALPHA.indexOf(tempCoord.charAt(1)) == -1) return false;
 
    if (tempCoord.charAt(2) != '-') return false;
 
    if (ALPHA.indexOf(tempCoord.charAt(3)) == -1) return false;
    if (ALPHA.indexOf(tempCoord.charAt(4)) == -1) return false;
 
    if (ALPHA.indexOf(tempCoord.charAt(0)) >= boardSize) return false;
    if (ALPHA.indexOf(tempCoord.charAt(1)) >= boardSize) return false;
    if (ALPHA.indexOf(tempCoord.charAt(3)) >= boardSize) return false;
    if (ALPHA.indexOf(tempCoord.charAt(4)) >= boardSize) return false;
 
    return true;
 
  }
 
  public boolean buildCheckBended(String tempCoord) {              // checks if coordinates represent bended ship
 
    if (tempCoord.charAt(0) != tempCoord.charAt(3) && tempCoord.charAt(1) != tempCoord.charAt(4)) return false;
 
    return true;
 
  }
 
  public boolean buildCheckLength(String tempCoord, int size) {    // checks if coordinates represent ship that is longer or shorter than allowed "size"
 
    int differenceX = Math.abs(ALPHA.indexOf(tempCoord.charAt(0)) - ALPHA.indexOf(tempCoord.charAt(3))) + 1;
    int differenceY = Math.abs(ALPHA.indexOf(tempCoord.charAt(1)) - ALPHA.indexOf(tempCoord.charAt(4))) + 1;
 
    if (differenceX == 1 && differenceY == size) return true;
    if (differenceX == size && differenceY == 1) return true;
 
    return false;
 
  }
 
  public boolean buildCheckRounds(String tempCoord, int size) {    // checks if coordinates represent ship that cannot be build on this place
 
    int[][] tempShips = buildGetTempShips(tempCoord, new int[size][2]);
 
    for (int x = 0; x < size; x++) {
 
      for (int i = 0; i < ROUND; i++) {
 
        if (this.round[i][0] == tempShips[x][0] && this.round[i][1] == tempShips[x][1]) return false;
 
      }
 
    }
 
    return true;
 
  }
 
  public void buildAddShips(String tempCoord, int size) {
     
    int[][] tempShips = buildGetTempShips(tempCoord, new int[size][2]);
 
    for (int i = 0; i < size; i++) {
 
      a:
 
      for (int j = 0; j < SHIPS; j++) {
 
        if (ships[j][0] == 0) {
 
           this.ships[j][0] = tempShips[i][0];
           this.ships[j][1] = tempShips[i][1];
 
           break a;
 
        }
 
      }
 
    }
 
    if (shift == 0) {                                              // boardBuff update
 
      for (int i = 0; i < SHIPS; i++) {
 
        if (this.ships[i][0] != 0) {
 
          boardBuff[this.ships[i][0] + 1 + shift][this.ships[i][1] + 1] = shipShips;
 
        }
 
      }
 
    }
 
  }
 
  public void buildAddRound(String tempCoord, int size) {
 
    int[][] tempShips = buildGetTempShips(tempCoord, new int[size][2]);
 
    for (int j = (tempShips[0][1] - 1); j < (tempShips[size - 1][1] + 2); j++) {
 
      for (int i = (tempShips[0][0] - 1); i < (tempShips[size - 1][0] + 2); i++) {
 
        a:
 
        for (int k = 0; k < ROUND; k++) {
 
          if (round[k][0] == 0) {
 
            if (i > boardSize || i == 0) this.round[k][0] = -1; else this.round[k][0] = i;
            if (j > boardSize || j == 0) this.round[k][1] = -1; else this.round[k][1] = j;
 
            if (this.round[k][0] == -1) this.round[k][1] = -1;     // helps to keep uniformity, if one coordinate marked as "-1" (out of field) second coordinate will also get value "-1"
            if (this.round[k][1] == -1) this.round[k][0] = -1;
 
            break a;
 
          }
 
        }
 
      }
 
    }
 
    if (shift == 0) {                                              // boardBuff update
     
      for (int i = 0; i < ROUND; i++) {               
 
        if (this.round[i][0] != 0) {
 
          if (this.round[i][0] != -1 && this.round[i][1] != -1) {
 
            boardBuff[this.round[i][0] + 1 + shift][this.round[i][1] + 1] = shipRound;
     
          }
 
        }
 
      }
 
    }
 
  }
 
  public int[][] buildGetTempShips(String tempCoord, int[][] tempShips) {
 
    int directionX = 1;
    int directionY = 1;
 
    int X = 0;
    int Y = 0;
 
    int X1 = ALPHA.indexOf(tempCoord.charAt(0));
    int X2 = ALPHA.indexOf(tempCoord.charAt(3));
    int Y1 = ALPHA.indexOf(tempCoord.charAt(1));
    int Y2 = ALPHA.indexOf(tempCoord.charAt(4));
 
         if (X2 > X1) { X = X1; }
    else if (X2 < X1) { X = X2; }
    else if (X2 == X1) { X = X1; directionX = 0; }
 
         if (Y2 > Y1) { Y = Y1; }
    else if (Y2 < Y1) { Y = Y2; }
    else if (Y2 == Y1) { Y = Y1; directionY = 0; }
 
    for (int i = 0; i < tempShips.length; i++) {
 
      tempShips[i][0] = (X + 1 + i * directionX);
      tempShips[i][1] = (Y + 1 + i * directionY);
 
    }
 
    return tempShips;
 
  }
 
  public void buildShipClear() {                                   // clears "human" field before battle
 
    for (int j = 0; j < boardSize; j++) {                          // clears field
 
      for (int i = 0; i < boardSize; i++) {
 
        boardBuff[i + 2 + shift][j + 2] = shipEmpty;
 
      }
 
    }
 
    for (int i = 0; i < SHIPS; i++) {                              // adds ships to field
 
      boardBuff[this.ships[i][0] + 1 + shift][this.ships[i][1] + 1] = shipShips;
 
    }
 
 
  
 
  public boolean moveHuman() {
 
    String  tempCoord;
    boolean ok;
 
    errorLine = "No errors";
    orderLine = "Enter coordinates where you want to shoot [" + ALPHA.charAt(0) + ALPHA.charAt(2) + "]: ";
 
    do {
 
      ok = true;
 
      this.putBoardBuff();
 
      tempCoord = Read.string().toUpperCase();                     // can process mixed case strings
 
      if (ok == true) ok = moveCheckCoord(tempCoord);              // checks the quality of the input coordinates
      if (ok == true) ok = moveCheckShoot(tempCoord);              // checks if the input coordinates were already entered earlier
      if (ok == true) ok = moveCheckRound(tempCoord);              // checks if the input coordinates point to sank ship or its surroundings
 
      if (ok == true) {
                                                                    
        moveAddShoot(tempCoord);                                   // adds point to "shoot" array if square that contains ship has been shot
        boolean shot = moveAddShips(tempCoord);                    // marks point in "ships" array as shot if it's shot
        moveAddRound();                                            // updates "round" array to absorb changes that happend in "ships" array
 
        moveUpdateBoardBuff();
 
        if (shot) return true; else return false;
 
      } else {
 
        errorLine = "Your coordinates are wrong, try again...";
 
      }
 
    } while (!ok);
 
    return false;
 
  }
 
  public boolean moveRobot() {                                     // random point generator, avoids shot points and points around sank ships
 
    int X = 0;                                                     // "X" and "Y" are random numbers
    int Y = 0;
 
    boolean ok;
 
    char[] tempArray = new char[2];                                // simulates human player's input style [AA] so the same check methods can be used
 
    do {
 
      ok = true;
 
      X = (int) (boardSize * Math.random());                       // gets random number from "0" to "boardSize - 1"
      Y = (int) (boardSize * Math.random());                       // gets random number from "0" to "boardSize - 1"
 
      tempArray[0] = ALPHA.charAt(X);
      tempArray[1] = ALPHA.charAt(Y);
 
      String tempCoord = new String(tempArray);
 
      if (ok == true) ok = moveCheckCoord(tempCoord);              // checks the quality of the input coordinates
      if (ok == true) ok = moveCheckShoot(tempCoord);              // checks if the input coordinates were already entered earlier
      if (ok == true) ok = moveCheckRound(tempCoord);              // checks if the input coordinates point to sank ship or its surroundings
 
      if (ok == true) {
                                                                    
        moveAddShoot(tempCoord);                                   // adds point to "shoot" array if square that contains ship has been shot
        boolean shot = moveAddShips(tempCoord);                    // marks point in "ships" array as shot if it's shot
        moveAddRound();                                            // updates "round" array to absorb changes that happend in "ships" array
 
        moveUpdateBoardBuff();
 
        if (shot) return true; else return false;
 
      }
 
    } while (!ok);
 
    return false;
 
  }
 
  public boolean moveCheckCoord(String tempCoord) {                // checks the quality of the input coordinates
 
    if (tempCoord.length() != 2) return false;
 
    if (ALPHA.indexOf(tempCoord.charAt(0)) == -1) return false;
    if (ALPHA.indexOf(tempCoord.charAt(1)) == -1) return false;
 
    if (ALPHA.indexOf(tempCoord.charAt(0)) > (boardSize + 1)) return false;
    if (ALPHA.indexOf(tempCoord.charAt(1)) > (boardSize + 1)) return false;
 
    return true;
 
  }
 
  public boolean moveCheckShoot(String tempCoord) {                // checks if the input coordinates were already entered earlier
 
    int X = ALPHA.indexOf(tempCoord.charAt(0));
    int Y = ALPHA.indexOf(tempCoord.charAt(1));
 
    if (this.shoot[X][Y] == 1) return false;
 
    return true;
 
  }
                                                                   // checks if the input coordinates point to sank ship or its surroundings
  public boolean moveCheckRound(String tempCoord) {
 
    int X = ALPHA.indexOf(tempCoord.charAt(0)) + 1;                // "+ 1" is here because in "ships" and "round" matrices coordinates begin with 1, not with 0
    int Y = ALPHA.indexOf(tempCoord.charAt(1)) + 1;
 
    for (int i = 0; i < ROUND; i++) {
 
      if (this.round[i][0] == X && this.round[i][1] == Y && this.round[i][2] == 1) return false;
 
    }
 
    return true;
 
  }
 
  public void moveAddShoot(String tempCoord) {                     // adds point to "shoot" array
 
    int X = ALPHA.indexOf(tempCoord.charAt(0));
    int Y = ALPHA.indexOf(tempCoord.charAt(1));
 
    this.shoot[X][Y] = 1;
 
  }
 
  public boolean moveAddShips(String tempCoord) {                  // marks point in "ships" array as shot if it's shot
 
    int X = ALPHA.indexOf(tempCoord.charAt(0)) + 1;                // "+ 1" is here because in ships and round matrices coordinates begin with 1, not with 0
    int Y = ALPHA.indexOf(tempCoord.charAt(1)) + 1;
 
    for (int i = 0; i < SHIPS; i++) {
 
      if (ships[i][0] == X && ships[i][1] == Y) {
 
        ships[i][2] = 1;
        return true;
 
      }
 
    }
 
    return false;
 
  }
 
  public void moveAddRound() {                                     // updates "round" array to absorb changes that happend in "ships" array
 
    if (this.ships[0][2] == 1 &&                                   // if ship is sank all places around it are marked as sank ship surroundings, shooting there is useless
        this.ships[1][2] == 1 &&
        this.ships[2][2] == 1 &&
        this.ships[3][2] == 1for (int i = 0; i < 18; i++)    if (this.round[i][0] == -1) this.round[i][2] = -1; else this.round[i][2] = 1;
 
    if (this.ships[4][2] == 1 &&
        this.ships[5][2] == 1 &&
        this.ships[6][2] == 1for (int i = 18; i < 33; i++)   if (this.round[i][0] == -1) this.round[i][2] = -1; else this.round[i][2] = 1;
 
    if (this.ships[7][2] == 1 &&
        this.ships[8][2] == 1 &&
        this.ships[9][2] == 1for (int i = 33; i < 48; i++)   if (this.round[i][0] == -1) this.round[i][2] = -1; else this.round[i][2] = 1;
 
    if (this.ships[10][2] == 1 &&
        this.ships[11][2] == 1) for (int i = 48; i < 60; i++)   if (this.round[i][0] == -1) this.round[i][2] = -1; else this.round[i][2] = 1;
 
    if (this.ships[12][2] == 1 &&
        this.ships[13][2] == 1) for (int i = 60; i < 72; i++)   if (this.round[i][0] == -1) this.round[i][2] = -1; else this.round[i][2] = 1;
 
    if (this.ships[14][2] == 1 &&
        this.ships[15][2] == 1) for (int i = 72; i < 84; i++)   if (this.round[i][0] == -1) this.round[i][2] = -1; else this.round[i][2] = 1;
 
    if (this.ships[16][2] == 1) for (int i = 84; i < 93; i++)   if (this.round[i][0] == -1) this.round[i][2] = -1; else this.round[i][2] = 1;
    if (this.ships[17][2] == 1) for (int i = 93; i < 102; i++)  if (this.round[i][0] == -1) this.round[i][2] = -1; else this.round[i][2] = 1;
    if (this.ships[18][2] == 1) for (int i = 102; i < 111; i++) if (this.round[i][0] == -1) this.round[i][2] = -1; else this.round[i][2] = 1;
    if (this.ships[19][2] == 1) for (int i = 111; i < 120; i++) if (this.round[i][0] == -1) this.round[i][2] = -1; else this.round[i][2] = 1;
 
  }
 
  public boolean alive() {
 
    for (int i = 0; i < SHIPS; i++) if (this.ships[i][2] == 0) return true;
 
    return false;
 
  }
 
  public void end () {
 
    for (int i = 0; i < 50; i++) System.out.println();             // clears screen
 
    if (shift == 0) {
 
      System.out.println("You won the battle against evil computer forces...");
 
    } else System.out.println("Evil computer forces were too strong for you, brother. RIP...");
 
  }
 
 
  public void moveUpdateBoardBuff() {
 
    for (int j = 0; j < boardSize; j++) {                          // performs rendering at three layers: first - shot points, second - points around sank ships, third - sank and wounded ships by themselves
 
      for (int i = 0; i < boardSize; i++) {
 
        if (this.shoot[i][j] == 1) boardBuff[i + 2 + shift][j + 2] = shipRound;
 
      }
 
    }
 
    for (int i = 0; i < ROUND; i++) {
 
      if (this.round[i][2] == 1) boardBuff[this.round[i][0] + 1 + shift][this.round[i][1] + 1] = shipRound;
 
    }
 
    for (int i = 0; i < SHIPS; i++) {
 
      if (this.ships[i][2] == 1) boardBuff[this.ships[i][0] + 1 + shift][this.ships[i][1] + 1] = shipShoot;
 
    }
 
  }
 
  public void putBoardBuff() {                                     // prints game board, current errors and orders bars
 
    for (int i = 0; i < 50; i++) System.out.println();             // clears screen
 
    System.out.print("NAVAL BATTLE\n");
    System.out.print("COPYRIGHT BY JURI STOTSKI, 2000\n\n");
 
    for (int j = 0; j < (boardSize + 3); j++) {
 
      for (int i = 0; i < (boardSize * 2 + 8); i++) {
 
        if (boardBuff[i][j] == 0) {                                // prints space if field is empty
 
          System.out.print(" ");
 
        } else System.out.print(boardBuff[i][j]);
 
        if (SPACE.equals("YES")) {                                 // makes spacing
 
          if (i == 1 && j == 1) { System.out.print(lineX); continue; }
          if (i == 1 && j == (boardSize + 2)) { System.out.print(lineX); continue; }
          if (i == (boardSize + 6) && j == 1) { System.out.print(lineX); continue; }
          if (i == (boardSize + 6) && j == (boardSize + 2)) { System.out.print(lineX); continue; }
 
          if (boardBuff[i][j] == lineX) {
 
            System.out.print(lineX);
 
          } else {System.out.print(" ");}
 
        }
 
      }
 
      System.out.print("\n");
 
    }
 
    System.out.print("\nERRORS: " + errorLine);
    System.out.print("\nORDERS: " + orderLine);
 
  }
 
}

Read.java:

https://www.stotski.com/img/misc/naval_battle/Read.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
/////////////////////////////////////////////////////////////////////////////
//
//  Naval Battle - Read class
//  version 1.0, build 29
//
//  Copyright 2000 Juri Stotski
//
/////////////////////////////////////////////////////////////////////////////
 
import java.io.*;
 
public class Read {
 
  public static BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
 
  public static String string() {
 
    String arvo = null;
 
    try {
 
      arvo = stdin.readLine();
 
    } catch (Exception e) {
 
      return "Fail";
 
    }
     
   // if (arvo == "exit") System.exit(1);
 
    return arvo;
 
  }
 
  public static int integer() {
 
    int arvo = -1;
 
    try {
 
      arvo = Integer.parseInt(stdin.readLine());
 
    } catch (Exception e) {
 
      return 3141592;
 
    }
 
    return arvo;
 
  }
 
}

Test run:

Leave a Reply

Your email address will not be published. Required fields are marked *