diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml index f0182ec..3330671 100644 --- a/.idea/deploymentTargetDropDown.xml +++ b/.idea/deploymentTargetDropDown.xml @@ -10,12 +10,12 @@ - + - + diff --git a/app/release/app-release.aab b/app/release/app-release.aab new file mode 100644 index 0000000..e28c8b6 Binary files /dev/null and b/app/release/app-release.aab differ diff --git a/app/src/main/java/com/avs/sea/battle/battle_field/BattleField.kt b/app/src/main/java/com/avs/sea/battle/battle_field/BattleField.kt index 4820814..70ed022 100644 --- a/app/src/main/java/com/avs/sea/battle/battle_field/BattleField.kt +++ b/app/src/main/java/com/avs/sea/battle/battle_field/BattleField.kt @@ -48,27 +48,101 @@ class BattleField : BaseBattleField() { printBattleField() } - fun handleShot(coordinate: Coordinate?): Boolean { + fun handleShot(coordinate: Coordinate?): Pair> { var isShipHit = false + var killedShipCoordinates: ArrayList = ArrayList() if (coordinate != null && coordinate.x in 0 until SQUARES_COUNT && coordinate.y in 0 until SQUARES_COUNT) { if (battleField[coordinate.x][coordinate.y]?.getCellState() == CellState.EMPTY) { battleField[coordinate.x][coordinate.y]?.setCellState(CellState.SHOT_FAILURE) } else { battleField[coordinate.x][coordinate.y]?.setCellState(CellState.SHOT_SUCCESS) - defineShipByCoordinate(coordinate) isShipHit = true + val ship = getShipByCoordinate(coordinate) + ship?.let { + it.setShotSuccessState(coordinate) + if (it.isDead()) { + markNeighbours(ship) + killedShipCoordinates = getShipCoordinates(ship) + } + } + } + } + return isShipHit to killedShipCoordinates + } + + private fun markNeighbours(ship: Ship) { + if (ship.getShipOrientation() == Orientation.VERTICAL) { + markVerticalNeighbours(ship) + } else { + markHorizontalNeighbours(ship) + } + } + + private fun markHorizontalNeighbours(ship: Ship) { + for (cell in ship.getShipCells()) { + if (cell.getX() != 0) battleField[cell.getX() - 1][cell.getY()]?.setCellState(CellState.SHOT_FAILURE) + if (cell.getX() != battleField.size - 1) battleField[cell.getX() + 1][cell.getY()]?.setCellState( + CellState.SHOT_FAILURE + ) + } + val fistCell = ship.getShipCells().first() + if (fistCell.getY() != 0) { + battleField[fistCell.getX()][fistCell.getY() - 1]?.setCellState(CellState.SHOT_FAILURE) + if (fistCell.getX() != 0) { + battleField[fistCell.getX() - 1][fistCell.getY() - 1]?.setCellState(CellState.SHOT_FAILURE) + } + if (fistCell.getX() != battleField.size - 1) { + battleField[fistCell.getX() + 1][fistCell.getY() - 1]?.setCellState(CellState.SHOT_FAILURE) + } + } + val lastCell = ship.getShipCells().last() + if (lastCell.getY() != battleField.size - 1) { + battleField[lastCell.getX()][lastCell.getY() + 1]?.setCellState(CellState.SHOT_FAILURE) + if (lastCell.getX() != 0) { + battleField[lastCell.getX() - 1][lastCell.getY() + 1]?.setCellState(CellState.SHOT_FAILURE) + } + if (lastCell.getX() != battleField.size - 1) { + battleField[lastCell.getX() + 1][lastCell.getY() + 1]?.setCellState(CellState.SHOT_FAILURE) } } - return isShipHit } - private fun defineShipByCoordinate(coordinate: Coordinate) { + private fun markVerticalNeighbours(ship: Ship) { + for (cell in ship.getShipCells()) { + if (cell.getY() != 0) battleField[cell.getX()][cell.getY() - 1]?.setCellState(CellState.SHOT_FAILURE) + if (cell.getY() != battleField.size - 1) battleField[cell.getX()][cell.getY() + 1]?.setCellState( + CellState.SHOT_FAILURE + ) + } + val fistCell = ship.getShipCells().first() + if (fistCell.getX() != 0) { + battleField[fistCell.getX() - 1][fistCell.getY()]?.setCellState(CellState.SHOT_FAILURE) + if (fistCell.getY() != 0) { + battleField[fistCell.getX() - 1][fistCell.getY() - 1]?.setCellState(CellState.SHOT_FAILURE) + } + if (fistCell.getY() != battleField.size - 1) { + battleField[fistCell.getX() - 1][fistCell.getY() + 1]?.setCellState(CellState.SHOT_FAILURE) + } + } + val lastCell = ship.getShipCells().last() + if (lastCell.getX() != battleField.size - 1) { + battleField[lastCell.getX() + 1][lastCell.getY()]?.setCellState(CellState.SHOT_FAILURE) + if (lastCell.getY() != 0) { + battleField[lastCell.getX() + 1][lastCell.getY() - 1]?.setCellState(CellState.SHOT_FAILURE) + } + if (lastCell.getY() != battleField.size - 1) { + battleField[lastCell.getX() + 1][lastCell.getY() + 1]?.setCellState(CellState.SHOT_FAILURE) + } + } + } + + private fun getShipByCoordinate(coordinate: Coordinate): Ship? { for (ship in ships) { if (coordinate.x in ship.getRowCoordinates() && coordinate.y in ship.getColumnCoordinates()) { - ship.setShotSuccessState(coordinate) - break + return ship } } + return null } fun isGameOver(): Boolean { @@ -94,12 +168,10 @@ class BattleField : BaseBattleField() { return shipsCoordinates } - fun getAllShipsCoordinates(): ArrayList { + private fun getShipCoordinates(ship: Ship): ArrayList { val shipsCoordinates = arrayListOf() - ships.forEach { ship -> - ship.getShipCells().forEach { cell -> - shipsCoordinates.add(cell.getCoordinate()) - } + ship.getShipCells().forEach { cell -> + shipsCoordinates.add(cell.getCoordinate()) } return shipsCoordinates } diff --git a/app/src/main/java/com/avs/sea/battle/main/MainActivity.kt b/app/src/main/java/com/avs/sea/battle/main/MainActivity.kt index adf4e3e..9c84079 100644 --- a/app/src/main/java/com/avs/sea/battle/main/MainActivity.kt +++ b/app/src/main/java/com/avs/sea/battle/main/MainActivity.kt @@ -9,7 +9,6 @@ import android.util.Log import android.view.MenuItem import android.view.MotionEvent import android.view.View -import android.widget.TextView import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.view.ContextThemeWrapper @@ -118,12 +117,6 @@ class MainActivity : AppCompatActivity(), PopupMenu.OnMenuItemClickListener { } } - private fun setTextColor(v: View, color: Int) { - if (v is TextView) v.setTextColor( - ContextCompat.getColor(this, color) - ) - } - private fun showPopup(v: View?) { val wrapper: Context = ContextThemeWrapper(this, R.style.PopupStyle) if (v != null) { diff --git a/app/src/main/java/com/avs/sea/battle/main/MainViewModel.kt b/app/src/main/java/com/avs/sea/battle/main/MainViewModel.kt index e398ca3..9e7f5de 100644 --- a/app/src/main/java/com/avs/sea/battle/main/MainViewModel.kt +++ b/app/src/main/java/com/avs/sea/battle/main/MainViewModel.kt @@ -105,9 +105,12 @@ class MainViewModel : ViewModel() { fun makeFireAsPerson() { if (activePlayer == Player.PERSON) { - val isShipHit = computerBattleField.handleShot(_selectedByPersonCoordinate.value) + val shipState = computerBattleField.handleShot(_selectedByPersonCoordinate.value) _selectedByPersonCoordinate.value = null - if (isShipHit) { + if (shipState.first) { + if (shipState.second.isNotEmpty()) { + _personFailShots.value = computerBattleField.getDotsCoordinates() + } _status.value = R.string.status_shot_ship_again_text _personSuccessfulShots.value = computerBattleField.getCrossesCoordinates() if (computerBattleField.isGameOver()) { @@ -127,12 +130,15 @@ class MainViewModel : ViewModel() { private fun playAsComputer() { val coordinate: Coordinate = shotManager.getCoordinateToShot() _selectedByComputerCoordinate.value = coordinate - val isShipHit = personBattleField.handleShot(coordinate) - shotManager.handleShot(isShipHit) - if (isShipHit) { + val shipState = personBattleField.handleShot(coordinate) + shotManager.handleShot(shipState) + if (shipState.first) { viewModelScope.launch { delay(SECOND_IN_MILLIS) _computerSuccessfulShots.value = personBattleField.getCrossesCoordinates() + if (shipState.second.isNotEmpty()) { + _computerFailShots.value = personBattleField.getDotsCoordinates() + } if (personBattleField.isGameOver()) { endGame(false) } else { @@ -161,7 +167,7 @@ class MainViewModel : ViewModel() { private fun endGame(isPersonWon: Boolean) { activePlayer = Player.NONE - _computerShips.value = computerBattleField.getAllShipsCoordinates() + _computerShips.value = computerBattleField.getShipsCoordinates() if (isPersonWon) { _endGameEvent.value = true to Player.PERSON _status.value = R.string.status_game_over_you_win_text diff --git a/app/src/main/java/com/avs/sea/battle/main/ShotManager.kt b/app/src/main/java/com/avs/sea/battle/main/ShotManager.kt index 0a30868..d5088c4 100644 --- a/app/src/main/java/com/avs/sea/battle/main/ShotManager.kt +++ b/app/src/main/java/com/avs/sea/battle/main/ShotManager.kt @@ -22,29 +22,17 @@ class ShotManager { ONE_DECK_SHIP_SIZE, ONE_DECK_SHIP_SIZE, ONE_DECK_SHIP_SIZE, ONE_DECK_SHIP_SIZE ) - fun getShipsSize(): Int { - return ships.size - } + fun getShipsSize(): Int = ships.size - fun getBattleField(): BaseBattleField { - return battleField - } + fun getBattleField(): BaseBattleField = battleField - fun getFirstCell(): Cell { - return firstCell - } + fun getFirstCell(): Cell = firstCell - fun getSecondCell(): Cell { - return secondCell - } + fun getSecondCell(): Cell = secondCell - fun getThirdCell(): Cell { - return thirdCell - } + fun getThirdCell(): Cell = thirdCell - fun getFourthCell(): Cell { - return fourthCell - } + fun getFourthCell(): Cell = fourthCell fun getCoordinateToShot(): Coordinate { var coordinate = Coordinate() @@ -162,17 +150,17 @@ class ShotManager { fun getMaxCoordinate(list: MutableList, orientation: Orientation): Coordinate { return if (orientation == Orientation.VERTICAL) { - list.maxByOrNull { it.x }!! + list.maxBy { it.x } } else { - list.maxByOrNull { it.y }!! + list.maxBy { it.y } } } fun getMinCoordinate(list: MutableList, orientation: Orientation): Coordinate { return if (orientation == Orientation.VERTICAL) { - list.minByOrNull { it.x }!! + list.minBy { it.x } } else { - list.minByOrNull { it.y }!! + list.minBy { it.y } } } @@ -267,7 +255,8 @@ class ShotManager { return firstCell.getCoordinate() } - fun handleShot(shipHit: Boolean) { + fun handleShot(shipState: Pair>) { + val shipHit = shipState.first if (firstCell.isState(EMPTY) || firstCell.isState(SHOT_FAILURE)) { updateBattleField(shipHit, firstCell) } else if (firstCell.isState(SHOT_SUCCESS) @@ -294,6 +283,9 @@ class ShotManager { markNeighbours(fourthCell) } } + if (shipState.second.isNotEmpty()) { + resetValuesAfterShipIsDead(shipState.second.size, shipState.second) + } } private fun markNeighbours(cell: Cell) {