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



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
Автор поста оценил этот комментарий

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

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

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

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

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

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

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

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

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

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

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

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

и пусть.

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

работает!

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