diff --git a/src/main/java/de/tims/fleetstorm/gui/GameLogic.java b/src/main/java/de/tims/fleetstorm/gui/GameLogic.java index 2bc34d5..c61cafa 100644 --- a/src/main/java/de/tims/fleetstorm/gui/GameLogic.java +++ b/src/main/java/de/tims/fleetstorm/gui/GameLogic.java @@ -194,10 +194,10 @@ public class GameLogic extends JPanel { // create player matchfield and set ships this.matchfield = new Matchfield(matchfieldSize); this.matchfield.createMatchfield(); - this.matchfield.setShip(new Coordinate(4, 6), 2, 0); - this.matchfield.setShip(new Coordinate(1, 3), 3, 0); - this.matchfield.setShip(new Coordinate(9, 1), 4, 1); - this.matchfield.setShip(new Coordinate(0, 0), 5, 0); + this.matchfield.setShipOnRandomPosition(2); + this.matchfield.setShipOnRandomPosition(3); + this.matchfield.setShipOnRandomPosition(4); + this.matchfield.setShipOnRandomPosition(5); this.aiLogic = new Logic(); this.aiLogic.setMatchfield(this.matchfield); @@ -206,10 +206,10 @@ public class GameLogic extends JPanel { // matchfield) this.enemyMatchfield = new Matchfield(matchfieldSize); this.enemyMatchfield.createMatchfield(); - this.enemyMatchfield.setShip(new Coordinate(8, 9), 2, 0); - this.enemyMatchfield.setShip(new Coordinate(0, 2), 3, 1); - this.enemyMatchfield.setShip(new Coordinate(7, 0), 4, 1); - this.enemyMatchfield.setShip(new Coordinate(3, 6), 5, 0); + this.enemyMatchfield.setShipOnRandomPosition(2); + this.enemyMatchfield.setShipOnRandomPosition(3); + this.enemyMatchfield.setShipOnRandomPosition(4); + this.enemyMatchfield.setShipOnRandomPosition(5); // enter game loop this.gameState = GameLogic.RUNNING; diff --git a/src/main/java/de/tims/fleetstorm/matchfield/Matchfield.java b/src/main/java/de/tims/fleetstorm/matchfield/Matchfield.java index cca91c9..54eb146 100644 --- a/src/main/java/de/tims/fleetstorm/matchfield/Matchfield.java +++ b/src/main/java/de/tims/fleetstorm/matchfield/Matchfield.java @@ -1,5 +1,7 @@ package de.tims.fleetstorm.matchfield; +import java.util.Random; + public class Matchfield { private Coordinate[][] matchfield; @@ -110,4 +112,53 @@ public class Matchfield { return shipCounter == 0; } + public boolean isFreePosition(Coordinate next, int length, int direction) { + + for (int i = 0; i < length; i++) { + + if (this.getState(next.getX(), next.getY()) != Coordinate.EMPTY) + return false; + + if (direction == 0) { + next = new Coordinate(next.getX() + 1, next.getY()); + } else if (direction == 1) { + next = new Coordinate(next.getX(), next.getY() + 1); + } + } + + return true; + } + + public boolean setShipOnRandomPosition(int length) { + boolean success = false; + Coordinate origin = null; + int randomDirection; + + do { + + Random random = new Random(); + + randomDirection = random.nextInt(2); + + int randomX = 0, randomY = 0; + + if (randomDirection == 0) { + randomX = random.nextInt(this.size - length); + randomY = random.nextInt(this.size); + } else if (randomDirection == 1) { + randomX = random.nextInt(this.size); + randomY = random.nextInt(this.size - length); + } + + origin = new Coordinate(randomX, randomY); + + if (this.isFreePosition(origin, length, randomDirection)) { + success = this.setShip(new Coordinate(randomX, randomY), length, randomDirection); + } + + } while (!success); + + return true; + } + } diff --git a/src/test/java/de/tims/fleetstorm/matchfield/MatchfieldShipTest.java b/src/test/java/de/tims/fleetstorm/matchfield/MatchfieldShipTest.java index 665f367..8a8814c 100644 --- a/src/test/java/de/tims/fleetstorm/matchfield/MatchfieldShipTest.java +++ b/src/test/java/de/tims/fleetstorm/matchfield/MatchfieldShipTest.java @@ -3,9 +3,8 @@ package de.tims.fleetstorm.matchfield; import static org.junit.jupiter.api.Assertions.*; import static org.assertj.core.api.Assertions.assertThat; - import java.util.stream.Stream; - +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -13,19 +12,27 @@ import org.junit.jupiter.params.provider.MethodSource; class MatchfieldShipTest { + private Matchfield matchfield; + private int matchfieldSize = 10; + + @BeforeEach + void setup() { + matchfield = new Matchfield(matchfieldSize); + matchfield.createMatchfield(); + } + @ParameterizedTest(name = "ship was set on the correct positions") @MethodSource("testShipPositioning") - void testMatchfieldShipSetHasCorrectPositions(String testName, int matchfieldSize, Coordinate coordinate, - int direction, int length, Coordinate[] coordinatesWithShip) { - Matchfield matchfield = new Matchfield(matchfieldSize); - matchfield.createMatchfield(); + void testMatchfieldShipSetHasCorrectPositions(String testName, Coordinate coordinate, int direction, int length, + Coordinate[] coordinatesWithShip) { matchfield.setShip(coordinate, length, direction); int shipSetCounter = 0; for (Coordinate toCheckCoordinate : coordinatesWithShip) { - if (matchfield.getField(toCheckCoordinate).getState() == Coordinate.SHIP) + if (matchfield.getField(toCheckCoordinate).getState() == Coordinate.SHIP) { shipSetCounter++; + } } assertThat(shipSetCounter).describedAs(testName).isEqualTo(length); @@ -39,42 +46,33 @@ class MatchfieldShipTest { new Coordinate(0, 4), new Coordinate(0, 5) }; return Stream.of( - Arguments.of("set ship from 0:0, length 2, direction 0", 10, new Coordinate(0, 0), 0, 2, + Arguments.of("set ship from 0:0, length 2, direction 0", new Coordinate(0, 0), 0, 2, coordinatesWithShip00_2_0), - Arguments.of("set ship from 0:1, length 3, direction 0", 10, new Coordinate(0, 1), 0, 3, + Arguments.of("set ship from 0:1, length 3, direction 0", new Coordinate(0, 1), 0, 3, coordinatesWithShip01_3_0), - Arguments.of("set ship from 0:2, length 4, direction 1", 10, new Coordinate(0, 2), 1, 4, + Arguments.of("set ship from 0:2, length 4, direction 1", new Coordinate(0, 2), 1, 4, coordinatesWithShip02_4_1)); } @ParameterizedTest(name = "ship positioning on invalid or valid coordinates") @MethodSource("testShipPositioningFailed") - void testMatchfieldShipSetWithInvalidOrValidCoordinates(String testName, int matchfieldSize, Coordinate coordinate, - int direction, int length, boolean expectedResult) { - Matchfield matchfield = new Matchfield(matchfieldSize); - matchfield.createMatchfield(); + void testMatchfieldShipSetWithInvalidOrValidCoordinates(String testName, Coordinate coordinate, int direction, + int length, boolean expectedResult) { boolean calculatedResult = matchfield.setShip(coordinate, length, direction); - - if (expectedResult) - assertThat(calculatedResult).describedAs(testName).isEqualTo(true); - - if (!expectedResult) - assertThat(calculatedResult).describedAs(testName).isEqualTo(false); + assertThat(calculatedResult).describedAs(testName).isEqualTo(expectedResult); } static Stream testShipPositioningFailed() { return Stream.of( - Arguments.of("invalid ship position from 9:0, length 2, direction 0", 10, new Coordinate(9, 0), 0, 2, - false), - Arguments.of("valid ship position from 8:0, length 5, direction 1", 10, new Coordinate(9, 0), 1, 5, + Arguments.of("invalid ship position from 9:0, length 2, direction 0 (x-axis)", new Coordinate(9, 0), 0, + 2, false), + Arguments.of("valid ship position from 8:0, length 5, direction 1 (y-axis)", new Coordinate(9, 0), 1, 5, true)); } @Test void testShipPositionAlreadySetWithShip() { - Matchfield matchfield = new Matchfield(10); - matchfield.createMatchfield(); matchfield.setShip(new Coordinate(0, 0), 5, 1); assertThat(matchfield.setShip(new Coordinate(0, 1), 5, 1)).describedAs("set ship on coordinate with ship") @@ -88,9 +86,6 @@ class MatchfieldShipTest { @Test void testIfAllShipsHitReturnsFalseWhenNoShipIsHit() { - Matchfield matchfield = new Matchfield(10); - matchfield.createMatchfield(); - matchfield.setShip(new Coordinate(0, 0), 5, 1); boolean calulatedResult = matchfield.areAllShipsHit(); assertFalse(calulatedResult); @@ -98,15 +93,9 @@ class MatchfieldShipTest { @Test void testIfAllShipsHitReturnsTrueWhenAllShipsAreHit() { - Matchfield matchfield = new Matchfield(10); - matchfield.createMatchfield(); - matchfield.setShip(new Coordinate(0, 0), 5, 1); - matchfield.getField(0, 0).setState(Coordinate.HIT); - matchfield.getField(0, 1).setState(Coordinate.HIT); - matchfield.getField(0, 2).setState(Coordinate.HIT); - matchfield.getField(0, 3).setState(Coordinate.HIT); - matchfield.getField(0, 4).setState(Coordinate.HIT); + + setFieldRangeHit(matchfield); boolean calulatedResult = matchfield.areAllShipsHit(); assertTrue(calulatedResult); @@ -114,15 +103,9 @@ class MatchfieldShipTest { @Test void testIfAllShipsHitReturnsFalseWhenTwoShipsAreNotFullyHit() { - Matchfield matchfield = new Matchfield(10); - matchfield.createMatchfield(); - matchfield.setShip(new Coordinate(0, 0), 5, 1); - matchfield.getField(0, 0).setState(Coordinate.HIT); - matchfield.getField(0, 1).setState(Coordinate.HIT); - matchfield.getField(0, 2).setState(Coordinate.HIT); - matchfield.getField(0, 3).setState(Coordinate.HIT); - matchfield.getField(0, 4).setState(Coordinate.HIT); + + setFieldRangeHit(matchfield); matchfield.setShip(new Coordinate(3, 4), 2, 0); matchfield.getField(4, 4).setState(Coordinate.HIT); @@ -130,4 +113,45 @@ class MatchfieldShipTest { boolean calulatedResult = matchfield.areAllShipsHit(); assertFalse(calulatedResult); } + + void setFieldRangeHit(Matchfield matchfield) { + for (int i = 0; i <= 4; i++) { + matchfield.getField(0, i).setState(Coordinate.HIT); + } + } + + @ParameterizedTest(name = "matchfield returns correct state if a position is free or not") + @MethodSource("testIsFreeMethod") + void testMatchfieldReturnsCorrectValueAboutFreeCoordinateSlots(String testName, Coordinate originCoordinate, + int direction, int length, Coordinate[] coordinatesWithShip, boolean expectedResult) { + + Matchfield matchfield = new Matchfield(matchfieldSize); + matchfield.createMatchfield(); + + for (Coordinate coordinate : coordinatesWithShip) { + matchfield.getField(coordinate).setState(Coordinate.SHIP); + } + + boolean calculatedResult = matchfield.isFreePosition(originCoordinate, length, direction); + assertThat(calculatedResult).describedAs(testName).isEqualTo(expectedResult); + + } + + static Stream testIsFreeMethod() { + return Stream.of( + Arguments.of("one ship is within the coordinates", new Coordinate(0, 0), 1, 2, + new Coordinate[] { new Coordinate(0, 0) }, false), + Arguments.of("no ship is within the coordinates", new Coordinate(1, 1), 0, 5, new Coordinate[] {}, + true), + Arguments.of("one of the coordinates is hit, others on free fields", new Coordinate(5, 5), 1, 3, + new Coordinate[] { new Coordinate(5, 7), new Coordinate(5, 8), new Coordinate(5, 9) }, false)); + } + + @Test + void testIfRandomShipPositioningIsWorking() { + for (int shipLength = 2; shipLength <= 5; shipLength++) { + boolean calculatedResult = matchfield.setShipOnRandomPosition(shipLength); + assertTrue(calculatedResult); + } + } }