Питон морской бой



import tkinter as tk

from tkinter import messagebox

import random

class BattleshipGame:

def __init__(self, master):

self.master = master

self.master.title("Морской Бой")

# Настройки игры

self.ship_sizes = [4, 3, 3, 2, 2, 2, 1, 1, 1, 1]

self.board_size = 10

self.cell_size = 40

# Инициализация игровых досок

self.player_board = self.create_board()

self.computer_board = self.create_board()

# Расстановка кораблей

self.place_ships(self.player_board)

self.place_ships(self.computer_board)

# Счетчики попаданий

self.player_hits = 0

self.computer_hits = 0

self.total_hits = sum(self.ship_sizes)

# Создание интерфейса

self.create_widgets()

# Флаг для отслеживания хода

self.game_over = False

def create_board(self):

return [[None for _ in range(self.board_size)] for _ in range(self.board_size)]

def place_ships(self, board):

for size in self.ship_sizes:

placed = False

while not placed:

direction = random.choice(['horizontal', 'vertical'])

if direction == 'horizontal':

max_col = self.board_size - size

max_row = self.board_size

else:

max_row = self.board_size - size

max_col = self.board_size

row = random.randint(0, max_row - 1)

col = random.randint(0, max_col - 1)

if self.can_place_ship(board, row, col, size, direction):

self.mark_ship(board, row, col, size, direction)

placed = True

def can_place_ship(self, board, row, col, size, direction):

if direction == 'horizontal':

for c in range(col - 1, col + size + 1):

for r in range(row - 1, row + 2):

if 0 <= r < self.board_size and 0 <= c < self.board_size:

if board[r][c] == 'ship':

return False

else:

for r in range(row - 1, row + size + 1):

for c in range(col - 1, col + 2):

if 0 <= r < self.board_size and 0 <= c < self.board_size:

if board[r][c] == 'ship':

return False

return True

def mark_ship(self, board, row, col, size, direction):

if direction == 'horizontal':

for c in range(col, col + size):

board[row][c] = 'ship'

else:

for r in range(row, row + size):

board[r][col] = 'ship'

def create_widgets(self):

# Фреймы для досок

self.player_frame = tk.Frame(self.master)

self.computer_frame = tk.Frame(self.master)

self.player_frame.pack(side=tk.LEFT, padx=20, pady=20)

self.computer_frame.pack(side=tk.RIGHT, padx=20, pady=20)

# Метки для досок

tk.Label(self.player_frame, text="Ваше поле").grid(row=0, column=0, columnspan=11)

tk.Label(self.computer_frame, text="Поле компьютера").grid(row=0, column=0, columnspan=11)

# Создание игровых полей

self.player_cells = self.create_grid(self.player_frame, self.player_board, False)

self.computer_cells = self.create_grid(self.computer_frame, self.computer_board, True)

def create_grid(self, parent, board, clickable):

cells = []

# Добавляем буквы над сеткой

for col in range(self.board_size):

lbl = tk.Label(parent, text=chr(65 + col))

lbl.grid(row=1, column=col+1)

# Добавляем цифры слева

for row in range(self.board_size):

lbl = tk.Label(parent, text=str(row))

lbl.grid(row=row+2, column=0)

# Создаем клетки поля

for row in range(self.board_size):

row_cells = []

for col in range(self.board_size):

frame = tk.Frame(parent,

width=self.cell_size,

height=self.cell_size,

bg='white',

relief='ridge',

borderwidth=1)

frame.grid(row=row+2, column=col+1)

if board[row][col] == 'ship' and parent == self.player_frame:

frame.config(bg='gray')

if clickable:

frame.bind('<Button-1>', lambda e, r=row, c=col: self.player_turn(r, c))

row_cells.append(frame)

cells.append(row_cells)

return cells

def update_cell(self, cells, row, col, status):

color = 'white'

if status == 'hit':

color = 'red'

elif status == 'miss':

color = 'lightblue'

cells[row][col].config(bg=color)

def player_turn(self, row, col):

if self.game_over or self.computer_board[row][col] in ['hit', 'miss']:

return

if self.computer_board[row][col] == 'ship':

self.computer_board[row][col] = 'hit'

self.player_hits += 1

self.update_cell(self.computer_cells, row, col, 'hit')

if self.player_hits == self.total_hits:

self.end_game("Поздравляем! Вы выиграли!")

return

else:

self.computer_board[row][col] = 'miss'

self.update_cell(self.computer_cells, row, col, 'miss')

self.computer_turn()

def computer_turn(self):

while True:

row = random.randint(0, self.board_size - 1)

col = random.randint(0, self.board_size - 1)

if self.player_board[row][col] not in ['hit', 'miss']:

break

if self.player_board[row][col] == 'ship':

self.player_board[row][col] = 'hit'

self.computer_hits += 1

self.update_cell(self.player_cells, row, col, 'hit')

if self.computer_hits == self.total_hits:

self.end_game("Компьютер выиграл!")

else:

self.player_board[row][col] = 'miss'

self.update_cell(self.player_cells, row, col, 'miss')

def end_game(self, message):

self.game_over = True

messagebox.showinfo("Игра окончена", message)

self.master.destroy()

if __name__ == "__main__":

root = tk.Tk()

game = BattleshipGame(root)

root.mainloop()

1
Автор поста оценил этот комментарий

Так, вот отформатированный код. Сам не запускал.

import tkinter as tk
from tkinter import messagebox
import random

class BattleshipGame:
    def __init__(self, master):
        self.master = master
        self.master.title("Морской Бой")

        # Настройки игры
        self.ship_sizes = [4, 3, 3, 2, 2, 2, 1, 1, 1, 1]
        self.board_size = 10
        self.cell_size = 40

        # Инициализация игровых досок
        self.player_board = self.create_board()
        self.computer_board = self.create_board()

        # Расстановка кораблей
        self.place_ships(self.player_board)
        self.place_ships(self.computer_board)

        # Счетчики попаданий
        self.player_hits = 0
        self.computer_hits = 0
        self.total_hits = sum(self.ship_sizes)

        # Создание интерфейса
        self.create_widgets()

        # Флаг для отслеживания хода
        self.game_over = False

    def create_board(self):
        return [[None for _ in range(self.board_size)] for _ in range(self.board_size)]

    def place_ships(self, board):
        for size in self.ship_sizes:
            placed = False
            while not placed:
                direction = random.choice(['horizontal', 'vertical'])
                if direction == 'horizontal':
                    max_col = self.board_size - size
                    max_row = self.board_size
                else:
                    max_row = self.board_size - size
                    max_col = self.board_size

                row = random.randint(0, max_row - 1)
                col = random.randint(0, max_col - 1)

                if self.can_place_ship(board, row, col, size, direction):
                    self.mark_ship(board, row, col, size, direction)
                    placed = True

    def can_place_ship(self, board, row, col, size, direction):
        if direction == 'horizontal':
            for c in range(col - 1, col + size + 1):
                for r in range(row - 1, row + 2):
                    if 0 <= r < self.board_size and 0 <= c < self.board_size:
                        if board[r][c] == 'ship':
                            return False
        else:
            for r in range(row - 1, row + size + 1):
                for c in range(col - 1, col + 2):
                    if 0 <= r < self.board_size and 0 <= c < self.board_size:
                        if board[r][c] == 'ship':
                            return False
        return True

    def mark_ship(self, board, row, col, size, direction):
        if direction == 'horizontal':
            for c in range(col, col + size):
                board[row][c] = 'ship'
        else:
            for r in range(row, row + size):
                board[r][col] = 'ship'

    def create_widgets(self):
        # Фреймы для досок
        self.player_frame = tk.Frame(self.master)
        self.computer_frame = tk.Frame(self.master)
        self.player_frame.pack(side=tk.LEFT, padx=20, pady=20)
        self.computer_frame.pack(side=tk.RIGHT, padx=20, pady=20)

        # Метки для досок
        tk.Label(self.player_frame, text="Ваше поле").grid(row=0, column=0, columnspan=11)
        tk.Label(self.computer_frame, text="Поле компьютера").grid(row=0, column=0, columnspan=11)

        # Создание игровых полей
        self.player_cells = self.create_grid(self.player_frame, self.player_board, False)
        self.computer_cells = self.create_grid(self.computer_frame, self.computer_board, True)

    def create_grid(self, parent, board, clickable):
        cells = []
        # Добавляем буквы над сеткой
        for col in range(self.board_size):
            lbl = tk.Label(parent, text=chr(65 + col))
            lbl.grid(row=1, column=col+1)

        # Добавляем цифры слева
        for row in range(self.board_size):
            lbl = tk.Label(parent, text=str(row))
            lbl.grid(row=row+2, column=0)

        # Создаем клетки поля
        for row in range(self.board_size):
            row_cells = []
            for col in range(self.board_size):
                frame = tk.Frame(parent,
                                width=self.cell_size,
                                height=self.cell_size,
                                bg='white',
                                relief='ridge',
                                borderwidth=1)
                frame.grid(row=row+2, column=col+1)

                if board[row][col] == 'ship' and parent == self.player_frame:
                    frame.config(bg='gray')

                if clickable:
                    frame.bind('<Button-1>', lambda e, r=row, c=col: self.player_turn(r, c))
                row_cells.append(frame)
            cells.append(row_cells)
        return cells

    def update_cell(self, cells, row, col, status):
        color = 'white'
        if status == 'hit':
            color = 'red'
        elif status == 'miss':
            color = 'lightblue'
        cells[row][col].config(bg=color)

    def player_turn(self, row, col):
        if self.game_over or self.computer_board[row][col] in ['hit', 'miss']:
            return

        if self.computer_board[row][col] == 'ship':
            self.computer_board[row][col] = 'hit'
            self.player_hits += 1
            self.update_cell(self.computer_cells, row, col, 'hit')
            if self.player_hits == self.total_hits:
                self.end_game("Поздравляем! Вы выиграли!")
                return
        else:
            self.computer_board[row][col] = 'miss'
            self.update_cell(self.computer_cells, row, col, 'miss')
            self.computer_turn()

    def computer_turn(self):
        while True:
            row = random.randint(0, self.board_size - 1)
            col = random.randint(0, self.board_size - 1)
            if self.player_board[row][col] not in ['hit', 'miss']:
                break

        if self.player_board[row][col] == 'ship':
            self.player_board[row][col] = 'hit'
            self.computer_hits += 1
            self.update_cell(self.player_cells, row, col, 'hit')
            if self.computer_hits == self.total_hits:
                self.end_game("Компьютер выиграл!")
        else:
            self.player_board[row][col] = 'miss'
            self.update_cell(self.player_cells, row, col, 'miss')

    def end_game(self, message):
        self.game_over = True
        messagebox.showinfo("Игра окончена", message)
        self.master.destroy()

if __name__ == "__main__":
    root = tk.Tk()
    game = BattleshipGame(root)
    root.mainloop()

раскрыть ветку (1)
1
Автор поста оценил этот комментарий

спасибо!

0
Poshanka!
Автор поста оценил этот комментарий

А нахера его было вообще вставлять? Надо было на гитхаб выложить и ссылку прикрепить, а не это вот.

раскрыть ветку (1)
0
Автор поста оценил этот комментарий

хорошая мысль спасибо.

0
Автор поста оценил этот комментарий
А отступы где? Я конечно не специалист по питону, но они в нем важны
раскрыть ветку (1)
0
Автор поста оценил этот комментарий

а они сюда не копируются

1
Автор поста оценил этот комментарий

За***ся отступы рассавлять.

раскрыть ветку (1)
0
Автор поста оценил этот комментарий

файл сам нормальный был сюда вставляется так

показать ответы
1
Автор поста оценил этот комментарий

Старо как мир.
   ▲
▲  ▲

раскрыть ветку (1)
0
Автор поста оценил этот комментарий

и пусть.

0
Автор поста оценил этот комментарий
Так не заработает же, сразу видно. Даже запускать не надо
раскрыть ветку (1)
0
Автор поста оценил этот комментарий

работает!

показать ответы

Темы

Политика

Теги

Популярные авторы

Сообщества

18+

Теги

Популярные авторы

Сообщества

Игры

Теги

Популярные авторы

Сообщества

Юмор

Теги

Популярные авторы

Сообщества

Отношения

Теги

Популярные авторы

Сообщества

Здоровье

Теги

Популярные авторы

Сообщества

Путешествия

Теги

Популярные авторы

Сообщества

Спорт

Теги

Популярные авторы

Сообщества

Хобби

Теги

Популярные авторы

Сообщества

Сервис

Теги

Популярные авторы

Сообщества

Природа

Теги

Популярные авторы

Сообщества

Бизнес

Теги

Популярные авторы

Сообщества

Транспорт

Теги

Популярные авторы

Сообщества

Общение

Теги

Популярные авторы

Сообщества

Юриспруденция

Теги

Популярные авторы

Сообщества

Наука

Теги

Популярные авторы

Сообщества

IT

Теги

Популярные авторы

Сообщества

Животные

Теги

Популярные авторы

Сообщества

Кино и сериалы

Теги

Популярные авторы

Сообщества

Экономика

Теги

Популярные авторы

Сообщества

Кулинария

Теги

Популярные авторы

Сообщества

История

Теги

Популярные авторы

Сообщества

Недвижимость и ремонт

Теги

Популярные авторы

Сообщества