Не правильно работает определение корабля в морском бое
Пишу "Морской бой" и нашел неприятный момент, когда стреляешь в 3 палубный корабль с середины и любую клетку с краю, он уничтожается и 3 клетка где должен быть еще корабль закрывается, с 4 палубным такая же история.
Если вот так расставить корабли

При самой игре, происходит вот так
я пометил, где еще должен стоять корабль
https://github.com/rangihrad/sw.git
извиняюсь, за большой код, но как мог его сократил.
Ответы (1 шт):
Ваша проблема заключалась в том, что вы нигде не храните знания о кораблях. Занятые ячейки поля, что вы храните в players[].board - этой информации не достаточно. Потому что, допустим, вы попадаете трехпалубнику в середину, и в результате в players[].boardон, по сути, "разваливается" на два однопалубника. Отсюда и получается полное потопление при попадании в любую из этих частей-однопалубников.
Итак, во-первых я замучился задавать корабли через ввод координат (честно говоря на третьем корабле). Поэтому я переделал так, что надо выделить нужное количество ячеек таблицы и нажать на кнопку "Поставить корабль". Заодно совместил задание однопалубника и остальных (не понял зачем его отдельно обрабатывали). Кнопки теперь эквивалентные, но мне было лень переделывать. Так что сами, к примеру, на их место поставьте счётчики оставшихся кораблей (что сейчас во всплывающих подсказках) и сделаете одну общую кнопку.
Я добавил в ваш класс Player() ещё и данные о кораблях `ships'. Этот массив содержит все корабли с координатами всех их частей и длиной. При попадании, у соответствующего корабля уменьшается длина, и корабль считается убитым при достижении нулевой длины.
Ну и схлопнул в циклы кучу однотипных строчек. Хотя в этом направлении ещё работать и работать. Подсказка: чтобы не плодить кучу однотипных простых переменных и писать кучи похожих строк кода - чаще используйте списки и словари, по которым потом можно итерироваться в циклах или адресоваться по индексу безо всяких if.
import sys
import re
from random import randrange
import sqlite3
from PyQt5.QtGui import QPixmap, QIcon
from PyQt5.QtCore import QBasicTimer, QCoreApplication
from PyQt5.QtWidgets import QApplication, QMainWindow, \
QStackedWidget, QMessageBox, QInputDialog, QTableWidgetItem, QAction
from PyQt5 import QtCore, QtGui
from PyQt5 import QtWidgets
def natural_key(string_):
return [int(s) if s.isdigit() else s for s in re.split(r'(\d+)', string_)]
class Ui_MainWindow_ready(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(960, 540)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout.setObjectName("gridLayout")
self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.playerLabel = QtWidgets.QLabel(self.centralwidget)
font = QtGui.QFont()
font.setPointSize(16)
self.playerLabel.setFont(font)
self.playerLabel.setObjectName("playerLabel")
self.horizontalLayout_2.addWidget(self.playerLabel)
self.gridLayout.addLayout(self.horizontalLayout_2, 0, 0, 1, 1)
self.readyButton = QtWidgets.QPushButton(self.centralwidget)
font = QtGui.QFont()
font.setPointSize(24)
self.readyButton.setFont(font)
self.readyButton.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
self.readyButton.setObjectName("readyButton")
self.gridLayout.addWidget(self.readyButton, 0, 2, 1, 2)
self.verticalLayout_2 = QtWidgets.QVBoxLayout()
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.linkorButton = QtWidgets.QPushButton(self.centralwidget)
font = QtGui.QFont()
font.setPointSize(10)
font.setItalic(False)
font.setStrikeOut(False)
self.linkorButton.setFont(font)
self.linkorButton.setObjectName("linkorButton")
self.verticalLayout_2.addWidget(self.linkorButton)
self.kreyserButton = QtWidgets.QPushButton(self.centralwidget)
self.kreyserButton.setFont(font)
self.kreyserButton.setObjectName("kreyserButton")
self.verticalLayout_2.addWidget(self.kreyserButton)
self.esminecButton = QtWidgets.QPushButton(self.centralwidget)
self.esminecButton.setFont(font)
self.esminecButton.setObjectName("esminecButton")
self.verticalLayout_2.addWidget(self.esminecButton)
self.torpedButton = QtWidgets.QPushButton(self.centralwidget)
self.torpedButton.setFont(font)
self.torpedButton.setObjectName("torpedButton")
self.verticalLayout_2.addWidget(self.torpedButton)
self.gridLayout.addLayout(self.verticalLayout_2, 1, 3, 1, 1)
self.boardMap = QtWidgets.QTableWidget(self.centralwidget)
font = QtGui.QFont()
font.setPointSize(10)
font.setBold(True)
font.setWeight(75)
self.boardMap.setFont(font)
self.boardMap.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
self.boardMap.setSizeAdjustPolicy(QtWidgets.QAbstractScrollArea.AdjustIgnored)
self.boardMap.setObjectName("boardMap")
self.boardMap.setColumnCount(10)
self.boardMap.setRowCount(10)
for i in range(10):
item = QtWidgets.QTableWidgetItem()
self.boardMap.setVerticalHeaderItem(i, item)
item = QtWidgets.QTableWidgetItem()
self.boardMap.setHorizontalHeaderItem(i, item)
self.gridLayout.addWidget(self.boardMap, 1, 0, 1, 1)
self.verticalLayout = QtWidgets.QVBoxLayout()
self.verticalLayout.setObjectName("verticalLayout")
self.linkorImage = QtWidgets.QLabel(self.centralwidget)
self.linkorImage.setText("")
self.linkorImage.setObjectName("linkorImage")
self.verticalLayout.addWidget(self.linkorImage)
self.kreyserImage = QtWidgets.QLabel(self.centralwidget)
self.kreyserImage.setText("")
self.kreyserImage.setObjectName("kreyserImage")
self.verticalLayout.addWidget(self.kreyserImage)
self.esminecImage = QtWidgets.QLabel(self.centralwidget)
self.esminecImage.setText("")
self.esminecImage.setObjectName("esminecImage")
self.verticalLayout.addWidget(self.esminecImage)
self.torpedImage = QtWidgets.QLabel(self.centralwidget)
self.torpedImage.setText("")
self.torpedImage.setObjectName("torpedImage")
self.verticalLayout.addWidget(self.torpedImage)
self.gridLayout.addLayout(self.verticalLayout, 1, 2, 1, 1)
self.verticalLayout_3 = QtWidgets.QVBoxLayout()
self.verticalLayout_3.setObjectName("verticalLayout_3")
self.lcdNumber = []
for i in range(4, 0, -1):
self.lcdNumber.append(QtWidgets.QLCDNumber(self.centralwidget))
self.lcdNumber[-1].setProperty("intValue", i)
self.lcdNumber[-1].setObjectName(f"lcdNumber_{4-i}")
self.verticalLayout_3.addWidget(self.lcdNumber[-1])
self.gridLayout.addLayout(self.verticalLayout_3, 1, 1, 1, 1)
self.label = QtWidgets.QLabel(self.centralwidget)
font = QtGui.QFont()
font.setPointSize(8)
self.label.setFont(font)
self.label.setObjectName("label")
self.gridLayout.addWidget(self.label, 0, 1, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 960, 26))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.playerLabel.setText(_translate("MainWindow", "Игрок1"))
self.readyButton.setText(_translate("MainWindow", "Я готов"))
for w in [self.linkorButton, self.kreyserButton, self.esminecButton, self.torpedButton]:
w.setText(_translate("MainWindow", "Поставить корабль"))
for i in range(10):
item = self.boardMap.verticalHeaderItem(i)
item.setText(_translate("MainWindow", str(i+1)))
for i, c in enumerate("ABCDEFGHIJ"):
item = self.boardMap.horizontalHeaderItem(i)
item.setText(_translate("MainWindow", c))
self.label.setText(_translate("MainWindow", "Количество ячеек."))
class Ui_MainWindow_pvp(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(960, 577)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout.setObjectName("gridLayout")
self.horizontalLayout = QtWidgets.QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout")
self.board1Label = QtWidgets.QLabel(self.centralwidget)
font = QtGui.QFont()
font.setPointSize(16)
self.board1Label.setFont(font)
self.board1Label.setObjectName("board1Label")
self.horizontalLayout.addWidget(self.board1Label)
self.linkorP1 = QtWidgets.QLabel(self.centralwidget)
self.linkorP1.setText("")
self.linkorP1.setObjectName("linkorP1")
self.horizontalLayout.addWidget(self.linkorP1)
self.kreyserP1 = QtWidgets.QLabel(self.centralwidget)
self.kreyserP1.setText("")
self.kreyserP1.setObjectName("kreyserP1")
self.horizontalLayout.addWidget(self.kreyserP1)
self.esminecP1 = QtWidgets.QLabel(self.centralwidget)
self.esminecP1.setText("")
self.esminecP1.setObjectName("esminecP1")
self.horizontalLayout.addWidget(self.esminecP1)
self.torpedP1 = QtWidgets.QLabel(self.centralwidget)
self.torpedP1.setText("")
self.torpedP1.setObjectName("torpedP1")
self.horizontalLayout.addWidget(self.torpedP1)
self.gridLayout.addLayout(self.horizontalLayout, 0, 0, 1, 1)
self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.linkorP2 = QtWidgets.QLabel(self.centralwidget)
self.linkorP2.setText("")
self.linkorP2.setObjectName("linkorP2")
self.horizontalLayout_2.addWidget(self.linkorP2)
self.kreyserP2 = QtWidgets.QLabel(self.centralwidget)
self.kreyserP2.setText("")
self.kreyserP2.setObjectName("kreyserP2")
self.horizontalLayout_2.addWidget(self.kreyserP2)
self.esminecP2 = QtWidgets.QLabel(self.centralwidget)
self.esminecP2.setText("")
self.esminecP2.setObjectName("esminecP2")
self.horizontalLayout_2.addWidget(self.esminecP2)
self.torpedP2 = QtWidgets.QLabel(self.centralwidget)
self.torpedP2.setText("")
self.torpedP2.setObjectName("torpedP2")
self.horizontalLayout_2.addWidget(self.torpedP2)
self.board2Label = QtWidgets.QLabel(self.centralwidget)
font = QtGui.QFont()
font.setPointSize(16)
self.board2Label.setFont(font)
self.board2Label.setObjectName("board2Label")
self.horizontalLayout_2.addWidget(self.board2Label)
self.gridLayout.addLayout(self.horizontalLayout_2, 0, 5, 1, 1)
self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)
self.tableWidget.setMinimumSize(QtCore.QSize(441, 461))
self.tableWidget.setObjectName("tableWidget")
self.tableWidget.setColumnCount(10)
self.tableWidget.setRowCount(10)
for i in range(10):
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setVerticalHeaderItem(i, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(i, item)
self.gridLayout.addWidget(self.tableWidget, 1, 0, 1, 3)
spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.gridLayout.addItem(spacerItem, 0, 1, 1, 1)
self.vsLable = QtWidgets.QLabel(self.centralwidget)
font = QtGui.QFont()
font.setFamily("Digital Counter 7")
font.setPointSize(36)
self.vsLable.setFont(font)
self.vsLable.setText("")
self.vsLable.setObjectName("vsLable")
self.gridLayout.addWidget(self.vsLable, 0, 2, 1, 2)
self.tableWidget_2 = QtWidgets.QTableWidget(self.centralwidget)
self.tableWidget_2.setMinimumSize(QtCore.QSize(441, 461))
self.tableWidget_2.setObjectName("tableWidget_2")
self.tableWidget_2.setColumnCount(10)
self.tableWidget_2.setRowCount(10)
for i in range(10):
item = QtWidgets.QTableWidgetItem()
self.tableWidget_2.setVerticalHeaderItem(i, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget_2.setHorizontalHeaderItem(i, item)
self.gridLayout.addWidget(self.tableWidget_2, 1, 3, 1, 3)
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.gridLayout.addItem(spacerItem1, 0, 4, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 960, 26))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "Game PVP"))
for i in range(10):
item = self.tableWidget.verticalHeaderItem(i)
item.setText(_translate("MainWindow", str(i+1)))
item = self.tableWidget_2.verticalHeaderItem(i)
item.setText(_translate("MainWindow", str(i+1)))
for i, c in enumerate("ABCDEFGHIJ"):
item = self.tableWidget.horizontalHeaderItem(i)
item.setText(_translate("MainWindow", c))
item = self.tableWidget_2.horizontalHeaderItem(i)
item.setText(_translate("MainWindow", c))
COORDS = dict(("ABCDEFGHIJ"[x]+str(y+1), (y, x)) for x in range(10) for y in range(10))
players = []
def new_cell_mul(): # Когда ставлю звёздочку в QTableWidget
cell_mul = QTableWidgetItem("*")
cell_mul.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
return cell_mul
def new_cell_x(): # Когда ставлю крестик в QTableWidget
cell_x = QTableWidgetItem("X")
cell_x.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
return cell_x
def new_cell_dot(): # Когда ставлю точку в QTableWidget
cell_dot = QTableWidgetItem(".")
cell_dot.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
return cell_dot
class ReadyMain(QMainWindow, Ui_MainWindow_ready):
"""Меню подготовления к самой игре"""
def __init__(self, parent=None):
super(ReadyMain, self).__init__(parent)
self.setupUi(self)
self.map = SeaMap(self.boardMap)
self.new_count() # Обновление переменных-счётчиков
self.new_map() # Обновление карты
self.initUI()
def initUI(self):
# Задаю цвет и форму кнопкам
for w in [self.linkorButton, self.kreyserButton, self.esminecButton, self.torpedButton]:
w.setStyleSheet("color: white; background-color: #b6afa9;"
"border-radius: 10px;")
w.clicked.connect(self.setShip)
self.readyButton.setStyleSheet("color: white; background-color: #b6afa9;"
"border-radius: 10px;")
self.readyButton.clicked.connect(self.start)
def new_map(self): # Метод создаёт(обновляет) карту
for i in range(self.boardMap.columnCount()):
for j in range(self.boardMap.rowCount()):
self.boardMap.setItem(i, j, new_cell_dot())
self.boardMap.resizeColumnsToContents()
self.boardMap.resizeRowsToContents()
self.boardMap.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch)
self.boardMap.verticalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch)
def new_db(self, who): # Занесения данных в базу данных
self.con = sqlite3.connect("Players.db")
self.cur = self.con.cursor()
for i, j in COORDS.items():
self.cur.execute(f"""UPDATE {who} SET {i[0]} = '{str(self.boardMap.item(*COORDS[i]).text())}'
WHERE id={int(i[1:])}""")
self.con.commit()
def start(self):
"""Если Игрок1 нажал кнопку,
то Игрок2 начинает заполнять данные.
Иначе начинает игру"""
# Проверка, все ли корабли поставлены
if any(self.count.values()):
self.error("Вы не поставили все корабли")
return
if self.sender().text() == 'Я готов':
self.new_db("Player1")
players.append(Player('Player1', self.boardMap, self.ships)) # Добавление в список игрока
players
self.readyButton.setText("Я готов")
self.playerLabel.setText("Игрок 2")
self.new_count() # Обновление переменных-счётчиков
self.new_map() # Обновление карты
else:
self.new_db("Player2")
players.append(Player('Player2', self.boardMap, self.ships)) # Добавление в список игрока
windows.setCurrentIndex(1)
def new_count(self): # Создание(обновление) переменных-счётчиков
self.count = { 'L': 1, 'K': 2, 'E': 3, 'T': 4}
self.ships = { 'L': [], 'K': [], 'E': [], 'T': []}
for who in "TEKL":
{'L': self.linkorButton,
'K': self.kreyserButton,
'E': self.esminecButton,
'T': self.torpedButton}[who].setToolTip(f"{self.count[who]} left")
def coords_is_right(self, new_coords, num, mode='dual'):
# проверка на правильность введённых координат
new_coords[0] = new_coords[0].upper()
new_coords[1] = new_coords[1].upper()
if mode != 'v':
return (COORDS[new_coords[1]][0] - COORDS[new_coords[0]][0] == 0 and
COORDS[new_coords[1]][1] - COORDS[new_coords[0]][1] == num) or \
(COORDS[new_coords[1]][0] - COORDS[new_coords[0]][0] == num and
COORDS[new_coords[1]][1] - COORDS[new_coords[0]][1] == 0)
return (COORDS[new_coords[1]][0] - COORDS[new_coords[0]][0] == num and
COORDS[new_coords[1]][1] - COORDS[new_coords[0]][1] == 0)
def check(self, c1, c2, i, num):
# Проверка, если в координатах есть * или X,
if num == 1:
return (str(self.boardMap.item(c1 + i, c2).text()) == "*" or
str(self.boardMap.item(c1 + i, c2).text()) == "X")
return (str(self.boardMap.item(c1, c2 + i).text()) == "*" or
str(self.boardMap.item(c1, c2 + i).text()) == "X")
def error(self, text="Недопустимый размер или форма корабля."): # Вызов ошибки
QMessageBox.critical(self, 'Ошибка!', text)
def setShipByType(self, coords, num, who): # Создание любого корабля на поле
error = False
new_coords = coords.split('-')
if self.coords_is_right(new_coords, num):
vertical = self.coords_is_right(new_coords, num, 'v')
c1, c2 = COORDS[new_coords[0]][0], COORDS[new_coords[0]][1]
for i in range(num + 1):
if self.check(c1, c2, i, 1 if vertical else 2):
self.error("Сюда нельзя поставить корабль")
return
coords_as_num = []
for i in range(num + 1):
if not vertical:
self.boardMap.setItem(c1, c2 + i, new_cell_x())
coords_as_num.append((c1, c2 + i))
if i == num:
self.map.shoot(c1, c2 + i, "sink")
else:
self.boardMap.setItem(c1 + i, c2, new_cell_x())
coords_as_num.append((c1 + i, c2))
if i == num:
self.map.shoot(c1 + i, c2, 'sink')
self.count[who] -= 1
self.ships[who].append([coords_as_num, {'L': 4, 'K': 3, 'E': 2, 'T': 1}[who]])
{'L': self.linkorButton,
'K': self.kreyserButton,
'E': self.esminecButton,
'T': self.torpedButton}[who].setToolTip(f"{self.count[who]} left")
else:
self.error()
def setShip(self): # Создание корабля
items = sorted(["ABCDEFGHIJ"[item.column()]+str(item.row()+1) for item in self.boardMap.selectedItems()], key=natural_key)
n = len(items)
if 1 <= n <= 4:
if self.count[' TEKL'[n]] == 0:
self.error("Все корабли этого типа поставлены")
return
try:
self.setShipByType(f"{items[0]}-{items[-1]}", n-1, " TEKL"[n])
except BaseException:
self.error()
else:
self.error()
class PVPMain(QMainWindow, Ui_MainWindow_pvp):
def __init__(self, parent=None):
super(PVPMain, self).__init__(parent)
self.setupUi(self)
self.turn = "Игрок1" # Очередь первого игрока
self.map = []
self.map.append(SeaMap(self.tableWidget))
self.map.append(SeaMap(self.tableWidget_2))
self.new_boards() # Создание игрового поля
self.initUI()
def initUI(self):
self.tableWidget.cellClicked[int, int].connect(self.course1)
self.tableWidget_2.cellClicked[int, int].connect(self.course2)
self.board1Label.setText("Игрок 1")
self.board2Label.setText("Игрок 2")
self.board1Label.setStyleSheet("background-color: #B22222")
self.board2Label.setStyleSheet("background-color: #1E90FF")
self.tableWidget.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch)
self.tableWidget.verticalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch)
self.tableWidget_2.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch)
self.tableWidget_2.verticalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch)
def new_boards(self):
for i in range(self.tableWidget.columnCount()):
for j in range(self.tableWidget.rowCount()):
self.tableWidget.setItem(i, j, new_cell_dot())
for i in range(self.tableWidget_2.columnCount()):
for j in range(self.tableWidget_2.rowCount()):
self.tableWidget_2.setItem(i, j, new_cell_dot())
self.tableWidget.resizeColumnsToContents()
self.tableWidget.resizeRowsToContents()
self.tableWidget_2.resizeColumnsToContents()
self.tableWidget_2.resizeRowsToContents()
def change_of_course(self): # Смена хода
if self.turn == "Игрок1":
self.turn = "Игрок2"
self.board2Label.setStyleSheet("background-color: #B22222")
self.board1Label.setStyleSheet("background-color: #1E90FF")
players[0], players[1] = players[1], players[0]
elif self.turn == "Игрок2":
self.turn = "Игрок1"
self.board1Label.setStyleSheet("background-color: #B22222")
self.board2Label.setStyleSheet("background-color: #1E90FF")
players[0], players[1] = players[1], players[0]
def info(self, text="Координаты правильные"): # Информационное табло
QMessageBox.information(self, "INFO", text)
def error(self, text="Вы уже стреляли в эту клетку."): # Вызов ошибки
QMessageBox.critical(self, 'Ошибка!', text)
def check(self):
if all(players[1].board[i][j] == 0 for i in range(10) for j in range(10)):
self.info(f"Выиграл {self.turn}!")
windows.setCurrentIndex(5)
return
def course1(self, c1, c2):
self.course(c1, c2, 1)
def course2(self, c1, c2):
self.course(c1, c2, 2)
def course(self, r, c, num): # Ход
if self.turn[-1] == '1' and num == 2 or self.turn[-1] == '2' and num == 1:
flag = True
coord = (r, c)
else:
flag = False
if num == 1:
if str(self.tableWidget.item(r, c).text()) == "*" or str(self.tableWidget.item(r, c).text()) == "X" :
self.error()
return
else:
if str(self.tableWidget_2.item(r, c).text()) == "*" or str(self.tableWidget_2.item(r, c).text()) == "X" :
self.error()
return
if flag:
if self.dot_or_notdot((r, c)):
dead = self.shootAndCheckIfShipIsDead((r, c))
what = 'sink' if dead else 'hit'
pl = 1 if self.turn[-1] == '1' else 0
self.map[pl].shoot(r, c, what)
players[1].board[r][c] = 0
self.info("Корабль потоплен!" if dead else "Попадание!")
self.check()
else:
pl = 1 if self.turn[-1] == '1' else 0
self.map[pl].shoot(r, c, 'miss')
self.info("Промах!")
self.change_of_course()
else:
QMessageBox.critical(self, "Ошибка!", "Не ваша очередь!")
def dot_or_notdot(self, coord): # Проверка попал, не попал
new_coord = None
for key, value in COORDS.items():
if value == coord:
new_coord = (key, value)
break
con = sqlite3.connect("Players.db")
cur = con.cursor()
result = cur.execute(
f"""SELECT {new_coord[0][0]} FROM Player{players[1].who[-1]}
WHERE id={new_coord[1][0] + 1}""").fetchone()
if result[0] == "." or result[0] == "*":
return False
return True
def shootAndCheckIfShipIsDead(self, pos): # Стреляем по кораблю и проверяем, потопил или ранил
x, y = pos
if 0 <= x < 10 and 0 <= y < 10:
if players[1].board[x][y] == 1:
for who in "TEKL":
for ship in players[1].ships[who]:
if pos in ship[0]:
ship[1] -= 1
return ship[1] == 0
return False
class Player:
def __init__(self, who, map, ships):
self.who = who
self.board = []
self.ships = ships
for i in range(10):
self.board.append([])
for j in range(10):
self.board[i].append(0)
for i in range(10):
for j in range(10):
if str(map.item(i, j).text()) == 'X':
self.board[i][j] = 1
class SeaMap:
def __init__(self, board):
self.map = board
def shoot(self, row, col, result):
if result == 'miss':
self.map.setItem(row, col, new_cell_mul())
elif result == 'hit':
self.map.setItem(row, col, new_cell_x())
elif result == 'sink':
for i in range(row - 1, row + 2):
for j in range(col - 1, col + 2):
if 0 <= i < 10 and 0 <= j < 10:
if str(self.map.item(i, j).text()) == '.':
self.map.setItem(i, j, new_cell_mul())
self.map.setItem(row, col, new_cell_x())
for j in range(10):
if str(self.map.item(row, j).text()) == 'X':
col = j
for i in range(row - 1, row + 2):
for u in range(col - 1, col + 2):
if 0 <= i < 10 and 0 <= u < 10:
if str(self.map.item(i, u).text()) == '.':
self.map.setItem(i, u, new_cell_mul())
for v in range(10):
if str(self.map.item(v, col).text()) == 'X':
row = v
for v in range(row - 1, row + 2):
for u in range(col - 1, col + 2):
if 0 <= v < 10 and 0 <= u < 10:
if str(self.map.item(v, u).text()) == '.':
self.map.setItem(v, u, new_cell_mul())
if __name__ == '__main__':
app = QApplication(sys.argv)
ready_window = ReadyMain()
pvp_window = PVPMain()
windows = QStackedWidget()
windows.addWidget(ready_window) # 0
windows.addWidget(pvp_window) # 1
windows.setWindowTitle("Морской бой")
windows.show()
sys.exit(app.exec())


