from random import randint
import os
# здесь просто задаем цвета. Они не соответствуют своим названиям, но главное всё сгруппировано в одном месте
# при желании цвета можно легко поменять не колупаясь во всей логике приложения
class Color:
yellow2 = '\033[1;35m'
reset = '\033[0m'
blue = '\033[0;34m'
yellow = '\033[1;33m'
red = '\033[1;31m'
miss = '\033[1;33m'
faded = '\033[2;37m'
# функция которая окрашивает текст в заданный цвет.
def set_color(text, color):
return color + text + Color.reset
# класс "клетка". Здесь мы задаем и визуальное отображение клеток и их цвет.
# по визуальному отображению мы проверяем какого типа клетка. Уж такая реализация.
# По этой причине нельзя обозначать одним символом два разных типа. Иначе в логике возникнет путаница.
class Cell:
ship_cell = set_color('■', Color.blue)
destroyed_ship = set_color('X', Color.yellow)
damaged_ship = set_color('□', Color.yellow)
miss_cell = set_color('•', Color.miss)
grid = set_color('•', Color.faded)
class Board:
letters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
def __init__(self):
# self.count_shot = 0
self.board = []
for n in range(10):
self.board.append([Cell.grid]*10)
@staticmethod
def clear_screen():
os.system('cls' if os.name == 'nt' else 'clear')
def print_board(self):
print('\n\t\033[1;4;33m* К О М П Ь Ю Т Е Р *\033[0m'.expandtabs(tabsize=7), \
'\t\033[1;4;33m* И Г Р О К *\033[0m'.expandtabs(tabsize=28), '\n')
print(' ', end=' ')
for j in range(10):
print('\033[1;4;36m', f'{j}', end=' ')
print('\033[0m\t'.expandtabs(tabsize=16), end='')
print(' ', end=' ')
for j in range(10):
print('\033[1;4;36m', f'{j}', end=' ')
print('\033[0m')
for i, row1, j, row2 in zip(self.letters, radar.board, self.letters, user.board):
print(f'\033[1;35m{i}|', '\033[0m', ' '.join(list(map(str, row1))), '\t'.expandtabs(tabsize=12), \
f'\033[1;35m{j}|', '\033[0m', ' '.join(list(map(str, row2))))
print('')
def random_row(self):
return randint(0, len(self.board)-1)
def random_col(self):
return randint(0, len(self.board[0])-1)
def mark_destroyed_ship(self, ship):
field = radar.board
x, y = ship.x, ship.y
width, height = ship.width, ship.height
# print(width, height)
for p_x in range(x - 1, x + height + 1):
for p_y in range(y - 1, y + width + 1):
if p_x < 0 or p_x >= len(field) or p_y < 0 or p_y >= len(field):
continue
field[p_x][p_y] = Cell.miss_cell
for p_x in range(x, x + height):
for p_y in range(y, y + width):
field[p_x][p_y] = Cell.destroyed_ship
class Ship:
ships_rules = [4, 3, 3, 2, 2, 2, 1, 1, 1, 1]
occupied_user = []
occupied_comp = []
occupied_radar = []
count_ship = 10
def __init__(self, len_ship):
self.x = user.random_row()
self.y = user.random_col()
self.len_ship = len_ship
self.direction = randint(0, 1)
self.set_ship()
self.setup = True
# self.print_ship()
# self.install_ship()
def __str__(self):
return Cell.ship_cell
def set_ship(self):
if self.direction == 0:
self.height = 1
self.width = self.len_ship
if self.direction == 1:
self.height = self.len_ship
self.width = 1
# self.print_ship()
def print_ship(self):
print(self.x, self.y, self.len_ship, self.direction)
# ship.install_ship()
def install_ship(self, field, occupied):
if self.x+self.height < 11 and self.y+self.width < 11 and field.board[self.x][self.y] != Cell.ship_cell \
and (self.x+max(0, self.height-3), self.y+max(0, self.width-3)) not in occupied \
and (self.x+max(0, self.height-2), self.y+max(0, self.width-2)) not in occupied \
and (self.x+max(0, self.height-1), self.y+max(0, self.width-1)) not in occupied:
for l in range(self.len_ship):
if self.direction == 0:
field.board[self.x][self.y+l] = ship
if self.direction == 1:
field.board[self.x+l][self.y] = ship
else:
self.setup = False
return
def occupied_board(self, field, occupied):
for o_x in range(self.x - 1, self.x + self.height + 1):
for o_y in range(self.y - 1, self.y + self.width + 1):
if o_x < 0 or o_x >= len(field.board) or o_y < 0 or o_y >= len(field.board):
continue
occupied.append((o_x, o_y))
# print(self.occupied)
def print_occupied(self, field, occupied):
for x, y in occupied:
if str(field.board[x][y]) != Cell.ship_cell:
field.board[x][y] = Cell.miss_cell
class Shot:
def __init__(self):
self.x = None
self.y = None
def shot_by_ships(self):
xy = input('\033[1;32mВаш выстрел (например, d3): ')
if len(xy) == 2:
input_x = xy[0]
if xy[1].isdigit():
input_y = int(xy[1])
else:
input_y = 10
if input_x in Board.letters and 0 <= input_y < 10:
self.x = Board.letters.index(input_x)
self.y = int(xy[1])
if radar.board[self.x][self.y] in (Cell.miss_cell, Cell.ship_cell, Cell.damaged_ship, Cell.destroyed_ship):
print('Эта клетка занята! Еще разок...')
self.shot_by_ships()
self.receive_shot()
else:
print('Неправильный ввод. Еще разок... ')
return self.shot_by_ships()
else:
print('Должно быть две координаты. Еще разок...')
return self.shot_by_ships()
def receive_shot(self):
sx = self.x
sy = self.y
# radar.count_shot += 1
if type(comp.board[sx][sy]) == Ship:
ship = comp.board[sx][sy]
ship.len_ship -= 1
if ship.len_ship <= 0:
radar.mark_destroyed_ship(ship)
print('\033[1;33mКорабль уничтожен!')
Ship.count_ship -= 1
return ship
radar.board[sx][sy] = Cell.damaged_ship
print('\033[1;33mПопадание!')
return 'get'
else:
radar.board[sx][sy] = Cell.miss_cell
print('\033[1;33mПромах!')
return 'miss'
if __name__ == "__main__":
user = Board()
radar = Board()
# user.print_board()
comp = Board()
for len_ship in Ship.ships_rules:
ship = Ship(len_ship)
# ship.print_ship()
ship.install_ship(user, Ship.occupied_user)
# print(ship.setup)
while ship.setup == False:
# print('Повторный запуск')
ship = Ship(len_ship)
# ship.print_ship()
ship.install_ship(user, Ship.occupied_user)
# print(ship.setup)
# user.print_board()
ship.occupied_board(user, Ship.occupied_user)
# ship.print_occupied(user, Ship.occupied_user)
for len_ship in Ship.ships_rules:
ship = Ship(len_ship)
# ship.print_ship()
ship.install_ship(comp, Ship.occupied_comp)
# print(ship.setup)
while ship.setup == False:
# print('Повторный запуск')
ship = Ship(len_ship)
# ship.print_ship()
ship.install_ship(comp, Ship.occupied_comp)
# print(ship.setup)
# radar.print_board()
ship.occupied_board(comp, Ship.occupied_comp)
# ship.print_occupied(radar, Ship.occupied_comp)
user.print_board()
while Ship.count_ship > 0:
shot = Shot()
# shot.shot_by_ships()
if shot.shot_by_ships() == 'miss':
print('\033[1;33mПромах!', 'Внешняя запись')
elif shot.shot_by_ships() == 'get':
print('\033[1;33mПопадание!', 'Внешняя запись')
elif type(shot.shot_by_ships) == Shot:
print('\033[1;33mКорабль уничтожен!', 'Внешняя запись')
# radar.clear_screen()
print('Отрисовка')
radar.print_board()
print('\033[1;31mИгра закончена!')