Merge remote-tracking branch 'origin/main'

This commit is contained in:
Artur Savitskiy 2024-04-09 20:00:41 +02:00
commit ce5dcdc592
8 changed files with 127 additions and 185 deletions

162
.gitignore vendored
View File

@ -1,162 +0,0 @@
# ---> Python
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/

14
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,14 @@
{
"python.testing.unittestArgs": [
"-v",
"-s",
"./HNC",
"-p",
"*_test.py"
],
"python.testing.pytestEnabled": true,
"python.testing.unittestEnabled": false,
"python.testing.pytestArgs": [
"."
]
}

View File

@ -15,15 +15,31 @@ class ShipField:
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '] ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']
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 = 0
self.ship_size = 4 self.ship_size = 4
self.ship_direction = 0 self.ship_direction = 0
def __getitem__(self, item):
if item is None:
return None
if type(item) is not int and item.isnumeric():
item = int(item)
if type(item) is int and 0 <= item < len(self.field):
return self.field[item]
return None
def action(self, row, col): def action(self, row, col):
self.clear_marker()
if self.field_mode == 0: if self.field_mode == 0:
if self.check_possible(row, col): if 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 == 1:
@ -31,23 +47,36 @@ class ShipField:
def target(self, row, col): def target(self, row, col):
if self.field_mode == 0:
self.clear_marker() self.clear_marker()
if self.field_mode == 0:
if self.check_possible(row, col): if self.check_possible(row, col):
if self.ship_direction == 0: if self.ship_direction == 0:
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:
self.field[r * self.field_size + col] = "p" self.field[r * self.field_size + col] = "p"
else:
self.field[r * self.field_size + col] = "r"
if self.ship_direction == 1: if self.ship_direction == 1:
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:
self.field[row * self.field_size + c] = "p" self.field[row * self.field_size + c] = "p"
else:
self.field[row * self.field_size + c] = "r"
else:
self.field[row * self.field_size + col] = "+"
def clear_marker(self): def clear_marker(self):
for i in range(0, len(self.field)): for i in range(0, len(self.field)):
if self.field[i] == "p": if self.field[i] == "p" or self.field[i] == "r":
self.field[i] = "" self.field[i] = ""
if "+" in self.field[i]:
self.field[i] = self.field[i].replace("+", "")
def set_ship(self, row, col): def set_ship(self, row, col):
if row < 0 or row > self.field_size: if row < 0 or row > self.field_size:
return return
@ -67,6 +96,9 @@ class ShipField:
index = row * self.field_size + c index = row * self.field_size + c
self.field[index] = "1" self.field[index] = "1"
if self.ship_size in self.ships:
self.ships.remove(self.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
@ -109,15 +141,23 @@ class ShipField:
return True return True
def set_ship_size(self, value): def set_ship_size(self, value):
if value is None:
return
if type(value) is str and value.isnumeric(): if type(value) is str and value.isnumeric():
value = int(value) value = int(value)
if 1 <= value <= 4:
if type(value) is int and 1 <= value <= 4:
self.ship_size = value self.ship_size = value
def set_ship_direction(self, value): def set_ship_direction(self, value):
if value is None:
return
if type(value) is str and value.isnumeric(): if type(value) is str and value.isnumeric():
value = int(value) value = int(value)
if 0 <= value <= 1:
if type(value) is int and 0 <= value <= 1:
self.ship_direction = value self.ship_direction = value
def toggle_ship_direction(self): def toggle_ship_direction(self):
@ -138,10 +178,7 @@ class ShipField:
blocked_string = "" blocked_string = ""
ship_string = "" ship_string = ""
for c in range(0, self.field_size): for c in range(0, self.field_size):
blocked_string += str(self.check_blocked(self, r, c))[0] + ", " blocked_string += str(self.check_blocked(r, c))[0] + ", "
ship_string += self.field[r * self.field_size + c] + ', ' ship_string += self.field[r * self.field_size + c] + ', '
print(blocked_string[:-2] + ' ' + ship_string[:-2]) print(blocked_string[:-2] + ' ' + ship_string[:-2])
print("********************************************************************") print("********************************************************************")

View File

@ -54,7 +54,11 @@ class TestShipField(TestCase):
self.assertEqual(ship_field.field_mode, 0) # Проверяем, что field_mode принял желаемое значение self.assertEqual(ship_field.field_mode, 0) # Проверяем, что field_mode принял желаемое значение
def test_action(self): def test_action(self):
self.fail() ship_field = ShipField()
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()
@ -114,8 +118,40 @@ class TestShipField(TestCase):
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_set_ship(self): def test_set_ship_size4_vertical_direction(self):
self.fail() ship_field = ShipField()
ship_field.set_ship_size(4)
ship_field.set_ship_direction(0) #vertikal
ship_field.set_ship(6, 3)
self.assertEqual(ship_field.field[63].strip(), '1')
self.assertEqual(ship_field.field[73].strip(), '1')
self.assertEqual(ship_field.field[83].strip(), '1')
self.assertEqual(ship_field.field[93].strip(), '1')
def test_set_ship_size4_horizontal_direction(self):
ship_field = ShipField()
ship_field.set_ship_size(4)
ship_field.set_ship_direction(1)
ship_field.set_ship(6, 3)
self.assertEqual(ship_field.field[63].strip(), '1')
self.assertEqual(ship_field.field[64].strip(), '1')
self.assertEqual(ship_field.field[65].strip(), '1')
self.assertEqual(ship_field.field[66].strip(), '1')
def test_set_ship_size4_vertical_direction_outofrange(self):
ship_field = ShipField()
ship_field.set_ship_size(4)
ship_field.set_ship_direction(0)
old_field_string = str.join(' ', ship_field.field)
ship_field.set_ship(7, 3)
new_field_string = str.join(' ', ship_field.field)
self.assertEqual(new_field_string, old_field_string)
def test_check_possible(self): def test_check_possible(self):
self.fail() self.fail()
@ -124,8 +160,22 @@ class TestShipField(TestCase):
self.fail() self.fail()
def test_set_ship_direction(self): def test_set_ship_direction(self):
self.fail() ship_field = ShipField()
ship_field.set_ship_direction(1)
self.assertEqual(ship_field.ship_direction, 1)
ship_field.set_ship_direction(0)
self.assertEqual(ship_field.ship_direction, 0)
def test_toggle_ship_direction(self): def test_toggle_ship_direction(self):
self.fail() ship_field = ShipField()
ship_field.toggle_ship_direction()
self.assertEqual(ship_field.ship_direction, 1)
ship_field.toggle_ship_direction()
self.assertEqual(ship_field.ship_direction, 0)

View File

@ -11,7 +11,6 @@ def draw_field(window, field, col_offset):
buttons = [] buttons = []
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):
index = r * field.field_size + c
btn = Button(window, text='', width=5, height=2) btn = Button(window, text='', width=5, height=2)
btn.grid(column=c + col_offset, row=r) btn.grid(column=c + col_offset, row=r)
btn.bind('<Button-1>', lambda e, x=r, y=c: left_button_click(buttons, x, y)) btn.bind('<Button-1>', lambda e, x=r, y=c: left_button_click(buttons, x, y))
@ -28,18 +27,22 @@ def colorize(field, buttons):
if field.field[i] == "1": if field.field[i] == "1":
bg = 'pink' bg = 'pink'
if field.field[i] == "\\": if field.field[i] == "\\":
bg = 'red' bg = 'grey'
if field.field[i] == "0": if field.field[i] == "0":
bg = 'black' bg = 'black'
if field.field[i] == "p": if field.field[i] == "p":
bg = 'blue' bg = 'blue'
if field.field[i] == "r":
bg = 'red'
if "+" in field.field[i]:
bg = 'orange'
buttons[i].configure(bg=bg) buttons[i].configure(bg=bg)
def keypress_handler(e): def keypress_handler(e):
global active_field global active_field
if e.keysym.isnumeric(): if e.keysym.isnumeric():
active_field.set_ship_size(e.keysym) active_field.set_ship_size(int(e.keysym))
else: else:
if e.keysym == 'm': if e.keysym == 'm':
active_field.toggle_field_mode() active_field.toggle_field_mode()