import pygame
import random
import sys
ИГРА "МОРСКОЙ БОЙ" 6x6
Правила: игрок и компьютер стреляют по полям противника.
Побеждает тот, кто первым сделает 4 попадания.
Корабли (2 корабля по 2 палубы) расставлены так, чтобы не соприкасаться.
pygame.init()
Константы
FIELD_SIZE = 6 # Поле 6x6
CELL_SIZE = 80
WINDOW_WIDTH = CELL_SIZE * FIELD_SIZE * 2 + 150
WINDOW_HEIGHT = CELL_SIZE * FIELD_SIZE + 200
SHIP_COUNT = 2 # 2 корабля
DECK_COUNT = 2 # по 2 палубы каждый
HITS_TO_WIN = 4 # Для победы нужно 4 попадания
Цвета
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
BLUE = (100, 150, 255)
DARK_BLUE = (50, 100, 200)
GRAY = (200, 200, 200)
RED = (255, 0, 0)
Состояния клетки
EMPTY, SHIP, MISS, HIT = 0, 1, 2, 3
class BattleshipGame:
def init(self):
self.screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption("Морской бой 6x6")
self.font = pygame.font.SysFont(None, 24)
self.small_font = pygame.font.SysFont(None, 18)
Два игровых поля (0=пусто, 1=корабль, 2=промах, 3=попадание)
self.player_field = [[EMPTY] * FIELD_SIZE for _ in range(FIELD_SIZE)]
self.computer_field = [[EMPTY] * FIELD_SIZE for _ in range(FIELD_SIZE)]
self.game_over = False
self.player_turn = True
self.message = "Ваш ход! Введите координаты (например: A1):"
self.input_buffer = ""
Расстановка кораблей
self.setup_ships(self.player_field)
self.setup_ships(self.computer_field)
def setup_ships(self, field):
"""Случайная расстановка кораблей с проверкой, чтобы не касались краями"""
for _ in range(SHIP_COUNT):
placed = False
attempts = 0
while not placed and attempts < 1000:
x, y = random.randint(0, FIELD_SIZE - 1), random.randint(0, FIELD_SIZE
horizontal = random.choice([True, False])
if self.can_place_ship(field, x, y, horizontal):
self.place_ship(field, x, y, horizontal)
placed = True
attempts += 1
def can_place_ship(self, field, x, y, horizontal):
"""Проверка: корабль помещается и не касается других краями (включая
диагонали)"""
Проверка границ поля
if (horizontal and x + DECK_COUNT > FIELD_SIZE) or (not horizontal and y +
DECK_COUNT > FIELD_SIZE):
return False
Клетки будущего корабля
cells = [(x + i, y) if horizontal else (x, y + i) for i in range(DECK_COUNT)]
Проверка, что все клетки пустые
for cx, cy in cells:
if field[cy][cx] != EMPTY:
return False
Проверка соседей (включая диагонали)
for cx, cy in cells:
for dy in (-1, 0, 1):
for dx in (-1, 0, 1):
nx, ny = cx + dx, cy + dy
if 0 <= nx < FIELD_SIZE and 0 <= ny < FIELD_SIZE:
if field[ny][nx] != EMPTY and (nx, ny) not in cells:
return False
return True
def place_ship(self, field, x, y, horizontal):
"""Размещение корабля на поле"""
for i in range(DECK_COUNT):
if horizontal:
field[y][x + i] = SHIP
else:
field[y + i][x] = SHIP
def draw_field(self, field, x, y, show_ships=False):
"""Отрисовка игрового поля с сеткой и координатами"""
Рисуем сетку
for i in range(FIELD_SIZE + 1):
pygame.draw.line(self.screen, BLACK, (x, y + i * CELL_SIZE), (x +
FIELD_SIZE * CELL_SIZE, y + i * CELL_SIZE), 2)
pygame.draw.line(self.screen, BLACK, (x + i * CELL_SIZE, y), (x + i *
CELL_SIZE, y + FIELD_SIZE * CELL_SIZE), 2)
Рисуем клетки
for row in range(FIELD_SIZE):
for col in range(FIELD_SIZE):
rect = pygame.Rect(x + col * CELL_SIZE + 1, y + row * CELL_SIZE + 1,
CELL_SIZE - 2, CELL_SIZE - 2)
Цвет зависит от состояния клетки
if field[row][col] == EMPTY:
color = BLUE
elif field[row][col] == SHIP:
color = DARK_BLUE if show_ships else BLUE
elif field[row][col] == MISS:
color = GRAY
else: # HIT
color = RED
pygame.draw.rect(self.screen, color, rect)
Буквы столбцов (A-F) - только в первой строке
if row == 0:
letter = self.small_font.render(chr(65 + col), True, BLACK)
self.screen.blit(letter, (x + col * CELL_SIZE + CELL_SIZE // 2 -
5, y - 20))
Цифры строк (1-6) - слева от поля
number = self.small_font.render(str(row + 1), True, BLACK)
self.screen.blit(number, (x - 30, y + row * CELL_SIZE + CELL_SIZE // 2 -
10))
def process_player_shot(self, col, row):
"""Обработка выстрела игрока по полю компьютера"""
if self.computer_field[row][col] == SHIP:
self.computer_field[row][col] = HIT
hits = sum(row.count(HIT) for row in self.computer_field)
self.message = f"Попал! Осталось попаданий: {HITS_TO_WIN - hits}"
if hits >= HITS_TO_WIN:
self.game_over = True
self.message = "Поздравляем! Вы победили!"
elif self.computer_field[row][col] == EMPTY:
self.computer_field[row][col] = MISS
self.message = "Мимо! Ход компьютера..."
self.player_turn = False
def computer_shot(self):
"""Случайный выстрел компьютера по полю игрока"""
while True:
col, row = random.randint(0, FIELD_SIZE - 1), random.randint(0, FIELD_SIZE
if self.player_field[row][col] in (EMPTY, SHIP):
break
if self.player_field[row][col] == SHIP:
self.player_field[row][col] = HIT
hits = sum(row.count(HIT) for row in self.player_field)
self.message = f"Компьютер попал! Осталось попаданий до поражения:
{HITS_TO_WIN - hits}"
if hits >= HITS_TO_WIN:
self.game_over = True
self.message = "Компьютер победил!"
else:
self.player_field[row][col] = MISS
self.message = "Компьютер промахнулся! Ваш ход."
self.player_turn = True
def check_coords(self, text):
"""Преобразует 'A1' в координаты (0,0) и проверяет корректность"""
if len(text) == 2 and text[0].isalpha() and text[1].isdigit():
x, y = ord(text[0]) - ord('A'), int(text[1]) - 1
if 0 <= x < FIELD_SIZE and 0 <= y < FIELD_SIZE:
return x, y
raise ValueError("Используйте формат A1-F6")
def run(self):
"""Главный игровой цикл"""
while True:
Обработка событий
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE: # Выход по ESC
pygame.quit()
sys.exit()
if self.player_turn and not self.game_over:
if event.key == pygame.K_RETURN and self.input_buffer:
try:
x, y = self.check_coords(self.input_buffer.upper())
if self.computer_field[y][x] in (HIT, MISS):
self.message = "Сюда уже стреляли!"
else:
self.process_player_shot(x, y)
self.input_buffer = ""
except Exception as e:
self.message = f"Ошибка: {e}"
elif event.key == pygame.K_BACKSPACE:
self.input_buffer = self.input_buffer[:-1]
elif event.unicode.isalnum() and len(self.input_buffer) < 3:
self.input_buffer += event.unicode.upper()
Ход компьютера
if not self.player_turn and not self.game_over:
pygame.time.wait(500)
self.computer_shot()
Отрисовка
self.screen.fill(WHITE)
self.draw_field(self.player_field, 50, 50, show_ships=True) #
Левое поле - игрока
self.draw_field(self.computer_field, WINDOW_WIDTH // 2 + 25, 50) #
Правое поле - компьютера
Вывод сообщений и подсказок
self.screen.blit(self.font.render(self.message, True, BLACK), (50,
WINDOW_HEIGHT - 80))
self.screen.blit(self.font.render(f"Ввод: {self.input_buffer}", True,
BLACK), (50, WINDOW_HEIGHT - 40))
self.screen.blit(self.small_font.render("ESC - выход", True, BLACK),
(WINDOW_WIDTH - 100, WINDOW_HEIGHT - 30))
pygame.display.flip()
if not self.game_over:
pygame.time.Clock().tick(30)
if name == "main":
BattleshipGame().run()
import pygame
import random
import sys
ИГРА "МОРСКОЙ БОЙ" 6x6
Правила: игрок и компьютер стреляют по полям противника.
Побеждает тот, кто первым сделает 4 попадания.
Корабли (2 корабля по 2 палубы) расставлены так, чтобы не соприкасаться.
pygame.init()
Константы
FIELD_SIZE = 6 # Поле 6x6
CELL_SIZE = 80
WINDOW_WIDTH = CELL_SIZE * FIELD_SIZE * 2 + 150
WINDOW_HEIGHT = CELL_SIZE * FIELD_SIZE + 200
SHIP_COUNT = 2 # 2 корабля
DECK_COUNT = 2 # по 2 палубы каждый
HITS_TO_WIN = 4 # Для победы нужно 4 попадания
Цвета
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
BLUE = (100, 150, 255)
DARK_BLUE = (50, 100, 200)
GRAY = (200, 200, 200)
RED = (255, 0, 0)
Состояния клетки
EMPTY, SHIP, MISS, HIT = 0, 1, 2, 3
class BattleshipGame:
def init(self):
self.screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption("Морской бой 6x6")
self.font = pygame.font.SysFont(None, 24)
self.small_font = pygame.font.SysFont(None, 18)
Два игровых поля (0=пусто, 1=корабль, 2=промах, 3=попадание)
self.player_field = [[EMPTY] * FIELD_SIZE for _ in range(FIELD_SIZE)]
self.computer_field = [[EMPTY] * FIELD_SIZE for _ in range(FIELD_SIZE)]
self.game_over = False
self.player_turn = True
self.message = "Ваш ход! Введите координаты (например: A1):"
self.input_buffer = ""
Расстановка кораблей
self.setup_ships(self.player_field)
self.setup_ships(self.computer_field)
def setup_ships(self, field):
"""Случайная расстановка кораблей с проверкой, чтобы не касались краями"""
for _ in range(SHIP_COUNT):
placed = False
attempts = 0
while not placed and attempts < 1000:
x, y = random.randint(0, FIELD_SIZE - 1), random.randint(0, FIELD_SIZE
horizontal = random.choice([True, False])
if self.can_place_ship(field, x, y, horizontal):
self.place_ship(field, x, y, horizontal)
placed = True
attempts += 1
def can_place_ship(self, field, x, y, horizontal):
"""Проверка: корабль помещается и не касается других краями (включая
диагонали)"""
Проверка границ поля
if (horizontal and x + DECK_COUNT > FIELD_SIZE) or (not horizontal and y +
DECK_COUNT > FIELD_SIZE):
return False
Клетки будущего корабля
cells = [(x + i, y) if horizontal else (x, y + i) for i in range(DECK_COUNT)]
Проверка, что все клетки пустые
for cx, cy in cells:
if field[cy][cx] != EMPTY:
return False
Проверка соседей (включая диагонали)
for cx, cy in cells:
for dy in (-1, 0, 1):
for dx in (-1, 0, 1):
nx, ny = cx + dx, cy + dy
if 0 <= nx < FIELD_SIZE and 0 <= ny < FIELD_SIZE:
if field[ny][nx] != EMPTY and (nx, ny) not in cells:
return False
return True
def place_ship(self, field, x, y, horizontal):
"""Размещение корабля на поле"""
for i in range(DECK_COUNT):
if horizontal:
field[y][x + i] = SHIP
else:
field[y + i][x] = SHIP
def draw_field(self, field, x, y, show_ships=False):
"""Отрисовка игрового поля с сеткой и координатами"""
Рисуем сетку
for i in range(FIELD_SIZE + 1):
pygame.draw.line(self.screen, BLACK, (x, y + i * CELL_SIZE), (x +
FIELD_SIZE * CELL_SIZE, y + i * CELL_SIZE), 2)
pygame.draw.line(self.screen, BLACK, (x + i * CELL_SIZE, y), (x + i *
CELL_SIZE, y + FIELD_SIZE * CELL_SIZE), 2)
Рисуем клетки
for row in range(FIELD_SIZE):
for col in range(FIELD_SIZE):
rect = pygame.Rect(x + col * CELL_SIZE + 1, y + row * CELL_SIZE + 1,
CELL_SIZE - 2, CELL_SIZE - 2)
Цвет зависит от состояния клетки
if field[row][col] == EMPTY:
color = BLUE
elif field[row][col] == SHIP:
color = DARK_BLUE if show_ships else BLUE
elif field[row][col] == MISS:
color = GRAY
else: # HIT
color = RED
pygame.draw.rect(self.screen, color, rect)
Буквы столбцов (A-F) - только в первой строке
if row == 0:
letter = self.small_font.render(chr(65 + col), True, BLACK)
self.screen.blit(letter, (x + col * CELL_SIZE + CELL_SIZE // 2 -
5, y - 20))
Цифры строк (1-6) - слева от поля
number = self.small_font.render(str(row + 1), True, BLACK)
self.screen.blit(number, (x - 30, y + row * CELL_SIZE + CELL_SIZE // 2 -
10))
def process_player_shot(self, col, row):
"""Обработка выстрела игрока по полю компьютера"""
if self.computer_field[row][col] == SHIP:
self.computer_field[row][col] = HIT
hits = sum(row.count(HIT) for row in self.computer_field)
self.message = f"Попал! Осталось попаданий: {HITS_TO_WIN - hits}"
if hits >= HITS_TO_WIN:
self.game_over = True
self.message = "Поздравляем! Вы победили!"
elif self.computer_field[row][col] == EMPTY:
self.computer_field[row][col] = MISS
self.message = "Мимо! Ход компьютера..."
self.player_turn = False
def computer_shot(self):
"""Случайный выстрел компьютера по полю игрока"""
while True:
col, row = random.randint(0, FIELD_SIZE - 1), random.randint(0, FIELD_SIZE
if self.player_field[row][col] in (EMPTY, SHIP):
break
if self.player_field[row][col] == SHIP:
self.player_field[row][col] = HIT
hits = sum(row.count(HIT) for row in self.player_field)
self.message = f"Компьютер попал! Осталось попаданий до поражения:
{HITS_TO_WIN - hits}"
if hits >= HITS_TO_WIN:
self.game_over = True
self.message = "Компьютер победил!"
else:
self.player_field[row][col] = MISS
self.message = "Компьютер промахнулся! Ваш ход."
self.player_turn = True
def check_coords(self, text):
"""Преобразует 'A1' в координаты (0,0) и проверяет корректность"""
if len(text) == 2 and text[0].isalpha() and text[1].isdigit():
x, y = ord(text[0]) - ord('A'), int(text[1]) - 1
if 0 <= x < FIELD_SIZE and 0 <= y < FIELD_SIZE:
return x, y
raise ValueError("Используйте формат A1-F6")
def run(self):
"""Главный игровой цикл"""
while True:
Обработка событий
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE: # Выход по ESC
pygame.quit()
sys.exit()
if self.player_turn and not self.game_over:
if event.key == pygame.K_RETURN and self.input_buffer:
try:
x, y = self.check_coords(self.input_buffer.upper())
if self.computer_field[y][x] in (HIT, MISS):
self.message = "Сюда уже стреляли!"
else:
self.process_player_shot(x, y)
self.input_buffer = ""
except Exception as e:
self.message = f"Ошибка: {e}"
elif event.key == pygame.K_BACKSPACE:
self.input_buffer = self.input_buffer[:-1]
elif event.unicode.isalnum() and len(self.input_buffer) < 3:
self.input_buffer += event.unicode.upper()
Ход компьютера
if not self.player_turn and not self.game_over:
pygame.time.wait(500)
self.computer_shot()
Отрисовка
self.screen.fill(WHITE)
self.draw_field(self.player_field, 50, 50, show_ships=True) #
Левое поле - игрока
self.draw_field(self.computer_field, WINDOW_WIDTH // 2 + 25, 50) #
Правое поле - компьютера
Вывод сообщений и подсказок
self.screen.blit(self.font.render(self.message, True, BLACK), (50,
WINDOW_HEIGHT - 80))
self.screen.blit(self.font.render(f"Ввод: {self.input_buffer}", True,
BLACK), (50, WINDOW_HEIGHT - 40))
self.screen.blit(self.small_font.render("ESC - выход", True, BLACK),
(WINDOW_WIDTH - 100, WINDOW_HEIGHT - 30))
pygame.display.flip()
if not self.game_over:
pygame.time.Clock().tick(30)
if name == "main":
BattleshipGame().run()