add kill check & kill marker

This commit is contained in:
ehermakov 2024-07-21 20:40:04 +03:00
parent 112b9a1394
commit feb25bb48f
20 changed files with 1125 additions and 1074 deletions

BIN
.DS_Store vendored

Binary file not shown.

BIN
HNS/.DS_Store vendored

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,30 +1,30 @@
import os import os
def list_levels(): def list_levels():
files = os.listdir(path=".") files = os.listdir(path=".")
result = [] result = []
for file in files: for file in files:
if file.lower().endswith('.txt'): if file.lower().endswith('.txt'):
result.append(file) result.append(file)
return result return result
def load(file): def load(file):
# 1 загрузить весь файл в строку # 1 загрузить весь файл в строку
f = open(file, "r") f = open(file, "r")
s = f.read() s = f.read()
# 2 заменить все пробелы и переводы строки на ничего # 2 заменить все пробелы и переводы строки на ничего
s = s.replace(" ", "") s = s.replace(" ", "")
s = s.replace('\n', "") s = s.replace('\n', "")
# 3 из полученной строки создать массив используя разделитель "," # 3 из полученной строки создать массив используя разделитель ","
a = s.split(",") a = s.split(",")
# а - массив строк, в которых хранятся числа # а - массив строк, в которых хранятся числа
b = [] b = []
f.close() f.close()
return a return a

View File

@ -1,16 +1,16 @@
from enum import Enum from enum import Enum
class GameMode(Enum): class GameMode(Enum):
MENU = 'MENU' MENU = 'MENU'
PLAN = 'PLAN' PLAN = 'PLAN'
BATTLE = 'BATTLE' BATTLE = 'BATTLE'
END = 'END' END = 'END'
@staticmethod @staticmethod
def from_string(raw_value): def from_string(raw_value):
if raw_value: if raw_value:
value = raw_value.upper() value = raw_value.upper()
if value in GameMode.__members__: if value in GameMode.__members__:
return GameMode[value] return GameMode[value]
return GameMode.MENU return GameMode.MENU

View File

@ -1,15 +1,15 @@
from enum import Enum from enum import Enum
class ShipDirection(Enum): class ShipDirection(Enum):
VERTICAL = 'VERTICAL' VERTICAL = 'VERTICAL'
HORIZONTAL = 'HORIZONTAL' HORIZONTAL = 'HORIZONTAL'
UNKNOWN = 'UNKNOWN' UNKNOWN = 'UNKNOWN'
@staticmethod @staticmethod
def from_string(raw_value): def from_string(raw_value):
if raw_value: if raw_value:
value = raw_value.upper() value = raw_value.upper()
if value in ShipDirection.__members__: if value in ShipDirection.__members__:
return ShipDirection[value] return ShipDirection[value]
return ShipDirection.UNKNOWN return ShipDirection.UNKNOWN

View File

@ -1,331 +1,380 @@
import copy import copy
from ShootResult import ShootResult from ShootResult import ShootResult
from ShipDirection import ShipDirection from ShipDirection import ShipDirection
from ShipMode import ShipMode from ShipMode import ShipMode
class ShipField: class ShipField:
field_size = 10 field_size = 10
def __init__(self): def __init__(self):
self.field = [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', self.field = [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '] ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']
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_mode = ShipMode.INACTIVE self.field_mode = ShipMode.INACTIVE
self.ship_size = 4 self.ship_size = 4
self.ship_direction = ShipDirection.VERTICAL self.ship_direction = ShipDirection.VERTICAL
def from_json(self, obj): def from_json(self, obj):
self.field = obj['field'] self.field = obj['field']
self.ships = obj['ships'] self.ships = obj['ships']
self.field_mode = ShipMode.from_string(obj['field_mode']) self.field_mode = ShipMode.from_string(obj['field_mode'])
self.ship_size = obj['ship_size'] self.ship_size = obj['ship_size']
self.ship_direction = ShipDirection.from_string(obj['ship_direction']) self.ship_direction = ShipDirection.from_string(obj['ship_direction'])
def __getitem__(self, item): def __getitem__(self, item):
if item is None: if item is None:
return None return None
if type(item) is not int and item.isnumeric(): if type(item) is not int and item.isnumeric():
item = int(item) item = int(item)
if type(item) is int and 0 <= item < len(self.field): if type(item) is int and 0 <= item < len(self.field):
return self.field[item] return self.field[item]
return None return None
def check_killed(self, row, col):
if row < 0 or row > ShipField.field_size:
return def mark_killed(self, row, col):
if col < 0 or col > ShipField.field_size: if row < 0 or row > ShipField.field_size:
return return
if col < 0 or col > ShipField.field_size:
ship_killed = True return
ship_direction = ShipDirection.UNKNOWN
self.field[row * ShipField.field_size + col] = 'x'
#check vertical self.fill_empty_killed(row, col)
for r in range(row + 1, ShipField.field_size):
if self.check_ship(r, col):
return False #check vertical
for r in range(row + 1, ShipField.field_size):
elif self.check_empty(r, col): if self.check_damaged(r, col):
break self.field[r * ShipField.field_size + col] = 'x'
self.fill_empty_killed(r, col)
for r in range(row - 1, -1, -1):
if self.check_ship(r, col): else:
return False break
elif self.check_empty(r, col): for r in range(row - 1, -1, -1):
break if self.check_damaged(r, col):
self.field[r * ShipField.field_size + col] = 'x'
# проверим горизонталь self.fill_empty_killed(r, col)
for c in range(col + 1, ShipField.field_size): else:
if self.check_ship(row, c): break
ship_direction = ShipDirection.HORIZONTAL
else: # проверим горизонталь
break for c in range(col + 1, ShipField.field_size):
if self.check_damaged(row, c):
for c in range(col + 1, ShipField.field_size): self.field[row * ShipField.field_size + c] = 'x'
if self.check_ship(row, c): self.fill_empty_killed(row, c)
return False else:
break
elif self.check_empty(row, c):
break for c in range(col - 1, -1, -1):
return True if self.check_damaged(row, c):
self.field[row * ShipField.field_size + c] = 'x'
def fill_empty_killed(self, row, col): self.fill_empty_killed(row, c)
pass else:
break
def action(self, row, col):
self.clear_marker() def check_killed(self, row, col):
if row < 0 or row > ShipField.field_size:
if self.field_mode == ShipMode.PUT: return
if self.check_ship(row, col): if col < 0 or col > ShipField.field_size:
self.get_ship(row, col) return
elif self.ship_size in self.ships and self.check_possible(row, col): ship_killed = True
self.set_ship(row, col) ship_direction = ShipDirection.UNKNOWN
elif self.field_mode == ShipMode.SHOOT: #check vertical
shoot_result = self.shoot(row, col) for r in range(row + 1, ShipField.field_size):
if self.check_ship(r, col):
if shoot_result == ShootResult.KILLED: return False
self.fill_empty_killed(row, col)
elif self.check_empty(r, col):
return shoot_result == ShootResult.EMPTY break
return False for r in range(row - 1, -1, -1):
if self.check_ship(r, col):
def target(self, row, col): return False
self.clear_marker()
elif self.check_empty(r, col):
if self.field_mode == ShipMode.PUT: break
if self.check_possible(row, col):
if self.ship_direction == ShipDirection.VERTICAL: # проверим горизонталь
for r in range(row, row + self.ship_size): for c in range(col + 1, ShipField.field_size):
if self.ship_size in self.ships: if self.check_ship(row, c):
self.field[r * ShipField.field_size + col] = "p" return False
else:
self.field[r * ShipField.field_size + col] = "r" elif self.check_empty(row, c):
break
if self.ship_direction == ShipDirection.HORIZONTAL:
for c in range(col, col + self.ship_size): for c in range(col - 1, -1, -1):
if self.ship_size in self.ships: if self.check_ship(row, c):
self.field[row * ShipField.field_size + c] = "p" return False
else:
self.field[row * ShipField.field_size + c] = "r" elif self.check_empty(row, c):
elif self.field_mode == ShipMode.SHOOT: break
self.field[row * ShipField.field_size + col] += "+"
return True
def clear_marker(self):
for i in range(0, len(self.field)): def fill_empty_killed(self, row, col):
if self.field[i] == "p" or self.field[i] == "r": for r in range(row - 1, row + 2):
self.field[i] = "" for c in range(col - 1, col + 2):
if self.check_empty(r, c):
if "+" in self.field[i]: self.field[r * ShipField.field_size + c] = '0'
self.field[i] = self.field[i].replace("+", "")
def action(self, row, col):
def set_ship(self, row, col): self.clear_marker()
if row < 0 or row > ShipField.field_size:
return if self.field_mode == ShipMode.PUT:
if col < 0 or col > ShipField.field_size: if self.check_ship(row, col):
return self.get_ship(row, col)
index = row * ShipField.field_size + col
if self.ship_direction == ShipDirection.VERTICAL: elif self.ship_size in self.ships and self.check_possible(row, col):
if ShipField.field_size - row < self.ship_size: self.set_ship(row, col)
return
for r in range(row, row + self.ship_size): elif self.field_mode == ShipMode.SHOOT:
index = r * ShipField.field_size + col shoot_result = self.shoot(row, col)
self.field[index] = "1"
if self.ship_direction == ShipDirection.HORIZONTAL: if shoot_result == ShootResult.KILLED:
if ShipField.field_size - col < self.ship_size: self.mark_killed(row, col)
return self.fill_empty_killed(row, col)
for c in range(col, col + self.ship_size):
index = row * ShipField.field_size + c return shoot_result == ShootResult.EMPTY
self.field[index] = "1"
return False
if self.ship_size in self.ships:
self.ships.remove(self.ship_size) def target(self, row, col):
self.print_field() self.clear_marker()
if self.ship_size not in self.ships and len(self.ships) > 0: if self.field_mode == ShipMode.PUT:
self.ship_size = max(self.ships) if self.check_possible(row, col):
if self.ship_direction == ShipDirection.VERTICAL:
def get_ship(self, row, col): for r in range(row, row + self.ship_size):
if row < 0 or row > ShipField.field_size: if self.ship_size in self.ships:
return self.field[r * ShipField.field_size + col] = "p"
if col < 0 or col > ShipField.field_size: else:
return self.field[r * ShipField.field_size + col] = "r"
self.field[row * ShipField.field_size + col] = "" if self.ship_direction == ShipDirection.HORIZONTAL:
for c in range(col, col + self.ship_size):
ship_size = 1 if self.ship_size in self.ships:
ship_direction = ShipDirection.UNKNOWN self.field[row * ShipField.field_size + c] = "p"
else:
# проверим вертикаль self.field[row * ShipField.field_size + c] = "r"
for r in range(row + 1, ShipField.field_size): elif self.field_mode == ShipMode.SHOOT:
if self.check_ship(r, col): self.field[row * ShipField.field_size + col] += "+"
ship_size += 1
ship_direction = ShipDirection.VERTICAL def clear_marker(self):
self.field[r * ShipField.field_size + col] = "" for i in range(0, len(self.field)):
else: if self.field[i] == "p" or self.field[i] == "r":
break self.field[i] = ""
for r in range(row - 1, -1, -1): if "+" in self.field[i]:
if self.check_ship(r, col): self.field[i] = self.field[i].replace("+", "")
ship_size += 1
ship_direction = ShipDirection.VERTICAL def set_ship(self, row, col):
self.field[row * ShipField.field_size + col] = "" if row < 0 or row > ShipField.field_size:
else: return
break if col < 0 or col > ShipField.field_size:
return
if ship_direction == ShipDirection.UNKNOWN: index = row * ShipField.field_size + col
if self.ship_direction == ShipDirection.VERTICAL:
# проверим горизонталь if ShipField.field_size - row < self.ship_size:
for c in range(col + 1, ShipField.field_size): return
if self.check_ship(row, c): for r in range(row, row + self.ship_size):
ship_size += 1 index = r * ShipField.field_size + col
ship_direction = ShipDirection.HORIZONTAL self.field[index] = "1"
self.field[row * ShipField.field_size + c] = "" if self.ship_direction == ShipDirection.HORIZONTAL:
else: if ShipField.field_size - col < self.ship_size:
break return
for c in range(col, col + self.ship_size):
for c in range(col - 1, -1, -1): index = row * ShipField.field_size + c
if self.check_ship(row, c): self.field[index] = "1"
ship_size += 1
ship_direction = ShipDirection.HORIZONTAL if self.ship_size in self.ships:
self.field[row * ShipField.field_size + c] = "" self.ships.remove(self.ship_size)
else: self.print_field()
break
self.set_ship_direction(ship_direction) if self.ship_size not in self.ships and len(self.ships) > 0:
self.set_ship_size(ship_size) self.ship_size = max(self.ships)
self.ships.append(ship_size)
def get_ship(self, row, col):
def shoot(self, row, col): if row < 0 or row > ShipField.field_size:
if row < 0 or row > ShipField.field_size - 1: return
return ShootResult.UNDEFINED if col < 0 or col > ShipField.field_size:
if col < 0 or col > ShipField.field_size - 1: return
return ShootResult.UNDEFINED
index = row * ShipField.field_size + col self.field[row * ShipField.field_size + col] = ""
if (self.field[index]).strip() == "":
self.field[index] = "0" ship_size = 1
return ShootResult.EMPTY ship_direction = ShipDirection.UNKNOWN
elif (self.field[index]).strip() == "1":
self.field[index] = "\\" # проверим вертикаль
if self.check_killed(row, col): for r in range(row + 1, ShipField.field_size):
return ShootResult.KILLED if self.check_ship(r, col):
return ShootResult.DAMAGED ship_size += 1
else: ship_direction = ShipDirection.VERTICAL
return ShootResult.UNDEFINED self.field[r * ShipField.field_size + col] = ""
else:
def check_ship(self, row, col): break
# функция должна возвражать тру, если в заданной клетке есть корабль
# в противном случае фолс for r in range(row - 1, -1, -1):
return self.field[row * ShipField.field_size + col].strip() == "1" if self.check_ship(r, col):
ship_size += 1
def check_damaged(self, row, col): ship_direction = ShipDirection.VERTICAL
return self.field[row * ShipField.field_size + col].strip() == "\\" self.field[row * ShipField.field_size + col] = ""
else:
def check_empty(self, row, col): break
cell = self.field[row * ShipField.field_size + col].strip()
return cell == "0" or cell == "" if ship_direction == ShipDirection.UNKNOWN:
def check_end(self): # проверим горизонталь
return "1" not in self.field for c in range(col + 1, ShipField.field_size):
if self.check_ship(row, c):
def check_possible(self, row, col): ship_size += 1
# Функция должна возвращать True, если можно поставить сюда корабль, ship_direction = ShipDirection.HORIZONTAL
# в противном случае - False self.field[row * ShipField.field_size + c] = ""
if self.ship_direction == ShipDirection.VERTICAL: else:
# Здесь мы знаем, что корабль помещается на поле. break
if ShipField.field_size - row >= self.ship_size:
# Теперь нужно проверить, не заблокировано ли какое-то из полей, for c in range(col - 1, -1, -1):
for r in range(row, row + self.ship_size): if self.check_ship(row, c):
if not self.check_blocked(r, col): ship_size += 1
return False ship_direction = ShipDirection.HORIZONTAL
return True self.field[row * ShipField.field_size + c] = ""
else:
if self.ship_direction == ShipDirection.HORIZONTAL: break
if ShipField.field_size - col >= self.ship_size: self.set_ship_direction(ship_direction)
for c in range(col, col + self.ship_size): self.set_ship_size(ship_size)
if not self.check_blocked(row, c): self.ships.append(ship_size)
return False
return True def shoot(self, row, col):
if row < 0 or row > ShipField.field_size - 1:
return False return ShootResult.UNDEFINED
if col < 0 or col > ShipField.field_size - 1:
def check_blocked(self, row, col): return ShootResult.UNDEFINED
# Функция возвращает True, если все клетки вокруг клетки с координатами row, col index = row * ShipField.field_size + col
# либо находятся за пределами поля, либо в них нет корабля/они пустые if (self.field[index]).strip() == "":
for r in range(row - 1, row + 2): self.field[index] = "0"
for c in range(col - 1, col + 2): return ShootResult.EMPTY
if 0 <= r < ShipField.field_size and 0 <= c < ShipField.field_size: elif (self.field[index]).strip() == "1":
cell = (self.field[r * ShipField.field_size + c]).strip() self.field[index] = "\\"
if cell != '' and cell != 'p': if self.check_killed(row, col):
return False return ShootResult.KILLED
return True return ShootResult.DAMAGED
else:
def set_ship_size(self, value): return ShootResult.UNDEFINED
if value is None:
return def check_ship(self, row, col):
# функция должна возвражать тру, если в заданной клетке есть корабль
if type(value) is str and value.isnumeric(): # в противном случае фолс
value = int(value) return self.field[row * ShipField.field_size + col].strip() == "1"
if type(value) is int and 1 <= value <= 4: def check_damaged(self, row, col):
self.ship_size = value return self.field[row * ShipField.field_size + col].strip() == "\\"
def set_ship_direction(self, value): def check_empty(self, row, col):
if value is None: cell = self.field[row * ShipField.field_size + col].strip()
return return cell == "0" or cell == ""
if type(value) is not ShipDirection: def check_end(self):
return return "1" not in self.field
if value != ShipDirection.UNKNOWN: def check_possible(self, row, col):
self.ship_direction = value # Функция должна возвращать True, если можно поставить сюда корабль,
# в противном случае - False
def toggle_ship_direction(self): if self.ship_direction == ShipDirection.VERTICAL:
if self.ship_direction == ShipDirection.VERTICAL: # Здесь мы знаем, что корабль помещается на поле.
self.ship_direction = ShipDirection.HORIZONTAL if ShipField.field_size - row >= self.ship_size:
else: # Теперь нужно проверить, не заблокировано ли какое-то из полей,
self.ship_direction = ShipDirection.VERTICAL for r in range(row, row + self.ship_size):
if not self.check_blocked(r, col):
def set_field_mode(self, value): return False
if value is None: return True
return
if self.ship_direction == ShipDirection.HORIZONTAL:
if type(value) is not ShipMode: if ShipField.field_size - col >= self.ship_size:
return for c in range(col, col + self.ship_size):
if not self.check_blocked(row, c):
self.field_mode = value return False
return True
def print_field(self):
print(self.ships) return False
for r in range(0, ShipField.field_size):
blocked_string = "" def check_blocked(self, row, col):
ship_string = "" # Функция возвращает True, если все клетки вокруг клетки с координатами row, col
for c in range(0, ShipField.field_size): # либо находятся за пределами поля, либо в них нет корабля/они пустые
blocked_string += str(self.check_blocked(r, c))[0] + ", " for r in range(row - 1, row + 2):
ship_string += self.field[r * ShipField.field_size + c] + ', ' for c in range(col - 1, col + 2):
print(ship_string[:-2]) if 0 <= r < ShipField.field_size and 0 <= c < ShipField.field_size:
# print(blocked_string[:-2] + ' ' + ship_string[:-2]) cell = (self.field[r * ShipField.field_size + c]).strip()
print("********************************************************************") if cell != '' and cell != 'p':
return False
@staticmethod return True
def convert_to_json(obj):
if isinstance(obj, ShipField): def set_ship_size(self, value):
result = copy.deepcopy(obj.__dict__) if value is None:
result['field_mode'] = obj.field_mode.value return
result['ship_direction'] = obj.ship_direction.value
return result if type(value) is str and value.isnumeric():
value = int(value)
if type(value) is int and 1 <= value <= 4:
self.ship_size = value
def set_ship_direction(self, value):
if value is None:
return
if type(value) is not ShipDirection:
return
if value != ShipDirection.UNKNOWN:
self.ship_direction = value
def toggle_ship_direction(self):
if self.ship_direction == ShipDirection.VERTICAL:
self.ship_direction = ShipDirection.HORIZONTAL
else:
self.ship_direction = ShipDirection.VERTICAL
def set_field_mode(self, value):
if value is None:
return
if type(value) is not ShipMode:
return
self.field_mode = value
def print_field(self):
print(self.ships)
for r in range(0, ShipField.field_size):
blocked_string = ""
ship_string = ""
for c in range(0, ShipField.field_size):
blocked_string += str(self.check_blocked(r, c))[0] + ", "
ship_string += self.field[r * ShipField.field_size + c] + ', '
print(ship_string[:-2])
# print(blocked_string[:-2] + ' ' + ship_string[:-2])
print("********************************************************************")
@staticmethod
def convert_to_json(obj):
if isinstance(obj, ShipField):
result = copy.deepcopy(obj.__dict__)
result['field_mode'] = obj.field_mode.value
result['ship_direction'] = obj.ship_direction.value
return result

View File

@ -1,17 +1,17 @@
from enum import Enum from enum import Enum
class ShipMode(Enum): class ShipMode(Enum):
PUT = 'PUT' PUT = 'PUT'
SHOOT = 'SHOOT' SHOOT = 'SHOOT'
INACTIVE = 'INACTIVE' INACTIVE = 'INACTIVE'
@staticmethod @staticmethod
def from_string(raw_value): def from_string(raw_value):
if raw_value: if raw_value:
value = raw_value.upper() value = raw_value.upper()
if value in ShipMode.__members__: if value in ShipMode.__members__:
return ShipMode[value] return ShipMode[value]
return ShipMode.INACTIVE return ShipMode.INACTIVE

View File

@ -1,12 +1,12 @@
from ShipField import ShipField from ShipField import ShipField
from tkinter import StringVar from tkinter import StringVar
class ShipView: class ShipView:
def __init__(self, ship_field, buttons, enemy): def __init__(self, ship_field, buttons, enemy):
self.ship_field = ship_field self.ship_field = ship_field
self.buttons = buttons self.buttons = buttons
self.remaining_ship_text = StringVar() self.remaining_ship_text = StringVar()
self.enemy = enemy self.enemy = enemy
self.active = False self.active = False

View File

@ -1,8 +1,8 @@
from enum import Enum from enum import Enum
class ShootResult(Enum): class ShootResult(Enum):
EMPTY = "EMPTY" EMPTY = "EMPTY"
DAMAGED = "DAMAGED" DAMAGED = "DAMAGED"
KILLED = "KILLED" KILLED = "KILLED"
UNDEFINED = "UNDEFINED" UNDEFINED = "UNDEFINED"

View File

@ -1,78 +1,78 @@
from ShipField import ShipField from ShipField import ShipField
def verify_value(actual, expected): def verify_value(actual, expected):
if actual == expected: if actual == expected:
print("OK") print("OK")
else: else:
print("ERROR") print("ERROR")
my_field = ShipField() my_field = ShipField()
print("set_ship_size()") print("set_ship_size()")
my_field.set_ship_size(1) my_field.set_ship_size(1)
verify_value(my_field.ship_size, 1) verify_value(my_field.ship_size, 1)
my_field.set_ship_size(0) my_field.set_ship_size(0)
my_field.set_ship_size(6) my_field.set_ship_size(6)
verify_value(my_field.ship_size, 1) verify_value(my_field.ship_size, 1)
my_field.set_ship_size([]) my_field.set_ship_size([])
my_field.set_ship_size("") my_field.set_ship_size("")
my_field.set_ship_size(None) my_field.set_ship_size(None)
my_field.set_ship_size(True) my_field.set_ship_size(True)
my_field.set_ship_size(False) my_field.set_ship_size(False)
verify_value(my_field.ship_size, 1) verify_value(my_field.ship_size, 1)
my_field.set_ship_size("2") my_field.set_ship_size("2")
verify_value(my_field.ship_size, 2) verify_value(my_field.ship_size, 2)
print() print()
print("set_ship_direction()") print("set_ship_direction()")
my_field.set_ship_direction(1) my_field.set_ship_direction(1)
verify_value(my_field.ship_direction, 1) verify_value(my_field.ship_direction, 1)
my_field.set_ship_direction(-1) my_field.set_ship_direction(-1)
my_field.set_ship_direction(6) my_field.set_ship_direction(6)
verify_value(my_field.ship_direction, 1) verify_value(my_field.ship_direction, 1)
my_field.set_ship_direction([]) my_field.set_ship_direction([])
my_field.set_ship_direction("") my_field.set_ship_direction("")
my_field.set_ship_direction(None) my_field.set_ship_direction(None)
my_field.set_ship_direction(True) my_field.set_ship_direction(True)
my_field.set_ship_direction(False) my_field.set_ship_direction(False)
verify_value(my_field.ship_direction, 1) verify_value(my_field.ship_direction, 1)
my_field.set_ship_direction("0") my_field.set_ship_direction("0")
verify_value(my_field.ship_direction, 0) verify_value(my_field.ship_direction, 0)
print() print()
print('toggle_field_mode()') print('toggle_field_mode()')
verify_value(my_field.field_mode, 0) verify_value(my_field.field_mode, 0)
my_field.toggle_field_mode() my_field.toggle_field_mode()
verify_value(my_field.field_mode, 1) verify_value(my_field.field_mode, 1)
my_field.toggle_field_mode() my_field.toggle_field_mode()
verify_value(my_field.field_mode, 0) verify_value(my_field.field_mode, 0)
print() print()
print("set_ship()") print("set_ship()")
verify_value(my_field.field[0], " ") verify_value(my_field.field[0], " ")
my_field.set_ship_size(1,) my_field.set_ship_size(1,)
my_field.set_ship_direction(0) my_field.set_ship_direction(0)
my_field.set_ship(0, 0) my_field.set_ship(0, 0)
verify_value(my_field.field[0], "1") verify_value(my_field.field[0], "1")
print() print()
my_field.set_ship_size(4) my_field.set_ship_size(4)
my_field.set_ship_direction(0) my_field.set_ship_direction(0)
my_field.set_ship(5, 5) my_field.set_ship(5, 5)
my_field.print_field() my_field.print_field()

View File

@ -1,287 +1,289 @@
import json import json
import os import os
import random import random
import time import time
from tkinter import * from tkinter import *
from tkinter import filedialog from tkinter import filedialog
from ShipView import ShipView from ShipView import ShipView
from ShipMode import ShipMode from ShipMode import ShipMode
from ShipField import ShipField from ShipField import ShipField
from GameMode import GameMode from GameMode import GameMode
from ShootResult import ShootResult from ShootResult import ShootResult
def create_view(window, enemy): def create_view(window, enemy):
field = ShipField() field = ShipField()
buttons = [] buttons = []
view = ShipView(field, buttons, enemy) view = ShipView(field, buttons, enemy)
for r in range(0, field.field_size): for r in range(0, field.field_size):
for c in range(0, field.field_size): for c in range(0, field.field_size):
btn = Button(window, text='', width=5, height=2) btn = Button(window, text='', width=5, height=2)
btn.bind('<Button-1>', lambda e, x=r, y=c: left_button_click(view, x, y)) btn.bind('<Button-1>', lambda e, x=r, y=c: left_button_click(view, x, y))
btn.bind('<Button-3>', lambda e: right_button_click(view)) btn.bind('<Button-3>', lambda e: right_button_click(view))
btn.bind('<Enter>', lambda e, x=r, y=c: button_enter(view, x, y)) btn.bind('<Enter>', lambda e, x=r, y=c: button_enter(view, x, y))
buttons.append(btn) buttons.append(btn)
colorize(view) colorize(view)
return view return view
def show_view(view, col_offset=0, row_offset=0): def show_view(view, col_offset=0, row_offset=0):
field_size = view.ship_field.field_size field_size = view.ship_field.field_size
for r in range(0, field_size): for r in range(0, field_size):
for c in range(0, field_size): for c in range(0, field_size):
btn = view.buttons[r * field_size +c] btn = view.buttons[r * field_size +c]
btn.grid(column=c + col_offset, row=r + row_offset) btn.grid(column=c + col_offset, row=r + row_offset)
def hide_view(view): def hide_view(view):
for button in view.buttons: for button in view.buttons:
button.grid_forget() button.grid_forget()
def colorize(view): def colorize(view):
field = view.ship_field field = view.ship_field
for i in range(len(field.field)): for i in range(len(field.field)):
bg = "white" bg = "white"
if field.field[i] == "1" and not view.enemy: if field.field[i] == "1" and not view.enemy:
bg = 'pink' bg = 'pink'
if field.field[i] == "\\": if field.field[i] == "\\":
bg = 'grey' bg = 'grey'
if field.field[i] == "0": if field.field[i] == "x":
bg = 'black' bg = 'red'
if field.field[i] == "p": if field.field[i] == "0":
bg = 'blue' bg = 'black'
if field.field[i] == "r": if field.field[i] == "p":
bg = 'red' bg = 'blue'
if "+" in field.field[i] and view.enemy: if field.field[i] == "r":
bg = 'orange' bg = 'red'
if "+" in field.field[i] and view.enemy:
view.buttons[i].configure(bg=bg) bg = 'orange'
refresh_remaining_ships_label(view) view.buttons[i].configure(bg=bg)
refresh_remaining_ships_label(view)
def keypress_handler(e):
if e.keysym.isnumeric():
if my_view.active: def keypress_handler(e):
my_view.ship_field.set_ship_size(int(e.keysym)) if e.keysym.isnumeric():
elif enemy_view.active: if my_view.active:
enemy_view.ship_field.set_ship_size(int(e.keysym)) my_view.ship_field.set_ship_size(int(e.keysym))
elif enemy_view.active:
enemy_view.ship_field.set_ship_size(int(e.keysym))
def left_button_click(view, row, col):
action_result = view.ship_field.action(row, col) def left_button_click(view, row, col):
if action_result and view.enemy and game_mode == GameMode.BATTLE: action_result = view.ship_field.action(row, col)
# Ход соперника
enemy_shoot_result = ShootResult.UNDEFINED if action_result and view.enemy and game_mode == GameMode.BATTLE:
# Ход соперника
while enemy_shoot_result != ShootResult.EMPTY: enemy_shoot_result = ShootResult.UNDEFINED
my_row = random.randint(0, ShipField.field_size - 1)
my_col = random.randint(0, ShipField.field_size - 1) while enemy_shoot_result != ShootResult.EMPTY:
my_row = random.randint(0, ShipField.field_size - 1)
enemy_shoot_result = my_view.ship_field.shoot(my_row, my_col) my_col = random.randint(0, ShipField.field_size - 1)
if game_mode == GameMode.BATTLE and my_view.ship_field.check_end():
next_game_mode() enemy_shoot_result = my_view.ship_field.shoot(my_row, my_col)
return if game_mode == GameMode.BATTLE and my_view.ship_field.check_end():
colorize(my_view) next_game_mode()
return
if game_mode == GameMode.BATTLE and view.ship_field.check_end(): colorize(my_view)
next_game_mode()
return if game_mode == GameMode.BATTLE and view.ship_field.check_end():
next_game_mode()
colorize(view) return
colorize(view)
def right_button_click(view):
view.ship_field.toggle_ship_direction()
colorize(view) def right_button_click(view):
view.ship_field.toggle_ship_direction()
colorize(view)
def button_enter(view, row, col):
if view.enemy:
my_view.ship_field.clear_marker() def button_enter(view, row, col):
enemy_view.ship_field.target(row, col) if view.enemy:
my_view.ship_field.clear_marker()
enemy_view.active = True enemy_view.ship_field.target(row, col)
my_view.active = False
else: enemy_view.active = True
enemy_view.ship_field.clear_marker() my_view.active = False
my_view.ship_field.target(row, col) else:
enemy_view.ship_field.clear_marker()
enemy_view.active = False my_view.ship_field.target(row, col)
my_view.active = True
enemy_view.active = False
colorize(my_view) my_view.active = True
colorize(enemy_view)
colorize(my_view)
colorize(enemy_view)
def savebutton_click(view):
file_path = filedialog.asksaveasfilename(filetypes=[("JSON files", "*.json")])
if file_path: def savebutton_click(view):
with open(file_path, "w") as f: file_path = filedialog.asksaveasfilename(filetypes=[("JSON files", "*.json")])
json.dump({"shipField": view.ship_field}, f, default=ShipField.convert_to_json) if file_path:
with open(file_path, "w") as f:
json.dump({"shipField": view.ship_field}, f, default=ShipField.convert_to_json)
def loadbutton_click(view):
file_path = filedialog.askopenfilename(filetypes=[('JSON files', '*.json')])
def loadbutton_click(view):
load_field(view, file_path) file_path = filedialog.askopenfilename(filetypes=[('JSON files', '*.json')])
load_field(view, file_path)
def load_field(view, file_path):
if os.path.isfile(file_path):
with open(file_path) as lines: def load_field(view, file_path):
view.ship_field.from_json(json.load(lines)['shipField']) if os.path.isfile(file_path):
with open(file_path) as lines:
colorize(view) view.ship_field.from_json(json.load(lines)['shipField'])
def refresh_remaining_ships_label(view): colorize(view)
text = ''
for i in range(1, 5): def refresh_remaining_ships_label(view):
count = view.ship_field.ships.count(i) text = ''
if count > 0: for i in range(1, 5):
text += f'{"[]" * i}: {count}, ' count = view.ship_field.ships.count(i)
view.remaining_ship_text.set(text[:-2]) if count > 0:
text += f'{"[]" * i}: {count}, '
view.remaining_ship_text.set(text[:-2])
def next_game_mode():
global game_mode
def next_game_mode():
if game_mode == GameMode.MENU: global game_mode
game_mode = GameMode.PLAN
elif game_mode == GameMode.PLAN: if game_mode == GameMode.MENU:
game_mode = GameMode.BATTLE game_mode = GameMode.PLAN
elif game_mode == GameMode.BATTLE: elif game_mode == GameMode.PLAN:
game_mode = GameMode.END game_mode = GameMode.BATTLE
elif game_mode == GameMode.BATTLE:
update_game_mode() game_mode = GameMode.END
update_game_mode()
def update_game_mode():
global game_mode
def update_game_mode():
if game_mode == GameMode.MENU: global game_mode
window.geometry('400x280')
my_view.ship_field.set_field_mode(ShipMode.INACTIVE) if game_mode == GameMode.MENU:
enemy_view.ship_field.set_field_mode(ShipMode.INACTIVE) window.geometry('400x280')
my_view.ship_field.set_field_mode(ShipMode.INACTIVE)
lbl_lower_enemy_horizontal.grid_forget() enemy_view.ship_field.set_field_mode(ShipMode.INACTIVE)
lbl_lower_horizontal.grid_forget()
lbl_lower_enemy_horizontal.grid_forget()
savebutton.grid_forget() lbl_lower_horizontal.grid_forget()
loadbutton.grid_forget()
savebutton.grid_forget()
start_button.grid(column=start_column_enemy_field, row=load_button_row, columnspan=4) loadbutton.grid_forget()
load_game_button.grid(column=start_column_enemy_field, row=load_button_row + 1, columnspan=4)
exit_button.grid(column=start_column_enemy_field, row=load_button_row + 2, columnspan=4) start_button.grid(column=start_column_enemy_field, row=load_button_row, columnspan=4)
load_game_button.grid(column=start_column_enemy_field, row=load_button_row + 1, columnspan=4)
hide_view(my_view) exit_button.grid(column=start_column_enemy_field, row=load_button_row + 2, columnspan=4)
hide_view(enemy_view)
hide_view(my_view)
elif game_mode == GameMode.PLAN: hide_view(enemy_view)
window.geometry('1020x640')
elif game_mode == GameMode.PLAN:
load_field(enemy_view, "default.json") window.geometry('1020x640')
my_view.ship_field.set_field_mode(ShipMode.PUT) load_field(enemy_view, "default.json")
enemy_view.ship_field.set_field_mode(ShipMode.INACTIVE)
my_view.ship_field.set_field_mode(ShipMode.PUT)
lbl_lower_enemy_horizontal.grid(column=start_column_my_field, row=row_horizontal_separator, columnspan=10) enemy_view.ship_field.set_field_mode(ShipMode.INACTIVE)
lbl_lower_horizontal.grid(column=start_column_enemy_field, row=row_horizontal_separator, columnspan=10)
lbl_lower_enemy_horizontal.grid(column=start_column_my_field, row=row_horizontal_separator, columnspan=10)
savebutton.grid(column=start_column_my_field, row=load_button_row, columnspan=4) lbl_lower_horizontal.grid(column=start_column_enemy_field, row=row_horizontal_separator, columnspan=10)
loadbutton.grid(column=start_column_my_field + 6, row=load_button_row, columnspan=4)
savebutton.grid(column=start_column_my_field, row=load_button_row, columnspan=4)
start_button.grid(column=start_column_my_field + 11, row=load_button_row, columnspan=4) loadbutton.grid(column=start_column_my_field + 6, row=load_button_row, columnspan=4)
load_game_button.grid_forget()
exit_button.grid_forget() start_button.grid(column=start_column_my_field + 11, row=load_button_row, columnspan=4)
load_game_button.grid_forget()
show_view(my_view, start_column_my_field, start_row_my_field) exit_button.grid_forget()
show_view(enemy_view, start_column_enemy_field, start_row_enemy_field)
show_view(my_view, start_column_my_field, start_row_my_field)
elif game_mode == GameMode.BATTLE: show_view(enemy_view, start_column_enemy_field, start_row_enemy_field)
window.geometry('1020x640')
my_view.ship_field.set_field_mode(ShipMode.INACTIVE) elif game_mode == GameMode.BATTLE:
enemy_view.ship_field.set_field_mode(ShipMode.SHOOT) window.geometry('1020x640')
my_view.ship_field.set_field_mode(ShipMode.INACTIVE)
lbl_lower_enemy_horizontal.grid_forget() enemy_view.ship_field.set_field_mode(ShipMode.SHOOT)
lbl_lower_horizontal.grid_forget()
lbl_lower_enemy_horizontal.grid_forget()
savebutton.grid_forget() lbl_lower_horizontal.grid_forget()
loadbutton.grid_forget()
savebutton.grid_forget()
start_button.grid_forget() loadbutton.grid_forget()
load_game_button.grid_forget()
exit_button.grid_forget() start_button.grid_forget()
load_game_button.grid_forget()
show_view(my_view, start_column_my_field, start_row_my_field) exit_button.grid_forget()
show_view(enemy_view, start_column_enemy_field, start_row_enemy_field)
show_view(my_view, start_column_my_field, start_row_my_field)
elif game_mode == GameMode.END: show_view(enemy_view, start_column_enemy_field, start_row_enemy_field)
window.geometry('400x280')
my_view.ship_field.set_field_mode(ShipMode.INACTIVE) elif game_mode == GameMode.END:
enemy_view.ship_field.set_field_mode(ShipMode.INACTIVE) window.geometry('400x280')
my_view.ship_field.set_field_mode(ShipMode.INACTIVE)
lbl_lower_enemy_horizontal.grid_forget() enemy_view.ship_field.set_field_mode(ShipMode.INACTIVE)
lbl_lower_horizontal.grid_forget()
lbl_lower_enemy_horizontal.grid_forget()
savebutton.grid_forget() lbl_lower_horizontal.grid_forget()
loadbutton.grid_forget()
savebutton.grid_forget()
start_button.grid_forget() loadbutton.grid_forget()
load_game_button.grid_forget()
exit_button.grid_forget() start_button.grid_forget()
load_game_button.grid_forget()
hide_view(my_view) exit_button.grid_forget()
hide_view(enemy_view)
hide_view(my_view)
lbl_left_vertical.grid(column=start_column_my_field - 1, row=start_row_my_field) hide_view(enemy_view)
lbl_center_vertical.grid(column=col_vertical_separator, row=start_row_my_field)
lbl_upper_horizontal.grid(column=start_column_my_field, row=start_row_my_field - 1) lbl_left_vertical.grid(column=start_column_my_field - 1, row=start_row_my_field)
lbl_center_vertical.grid(column=col_vertical_separator, row=start_row_my_field)
lbl_upper_horizontal.grid(column=start_column_my_field, row=start_row_my_field - 1)
window = Tk()
window.title("Ship Craft!")
window.bind_all('<KeyPress>', keypress_handler) window = Tk()
window.title("Ship Craft!")
start_column_my_field = 1 window.bind_all('<KeyPress>', keypress_handler)
start_row_my_field = 1
start_column_my_field = 1
start_column_enemy_field = start_column_my_field + ShipField.field_size + 1 start_row_my_field = 1
start_row_enemy_field = start_row_my_field
start_column_enemy_field = start_column_my_field + ShipField.field_size + 1
col_vertical_separator = start_column_my_field + ShipField.field_size start_row_enemy_field = start_row_my_field
row_horizontal_separator = start_row_my_field + ShipField.field_size
col_vertical_separator = start_column_my_field + ShipField.field_size
load_button_row = start_row_my_field + ShipField.field_size + 1 row_horizontal_separator = start_row_my_field + ShipField.field_size
my_view = create_view(window, False) load_button_row = start_row_my_field + ShipField.field_size + 1
enemy_view = create_view(window, True)
my_view = create_view(window, False)
lbl_left_vertical = Label(window, text='', width=5, height=2) enemy_view = create_view(window, True)
lbl_center_vertical = Label(window, text='', width=5, height=2)
lbl_upper_horizontal = Label(window, text='', width=5, height=2) lbl_left_vertical = Label(window, text='', width=5, height=2)
lbl_center_vertical = Label(window, text='', width=5, height=2)
lbl_upper_horizontal = Label(window, text='', width=5, height=2)
lbl_lower_horizontal = Label(window, text='', width=50, height=2, textvariable=my_view.remaining_ship_text)
lbl_lower_enemy_horizontal = Label(window, text='', width=50, height=2, textvariable=enemy_view.remaining_ship_text)
lbl_lower_horizontal = Label(window, text='', width=50, height=2, textvariable=my_view.remaining_ship_text)
lbl_lower_enemy_horizontal = Label(window, text='', width=50, height=2, textvariable=enemy_view.remaining_ship_text)
savebutton = Button(window, text='Save', width=20, height=2, command=lambda: savebutton_click(my_view))
loadbutton = Button(window, text='Load', width=20, height=2, command=lambda: loadbutton_click(my_view))
savebutton = Button(window, text='Save', width=20, height=2, command=lambda: savebutton_click(my_view))
start_button = Button(window, text='START', width=20, height=2, command=next_game_mode) loadbutton = Button(window, text='Load', width=20, height=2, command=lambda: loadbutton_click(my_view))
load_game_button = Button(window, text='LOAD', width=20, height=2)
exit_button = Button(window, text='EXIT', width=20, height=2) start_button = Button(window, text='START', width=20, height=2, command=next_game_mode)
load_game_button = Button(window, text='LOAD', width=20, height=2)
exit_button = Button(window, text='EXIT', width=20, height=2)
game_mode = GameMode.MENU
update_game_mode()
game_mode = GameMode.MENU
window.mainloop() update_game_mode()
window.mainloop()

View File

@ -1,281 +1,281 @@
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 ShipMode import ShipMode
from ShipDirection import ShipDirection from ShipDirection import ShipDirection
class TestShipField(TestCase): class TestShipField(TestCase):
def test_set_ship_size(self): def test_set_ship_size(self):
ship_field = ShipField() # Заводим объект типа ShipField ship_field = ShipField() # Заводим объект типа ShipField
ship_field.set_ship_size(1) ship_field.set_ship_size(1)
self.assertEqual(ship_field.ship_size, 1) self.assertEqual(ship_field.ship_size, 1)
ship_field.set_ship_size(2) ship_field.set_ship_size(2)
self.assertEqual(ship_field.ship_size, 2) self.assertEqual(ship_field.ship_size, 2)
ship_field.set_ship_size(3) ship_field.set_ship_size(3)
self.assertEqual(ship_field.ship_size, 3) self.assertEqual(ship_field.ship_size, 3)
ship_field.set_ship_size(4) ship_field.set_ship_size(4)
self.assertEqual(ship_field.ship_size, 4) self.assertEqual(ship_field.ship_size, 4)
def test_set_ship_size_outofrange(self): def test_set_ship_size_outofrange(self):
ship_field = ShipField() # Заводим объект типа ShipField ship_field = ShipField() # Заводим объект типа ShipField
ship_field.set_ship_size(1) ship_field.set_ship_size(1)
ship_field.set_ship_size(-1) ship_field.set_ship_size(-1)
self.assertEqual(ship_field.ship_size, 1) self.assertEqual(ship_field.ship_size, 1)
ship_field.set_ship_size(0) ship_field.set_ship_size(0)
self.assertEqual(ship_field.ship_size, 1) self.assertEqual(ship_field.ship_size, 1)
ship_field.set_ship_size(6) ship_field.set_ship_size(6)
self.assertEqual(ship_field.ship_size, 1) self.assertEqual(ship_field.ship_size, 1)
ship_field.set_ship_size(100) ship_field.set_ship_size(100)
self.assertEqual(ship_field.ship_size, 1) self.assertEqual(ship_field.ship_size, 1)
def test_set_ship_size_wrongtype(self): def test_set_ship_size_wrongtype(self):
ship_field = ShipField() # Заводим объект типа ShipField ship_field = ShipField() # Заводим объект типа ShipField
ship_field.set_ship_size(1) ship_field.set_ship_size(1)
ship_field.set_ship_size([]) ship_field.set_ship_size([])
self.assertEqual(ship_field.ship_size, 1) self.assertEqual(ship_field.ship_size, 1)
ship_field.set_ship_size('') ship_field.set_ship_size('')
self.assertEqual(ship_field.ship_size, 1) self.assertEqual(ship_field.ship_size, 1)
ship_field.set_ship_size(None) ship_field.set_ship_size(None)
self.assertEqual(ship_field.ship_size, 1) self.assertEqual(ship_field.ship_size, 1)
ship_field.set_ship_size(False) ship_field.set_ship_size(False)
self.assertEqual(ship_field.ship_size, 1) self.assertEqual(ship_field.ship_size, 1)
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, ShipMode.PUT) # Проверяем, что изначальное значение 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, ShipMode.SHOOT) # Проверяем, что 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, ShipMode.PUT) # Проверяем, что field_mode принял желаемое значение self.assertEqual(ship_field.field_mode, ShipMode.PUT) # Проверяем, что field_mode принял желаемое значение
def test_action(self): def test_action(self):
self.fail() self.fail()
def test_target_ShipMode_PUT(self): def test_target_ShipMode_PUT(self):
ship_field = ShipField() ship_field = ShipField()
ship_field.set_ship_size(3) ship_field.set_ship_size(3)
ship_field.set_ship_direction(ShipDirection.HORIZONTAL) ship_field.set_ship_direction(ShipDirection.HORIZONTAL)
index = 5 * ship_field.field_size + 5 index = 5 * ship_field.field_size + 5
old_field_string = str.join(' ', ship_field.field) old_field_string = str.join(' ', ship_field.field)
ship_field.target(5, 5) ship_field.target(5, 5)
field_after_target = [ship_field.field[index], ship_field.field[index + 1], ship_field.field[index + 2]] field_after_target = [ship_field.field[index], ship_field.field[index + 1], ship_field.field[index + 2]]
ship_field.field[index] = ' ' ship_field.field[index] = ' '
ship_field.field[index + 1] = ' ' ship_field.field[index + 1] = ' '
ship_field.field[index + 2] = ' ' ship_field.field[index + 2] = ' '
new_field_string = str.join(' ', ship_field.field) new_field_string = str.join(' ', ship_field.field)
self.assertListEqual(['p', 'p', 'p'], field_after_target) self.assertListEqual(['p', 'p', 'p'], field_after_target)
self.assertNotIn('p', new_field_string) self.assertNotIn('p', new_field_string)
self.assertEqual(new_field_string, old_field_string) self.assertEqual(new_field_string, old_field_string)
def test_target_ShipMode_SHOOT(self): def test_target_ShipMode_SHOOT(self):
ship_field = ShipField() ship_field = ShipField()
ship_field.toggle_field_mode() ship_field.toggle_field_mode()
index = 5 * ship_field.field_size + 5 index = 5 * ship_field.field_size + 5
old_field_string = str.join(' ', ship_field.field) old_field_string = str.join(' ', ship_field.field)
ship_field.target(5, 5) ship_field.target(5, 5)
field_after_target = ship_field.field[index] field_after_target = ship_field.field[index]
ship_field.field[index] = ship_field.field[index].replace('+', '') ship_field.field[index] = ship_field.field[index].replace('+', '')
new_field_string = str.join(' ', ship_field.field) new_field_string = str.join(' ', ship_field.field)
self.assertIn('+', field_after_target) self.assertIn('+', field_after_target)
self.assertNotIn('+', new_field_string) self.assertNotIn('+', new_field_string)
self.assertEqual(new_field_string, old_field_string) self.assertEqual(new_field_string, old_field_string)
def get_ship(self): def get_ship(self):
self.fail() self.fail()
def test_clear_marker(self): def test_clear_marker(self):
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.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) self.assertNotIn('r', ship_field.field)
def test_shoot_empty(self): def test_shoot_empty(self):
ship_field = ShipField() ship_field = ShipField()
self.assertEqual(ship_field.field[0].strip(), '') self.assertEqual(ship_field.field[0].strip(), '')
result = ship_field.shoot(0, 0) result = ship_field.shoot(0, 0)
self.assertEqual(ship_field.field[0].strip(), '0') self.assertEqual(ship_field.field[0].strip(), '0')
self.assertEqual(result, ShootResult.EMPTY) self.assertEqual(result, ShootResult.EMPTY)
def test_shoot_ship(self): def test_shoot_ship(self):
ship_field = ShipField() ship_field = ShipField()
ship_field.field[0] = '1' ship_field.field[0] = '1'
result = ship_field.shoot(0, 0) result = ship_field.shoot(0, 0)
self.assertEqual(ship_field.field[0].strip(), '\\') self.assertEqual(ship_field.field[0].strip(), '\\')
self.assertEqual(result, ShootResult.DAMAGED) self.assertEqual(result, ShootResult.DAMAGED)
def test_shoot_unknown(self): def test_shoot_unknown(self):
ship_field = ShipField() ship_field = ShipField()
ship_field.field[0] = 'x' ship_field.field[0] = 'x'
result = ship_field.shoot(0, 0) result = ship_field.shoot(0, 0)
self.assertEqual(ship_field.field[0].strip(), 'x') self.assertEqual(ship_field.field[0].strip(), 'x')
self.assertEqual(result, ShootResult.UNDEFINED) self.assertEqual(result, ShootResult.UNDEFINED)
def test_shoot_outofrange(self): def test_shoot_outofrange(self):
ship_field = ShipField() ship_field = ShipField()
old_field_string = str.join(' ', ship_field.field) old_field_string = str.join(' ', ship_field.field)
result = ship_field.shoot(-1, -1) result = ship_field.shoot(-1, -1)
self.assertEqual(result, ShootResult.UNDEFINED) self.assertEqual(result, ShootResult.UNDEFINED)
result = ship_field.shoot(-1, 0) result = ship_field.shoot(-1, 0)
self.assertEqual(result, ShootResult.UNDEFINED) self.assertEqual(result, ShootResult.UNDEFINED)
result = ship_field.shoot(1000, 1000) result = ship_field.shoot(1000, 1000)
self.assertEqual(result, ShootResult.UNDEFINED) self.assertEqual(result, ShootResult.UNDEFINED)
result = ship_field.shoot(0, 1000) result = ship_field.shoot(0, 1000)
self.assertEqual(result, ShootResult.UNDEFINED) self.assertEqual(result, ShootResult.UNDEFINED)
new_field_string = str.join(' ', ship_field.field) new_field_string = str.join(' ', ship_field.field)
self.assertEqual(new_field_string, old_field_string) self.assertEqual(new_field_string, old_field_string)
def test_check_possible_false(self): def test_check_possible_false(self):
# arrangement установка # arrangement установка
ship_field = ShipField() ship_field = ShipField()
ship_field.set_ship_size(4) ship_field.set_ship_size(4)
ship_field.set_ship_direction(ShipDirection.HORIZONTAL) ship_field.set_ship_direction(ShipDirection.HORIZONTAL)
# action действие # action действие
ship_field.set_ship(5, 3) ship_field.set_ship(5, 3)
# assertion проверка занятых # assertion проверка занятых
self.assertEqual(ship_field.check_possible(5, 3), False) 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, 4), False)
self.assertEqual(ship_field.check_possible(5, 5), 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(5, 6), False)
# проверка строки ниже # проверка строки ниже
self.assertEqual(ship_field.check_possible(6, 3), 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, 4), False)
self.assertEqual(ship_field.check_possible(6, 5), 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(6, 6), False)
# проверка строки выше # проверка строки выше
self.assertEqual(ship_field.check_possible(4, 3), False) self.assertEqual(ship_field.check_possible(4, 3), False)
self.assertEqual(ship_field.check_possible(4, 4), False) self.assertEqual(ship_field.check_possible(4, 4), False)
self.assertEqual(ship_field.check_possible(4, 5), False) self.assertEqual(ship_field.check_possible(4, 5), False)
self.assertEqual(ship_field.check_possible(4, 6), False) self.assertEqual(ship_field.check_possible(4, 6), False)
def test_check_possible_true(self): def test_check_possible_true(self):
# arrangement установка # arrangement установка
ship_field = ShipField() ship_field = ShipField()
ship_field.set_ship_size(4) ship_field.set_ship_size(4)
ship_field.set_ship_direction(ShipDirection.HORIZONTAL) ship_field.set_ship_direction(ShipDirection.HORIZONTAL)
# action действие # action действие
ship_field.set_ship(5, 3) ship_field.set_ship(5, 3)
# проверка свободных ниже на 2 строки # проверка свободных ниже на 2 строки
self.assertEqual(ship_field.check_possible(7, 3), True) 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, 4), True)
self.assertEqual(ship_field.check_possible(7, 5), True) self.assertEqual(ship_field.check_possible(7, 5), True)
self.assertEqual(ship_field.check_possible(7, 6), True) self.assertEqual(ship_field.check_possible(7, 6), True)
# проверка свободных ВЫШЕ на 2 строки # проверка свободных ВЫШЕ на 2 строки
self.assertEqual(ship_field.check_possible(3, 3), True) self.assertEqual(ship_field.check_possible(3, 3), True)
self.assertEqual(ship_field.check_possible(3, 4), True) self.assertEqual(ship_field.check_possible(3, 4), True)
self.assertEqual(ship_field.check_possible(3, 5), True) self.assertEqual(ship_field.check_possible(3, 5), True)
self.assertEqual(ship_field.check_possible(3, 6), True) self.assertEqual(ship_field.check_possible(3, 6), True)
def test_check_blocked(self): def test_check_blocked(self):
# arrangement установка # arrangement установка
ship_field = ShipField() ship_field = ShipField()
ship_field.set_ship_size(4) ship_field.set_ship_size(4)
ship_field.set_ship_direction(ShipDirection.HORIZONTAL) ship_field.set_ship_direction(ShipDirection.HORIZONTAL)
# action действие # action действие
ship_field.set_ship(5, 3) ship_field.set_ship(5, 3)
# assertion проверка занятых # assertion проверка занятых
self.assertEqual(ship_field.check_blocked(5, 3), False) self.assertEqual(ship_field.check_blocked(5, 3), False)
self.assertEqual(ship_field.check_blocked(5, 4), False) self.assertEqual(ship_field.check_blocked(5, 4), False)
self.assertEqual(ship_field.check_blocked(5, 5), False) self.assertEqual(ship_field.check_blocked(5, 5), False)
self.assertEqual(ship_field.check_blocked(5, 6), False) self.assertEqual(ship_field.check_blocked(5, 6), False)
#проверка строки ниже #проверка строки ниже
self.assertEqual(ship_field.check_blocked(6, 3), False) self.assertEqual(ship_field.check_blocked(6, 3), False)
self.assertEqual(ship_field.check_blocked(6, 4), False) self.assertEqual(ship_field.check_blocked(6, 4), False)
self.assertEqual(ship_field.check_blocked(6, 5), False) self.assertEqual(ship_field.check_blocked(6, 5), False)
self.assertEqual(ship_field.check_blocked(6, 7), False) self.assertEqual(ship_field.check_blocked(6, 7), False)
#проверка свободных ниже на 2 строки #проверка свободных ниже на 2 строки
self.assertEqual(ship_field.check_blocked(7, 3), True) self.assertEqual(ship_field.check_blocked(7, 3), True)
self.assertEqual(ship_field.check_blocked(7, 4), True) self.assertEqual(ship_field.check_blocked(7, 4), True)
self.assertEqual(ship_field.check_blocked(7, 5), True) self.assertEqual(ship_field.check_blocked(7, 5), True)
self.assertEqual(ship_field.check_blocked(7, 6), True) self.assertEqual(ship_field.check_blocked(7, 6), True)
def test_set_ship_direction(self): def test_set_ship_direction(self):
ship_field = ShipField() # Заводим объект типа ShipField ship_field = ShipField() # Заводим объект типа ShipField
ship_field.set_ship_direction(ShipDirection.HORIZONTAL) ship_field.set_ship_direction(ShipDirection.HORIZONTAL)
self.assertEqual(ship_field.ship_direction, ShipDirection.HORIZONTAL) self.assertEqual(ship_field.ship_direction, ShipDirection.HORIZONTAL)
ship_field.set_ship_direction(ShipDirection.VERTICAL) ship_field.set_ship_direction(ShipDirection.VERTICAL)
self.assertEqual(ship_field.ship_direction, ShipDirection.VERTICAL) self.assertEqual(ship_field.ship_direction, ShipDirection.VERTICAL)
def test_set_ship_direction_outofrange(self): def test_set_ship_direction_outofrange(self):
ship_field = ShipField() # Заводим объект типа ShipField ship_field = ShipField() # Заводим объект типа ShipField
ship_field.set_ship_direction(ShipDirection.HORIZONTAL) ship_field.set_ship_direction(ShipDirection.HORIZONTAL)
ship_field.set_ship_direction(-1) ship_field.set_ship_direction(-1)
ship_field.set_ship_direction(2) ship_field.set_ship_direction(2)
self.assertEqual(ship_field.ship_direction, ShipDirection.HORIZONTAL) self.assertEqual(ship_field.ship_direction, ShipDirection.HORIZONTAL)
def test_set_ship_direction_wrongtype(self): def test_set_ship_direction_wrongtype(self):
ship_field = ShipField() # Заводим объект типа ShipField ship_field = ShipField() # Заводим объект типа ShipField
ship_field.set_ship_direction(ShipDirection.HORIZONTAL) ship_field.set_ship_direction(ShipDirection.HORIZONTAL)
ship_field.set_ship_direction(None) ship_field.set_ship_direction(None)
ship_field.set_ship_direction([2]) ship_field.set_ship_direction([2])
ship_field.set_ship_direction({}) ship_field.set_ship_direction({})
self.assertEqual(ship_field.ship_direction, ShipDirection.HORIZONTAL) self.assertEqual(ship_field.ship_direction, ShipDirection.HORIZONTAL)
def test_toggle_ship_direction(self): def test_toggle_ship_direction(self):
# arrangement установка # arrangement установка
ship_field = ShipField() ship_field = ShipField()
ship_field.set_ship_direction(ShipDirection.VERTICAL) ship_field.set_ship_direction(ShipDirection.VERTICAL)
# action действие # action действие
ship_field.toggle_ship_direction() ship_field.toggle_ship_direction()
# assertion проверка # assertion проверка
self.assertEqual(ship_field.ship_direction, ShipDirection.HORIZONTAL) self.assertEqual(ship_field.ship_direction, ShipDirection.HORIZONTAL)
ship_field.toggle_ship_direction() ship_field.toggle_ship_direction()
self.assertEqual(ship_field.ship_direction, ShipDirection.VERTICAL) self.assertEqual(ship_field.ship_direction, ShipDirection.VERTICAL)
def test_set_ship(self): def test_set_ship(self):
# arrangement установка # arrangement установка
ship_field = ShipField() ship_field = ShipField()
ship_field.set_ship_size(4) ship_field.set_ship_size(4)
ship_field.set_ship_direction(ShipDirection.HORIZONTAL) ship_field.set_ship_direction(ShipDirection.HORIZONTAL)
# action действие # action действие
ship_field.set_ship(5, 3) ship_field.set_ship(5, 3)
# assertion проверка # assertion проверка
self.assertEqual(ship_field.field[53].strip(), '1') self.assertEqual(ship_field.field[53].strip(), '1')
self.assertEqual(ship_field.field[54].strip(), '1') self.assertEqual(ship_field.field[54].strip(), '1')
self.assertEqual(ship_field.field[55].strip(), '1') self.assertEqual(ship_field.field[55].strip(), '1')
self.assertEqual(ship_field.field[56].strip(), '1') self.assertEqual(ship_field.field[56].strip(), '1')
def test_set_ship_size4_vertical_outofrange(self): def test_set_ship_size4_vertical_outofrange(self):
# arrangement установка # arrangement установка
ship_field = ShipField() ship_field = ShipField()
ship_field.set_ship_size(4) ship_field.set_ship_size(4)
ship_field.set_ship_direction(ShipDirection.VERTICAL) ship_field.set_ship_direction(ShipDirection.VERTICAL)
old_field_string = str.join(" ", ship_field.field) old_field_string = str.join(" ", ship_field.field)
# action действие # action действие
ship_field.set_ship(7, 3) ship_field.set_ship(7, 3)
# assertion проверка # assertion проверка
new_field_string = str.join(" ", ship_field.field) new_field_string = str.join(" ", ship_field.field)
self.assertEqual(new_field_string, old_field_string) self.assertEqual(new_field_string, old_field_string)