Changes from lesson 18

This commit is contained in:
danii 2024-04-16 11:47:52 +02:00
parent f62df29ed2
commit 20b930520f
8 changed files with 150 additions and 40 deletions

View File

@ -0,0 +1,6 @@
from enum import Enum
class ShipDirection(Enum):
VERTICAL = 0
HORIZONTAL = 1
UNKNOWN = -1

View File

@ -1,4 +1,6 @@
from ShootResult import ShootResult from ShootResult import ShootResult
from ShipMode import ShipMode
from ShipDirection import ShipDirection
class ShipField: class ShipField:
@ -17,9 +19,9 @@ class ShipField:
self.ships = [4, 3, 3, 2, 2, 2, 1, 1, 1, 1] self.ships = [4, 3, 3, 2, 2, 2, 1, 1, 1, 1]
self.field_size = 10 self.field_size = 10
self.field_mode = 0 self.field_mode = ShipMode.PUT
self.ship_size = 4 self.ship_size = 4
self.ship_direction = 0 self.ship_direction = ShipDirection.VERTICAL
def __getitem__(self, item): def __getitem__(self, item):
@ -38,27 +40,30 @@ class ShipField:
def action(self, row, col): def action(self, row, col):
self.clear_marker() self.clear_marker()
if self.field_mode == 0: if self.field_mode == ShipMode.PUT:
if self.ship_size in self.ships and self.check_possible(row, col): if self.check_ship(row, col):
self.get_ship(row, col)
elif self.ship_size in self.ships and self.check_possible(row, col):
self.set_ship(row, col) self.set_ship(row, col)
elif self.field_mode == 1: elif self.field_mode == ShipMode.SHOOT:
self.shoot(row, col) self.shoot(row, col)
def target(self, row, col): def target(self, row, col):
self.clear_marker() self.clear_marker()
if self.field_mode == 0: if self.field_mode == ShipMode.PUT:
if self.check_possible(row, col): if self.check_possible(row, col):
if self.ship_direction == 0: if self.ship_direction == ShipDirection.VERTICAL:
for r in range(row, row + self.ship_size): for r in range(row, row + self.ship_size):
if self.ship_size in self.ships: if self.ship_size in self.ships:
self.field[r * self.field_size + col] = "p" self.field[r * self.field_size + col] = "p"
else: else:
self.field[r * self.field_size + col] = "r" self.field[r * self.field_size + col] = "r"
if self.ship_direction == 1: if self.ship_direction == ShipDirection.HORIZONTAL:
for c in range(col, col + self.ship_size): for c in range(col, col + self.ship_size):
if self.ship_size in self.ships: if self.ship_size in self.ships:
self.field[row * self.field_size + c] = "p" self.field[row * self.field_size + c] = "p"
@ -83,13 +88,13 @@ class ShipField:
if col < 0 or col > self.field_size: if col < 0 or col > self.field_size:
return return
index = row * self.field_size + col index = row * self.field_size + col
if self.ship_direction == 0: if self.ship_direction == ShipDirection.VERTICAL:
if self.field_size - row < self.ship_size: if self.field_size - row < self.ship_size:
return return
for r in range(row, row + self.ship_size): for r in range(row, row + self.ship_size):
index = r * self.field_size + col index = r * self.field_size + col
self.field[index] = "1" self.field[index] = "1"
if self.ship_direction == 1: if self.ship_direction == ShipDirection.HORIZONTAL:
if self.field_size - col < self.ship_size: if self.field_size - col < self.ship_size:
return return
for c in range(col, col + self.ship_size): for c in range(col, col + self.ship_size):
@ -99,6 +104,59 @@ class ShipField:
if self.ship_size in self.ships: if self.ship_size in self.ships:
self.ships.remove(self.ship_size) self.ships.remove(self.ship_size)
def get_ship(self, row, col):
if row < 0 or row > self.field_size:
return
if col < 0 or col > self.field_size:
return
self.field[row * self.field_size + col] = ''
ship_size = 1
ship_direction = ShipDirection.UNKNOWN
# check vertical
for r in range(row + 1, self.field_size):
if self.check_ship(r, col):
ship_size += 1
ship_direction = ShipDirection.VERTICAL
self.field[r * self.field_size + col] = ''
else:
break
for r in range(row - 1, -1, -1):
if self.check_ship(r, col):
ship_size += 1
ship_direction = ShipDirection.VERTICAL
self.field[r * self.field_size + col] = ''
else:
break
if ship_direction == ShipDirection.UNKNOWN:
# check horizontal
for c in range(col + 1, self.field_size):
if self.check_ship(row, c):
ship_size += 1
ship_direction = ShipDirection.HORIZONTAL
self.field[row * self.field_size + c] = ''
else:
break
for c in range(col - 1, - 1, -1):
if self.check_ship(row, c):
ship_size += 1
ship_direction = ShipDirection.HORIZONTAL
self.field[row * self.field_size + c] = ''
else:
break
self.set_ship_direction(ship_direction)
self.set_ship_size(ship_size)
self.ships.append(ship_size)
def shoot(self, row, col): def shoot(self, row, col):
if row < 0 or row > self.field_size - 1: if row < 0 or row > self.field_size - 1:
return ShootResult.UNDEFINED return ShootResult.UNDEFINED
@ -113,16 +171,19 @@ class ShipField:
return ShootResult.DAMAGED return ShootResult.DAMAGED
else: else:
return ShootResult.UNDEFINED return ShootResult.UNDEFINED
def check_ship(self, row, col):
return self.field[row * self.field_size + col].strip() == '1'
def check_possible(self, row, col): def check_possible(self, row, col):
if self.ship_direction == 0: if self.ship_direction == ShipDirection.VERTICAL:
if self.field_size - row >= self.ship_size: if self.field_size - row >= self.ship_size:
for r in range(row, row + self.ship_size): for r in range(row, row + self.ship_size):
if not self.check_blocked(r, col): if not self.check_blocked(r, col):
return False return False
return True return True
if self.ship_direction == 1: if self.ship_direction == ShipDirection.HORIZONTAL:
if self.field_size - col >= self.ship_size: if self.field_size - col >= self.ship_size:
for c in range(col, col + self.ship_size): for c in range(col, col + self.ship_size):
if not self.check_blocked(row, c): if not self.check_blocked(row, c):
@ -154,24 +215,24 @@ class ShipField:
if value is None: if value is None:
return return
if type(value) is str and value.isnumeric(): if type(value) is not ShipDirection:
value = int(value) return
if type(value) is int and 0 <= value <= 1: if value != ShipDirection.UNKNOWN:
self.ship_direction = value self.ship_direction = value
def toggle_ship_direction(self): def toggle_ship_direction(self):
if self.field_mode == 0: if self.field_mode == ShipMode.PUT:
if self.ship_direction == 0: if self.ship_direction == ShipDirection.VERTICAL:
self.ship_direction = 1 self.ship_direction = ShipDirection.HORIZONTAL
else: else:
self.ship_direction = 0 self.ship_direction = ShipDirection.VERTICAL
def toggle_field_mode(self): def toggle_field_mode(self):
if self.field_mode == 0: if self.field_mode == ShipMode.PUT:
self.field_mode = 1 self.field_mode = ShipMode.SHOOT
else: else:
self.field_mode = 0 self.field_mode = ShipMode.PUT
def print_field(self): def print_field(self):
for r in range(0, self.field_size): for r in range(0, self.field_size):

View File

@ -1,6 +1,8 @@
from unittest import TestCase from unittest import TestCase
from ShipField import ShipField from ShipField import ShipField
from ShootResult import ShootResult from ShootResult import ShootResult
from ShipMode import ShipMode
from ShipDirection import ShipDirection
class TestShipField(TestCase): class TestShipField(TestCase):
@ -45,20 +47,16 @@ class TestShipField(TestCase):
def test_toggle_field_mode(self): def test_toggle_field_mode(self):
ship_field = ShipField() # Заводим объект типа ShipField ship_field = ShipField() # Заводим объект типа ShipField
self.assertEqual(ship_field.field_mode, 0) # Проверяем, что изначальное значение field_mode равно 0 self.assertEqual(ship_field.field_mode, ShipMode.PUT) # Проверяем, что изначальное значение field_mode равно 0
ship_field.toggle_field_mode() # Вызываем метод, который тестируем ship_field.toggle_field_mode() # Вызываем метод, который тестируем
self.assertEqual(ship_field.field_mode, 1) # Проверяем, что field_mode принял желаемое значение self.assertEqual(ship_field.field_mode, ShipMode.SHOOT) # Проверяем, что field_mode принял желаемое значение
ship_field.toggle_field_mode() # Вызываем метод, который тестируем ship_field.toggle_field_mode() # Вызываем метод, который тестируем
self.assertEqual(ship_field.field_mode, 0) # Проверяем, что field_mode принял желаемое значение self.assertEqual(ship_field.field_mode, ShipMode.PUT) # Проверяем, что field_mode принял желаемое значение
def test_action(self): def test_action(self):
ship_field = ShipField() self.fail()
self.assertEqual(ship_field.action, 0)
ship_field.action()
self.assertEqual(ship_field.action, 1)
def test_target(self): def test_target(self):
self.fail() self.fail()
@ -67,10 +65,12 @@ class TestShipField(TestCase):
ship_field = ShipField() ship_field = ShipField()
ship_field.field[0] = 'p' ship_field.field[0] = 'p'
ship_field.field[ship_field.field_size - 1] = 'p' ship_field.field[ship_field.field_size - 1] = 'p'
ship_field.field[ship_field.field_size - 4] = 'r'
ship_field.clear_marker() ship_field.clear_marker()
self.assertNotIn('p', ship_field.field) self.assertNotIn('p', ship_field.field)
self.assertNotIn('r', ship_field.field)
def test_shoot_empty(self): def test_shoot_empty(self):
ship_field = ShipField() ship_field = ShipField()
@ -133,7 +133,7 @@ class TestShipField(TestCase):
def test_set_ship_size4_horizontal_direction(self): def test_set_ship_size4_horizontal_direction(self):
ship_field = ShipField() ship_field = ShipField()
ship_field.set_ship_size(4) ship_field.set_ship_size(4)
ship_field.set_ship_direction(1) ship_field.set_ship_direction(ShipDirection.HORIZONTAL)
ship_field.set_ship(6, 3) ship_field.set_ship(6, 3)
@ -154,18 +154,56 @@ class TestShipField(TestCase):
self.assertEqual(new_field_string, old_field_string) self.assertEqual(new_field_string, old_field_string)
def test_check_possible(self): def test_check_possible(self):
self.fail() ship_field = ShipField()
ship_field.set_ship_size(4)
ship_field.set_ship_direction(ShipDirection.HORIZONTAL)
ship_field.set_ship(5, 3)
self.assertEqual(ship_field.check_possible(5, 3), False)
self.assertEqual(ship_field.check_possible(5, 4), False)
self.assertEqual(ship_field.check_possible(5, 5), False)
self.assertEqual(ship_field.check_possible(5, 6), False)
self.assertEqual(ship_field.check_possible(6, 3), False)
self.assertEqual(ship_field.check_possible(6, 4), False)
self.assertEqual(ship_field.check_possible(6, 5), False)
self.assertEqual(ship_field.check_possible(6, 6), False)
self.assertEqual(ship_field.check_possible(7, 3), True)
self.assertEqual(ship_field.check_possible(7, 4), True)
self.assertEqual(ship_field.check_possible(7, 5), True)
self.assertEqual(ship_field.check_possible(7, 6), True)
def test_check_blocked(self): def test_check_blocked(self):
self.fail() ship_field = ShipField()
ship_field.set_ship_size(4)
ship_field.set_ship_direction(ShipDirection.HORIZONTAL)
ship_field.set_ship(5, 3)
self.assertEqual(ship_field.check_possible(5, 3), False)
self.assertEqual(ship_field.check_possible(5, 4), False)
self.assertEqual(ship_field.check_possible(5, 5), False)
self.assertEqual(ship_field.check_possible(5, 6), False)
self.assertEqual(ship_field.check_possible(6, 3), False)
self.assertEqual(ship_field.check_possible(6, 4), False)
self.assertEqual(ship_field.check_possible(6, 5), False)
self.assertEqual(ship_field.check_possible(6, 6), False)
self.assertEqual(ship_field.check_possible(7, 3), True)
self.assertEqual(ship_field.check_possible(7, 4), True)
self.assertEqual(ship_field.check_possible(7, 5), True)
self.assertEqual(ship_field.check_possible(7, 6), True)
def test_set_ship_direction(self): def test_set_ship_direction(self):
ship_field = ShipField() ship_field = ShipField()
ship_field.set_ship_direction(1) ship_field.set_ship_direction(ShipDirection.HORIZONTAL)
self.assertEqual(ship_field.ship_direction, 1) self.assertEqual(ship_field.ship_direction, ShipDirection.HORIZONTAL)
ship_field.set_ship_direction(0) ship_field.set_ship_direction(ShipDirection.VERTICAL)
self.assertEqual(ship_field.ship_direction, 0) self.assertEqual(ship_field.ship_direction, ShipDirection.VERTICAL)
def test_toggle_ship_direction(self): def test_toggle_ship_direction(self):
@ -173,9 +211,9 @@ class TestShipField(TestCase):
ship_field.toggle_ship_direction() ship_field.toggle_ship_direction()
self.assertEqual(ship_field.ship_direction, 1) self.assertEqual(ship_field.ship_direction, ShipDirection.HORIZONTAL)
ship_field.toggle_ship_direction() ship_field.toggle_ship_direction()
self.assertEqual(ship_field.ship_direction, 0) self.assertEqual(ship_field.ship_direction, ShipDirection.VERTICAL)

View File

@ -0,0 +1,5 @@
from enum import Enum
class ShipMode(Enum):
PUT = 0
SHOOT = 1