Загрузка данных
importtkinter as tk
from tkinter import messagebox, ttk
import random
import json
import os
WINDOW_TITLE = "Батискаф — сборресурсов"
CELL_SIZE = 42
GRID_COLS = 15
GRID_ROWS = 12
COLOR_BG = "#0b1d33"
COLOR_GRID = "#1e3a5f"
COLOR_PANEL = "#11294a"
COLOR_TEXT = "#e6f0ff"
COLOR_WATER = "#12335a"
COLOR_ROCK = "#555f6a"
COLOR_SEAWEED = "#2f7a52"
COLOR_CRYSTAL = "#00d8ff"
COLOR_PEARL = "#f5f0d6"
COLOR_GOLD = "#f2c94c"
COLOR_MINE = "#b03a2e"
COLOR_OXYGEN = "#7ed3f7"
COLOR_SURFACE = "#98e37e"
COLOR_BATHYSCAPHE = "#ffb84d"
START_OXYGEN = 100
START_BATTERY = 100
OXYGEN_COST = 2
BATTERY_COST = 1
RESOURCE_SCORES = {"crystal": 10, "pearl": 20, "gold": 35}
OBSTACLE_PENALTIES = {"mine": -15}
LEVELS = [
{"name": "Мелководье", "obstacles": 12, "resources": 10, "mines": 0},
{"name": "Подводныерифы", "obstacles": 22, "resources": 12, "mines": 2},
{"name": "Глубина", "obstacles": 30, "resources": 14, "mines": 4},
{"name": "Затонувшийгород", "obstacles": 38, "resources": 16, "mines": 6},
]
class World:
def __init__(self, cols, rows, obstacles_count, resources_count,
mines_count):
self.cols = cols
self.rows = rows
self.obstacles_count = obstacles_count
self.resources_count = resources_count
self.mines_count = mines_count
self.grid = [["empty"] * cols for _ in range(rows)]
self.start_position = (1, 1)
self.surface_position = (cols - 2, rows - 2)
def generate(self):
self.grid = [["empty"] * self.cols for _ in range(self.rows)]
self.start_position = (1, 1)
self.surface_position = (self.cols - 2, self.rows - 2)
sx, sy = self.surface_position
self.grid[sy][sx] = "surface"
self._place_obstacles()
self._place_resources()
self._place_mines()
self._place_oxygen_stations(2)
def get_cell(self, x, y):
return self.grid[y][x]
def set_cell(self, x, y, value):
self.grid[y][x] = value
def is_inside(self, x, y):
return 0 <= x <self.cols and 0 <= y <self.rows
def _is_protected(self, x, y, radius=1):
sx, sy = self.start_position
fx, fy = self.surface_position
near_start = abs(x - sx) <= radius and abs(y - sy) <= radius
near_finish = abs(x - fx) <= radius and abs(y - fy) <= radius
return near_start or near_finish
def _place_obstacles(self):
placed = 0
attempts = 0
while placed <self.obstacles_count and attempts < 1000:
attempts += 1
x = random.randint(0, self.cols - 1)
y = random.randint(0, self.rows - 1)
if self._is_protected(x, y) or self.grid[y][x] != "empty":
continue
self.grid[y][x] = random.choice(["rock", "rock", "seaweed"])
placed += 1
def _place_resources(self):
pool = ["crystal"] * 5 + ["pearl"] * 3 + ["gold"] * 2
placed = 0
attempts = 0
while placed <self.resources_count and attempts < 1000:
attempts += 1
x = random.randint(0, self.cols - 1)
y = random.randint(0, self.rows - 1)
if self._is_protected(x, y) or self.grid[y][x] != "empty":
continue
self.grid[y][x] = random.choice(pool)
placed += 1
def _place_mines(self):
placed = 0
attempts = 0
while placed <self.mines_count and attempts < 1000:
attempts += 1
x = random.randint(0, self.cols - 1)
y = random.randint(0, self.rows - 1)
if self._is_protected(x, y, radius=2) or \
self.grid[y][x] != "empty":
continue
self.grid[y][x] = "mine"
placed += 1
def _place_oxygen_stations(self, count):
placed = 0
attempts = 0
while placed < count and attempts < 1000:
attempts += 1
x = random.randint(0, self.cols - 1)
y = random.randint(0, self.rows - 1)
if self._is_protected(x, y) or self.grid[y][x] != "empty":
continue
self.grid[y][x] = "oxygen_station"
placed += 1
class Bathyscaphe:
def __init__(self, x, y, oxygen, battery):
self.x = x
self.y = y
self.oxygen = oxygen
self.battery = battery
self.inventory = {}
def move_to(self, new_x, new_y):
self.x = new_x
self.y = new_y
def is_alive(self):
return self.oxygen> 0 and self.battery> 0
class Renderer:
def __init__(self, canvas, world, bathyscaphe):
self.canvas = canvas
self.world = world
self.bathyscaphe = bathyscaphe
def draw_world(self):
self.canvas.delete("all")
for y in range(self.world.rows):
for x in range(self.world.cols):
self._draw_cell(x, y, self.world.get_cell(x, y))
def draw_bathyscaphe(self):
x = self.bathyscaphe.x
y = self.bathyscaphe.y
px, py = x * CELL_SIZE, y * CELL_SIZE
pad = 4
# Корпус
self.canvas.create_oval(
px + pad, py + pad + 4,
px + CELL_SIZE - pad, py + CELL_SIZE - pad - 4,
fill=COLOR_BATHYSCAPHE, outline="#a65a00", width=2
)
# Иллюминатор
cx = px + CELL_SIZE // 2
cy = py + CELL_SIZE // 2
r = 6
self.canvas.create_oval(
cx - r, cy - r, cx + r, cy + r,
fill="#0b1d33", outline="#cceeff", width=1
)
# Пропеллеры
self.canvas.create_line(
px + 2, cy, px + pad, cy, fill="#a65a00", width=2
)
self.canvas.create_line(
px + CELL_SIZE - pad, cy, px + CELL_SIZE - 2, cy,
fill="#a65a00", width=2
)
def _draw_cell(self, x, y, cell_type):
self._draw_water(x, y)
if cell_type == "rock":
self._draw_rock(x, y)
elifcell_type == "seaweed":
self._draw_seaweed(x, y)
elifcell_type == "crystal":
self._draw_crystal(x, y)
elifcell_type == "pearl":
self._draw_pearl(x, y)
elifcell_type == "gold":
self._draw_gold(x, y)
elifcell_type == "mine":
self._draw_mine(x, y)
elifcell_type == "oxygen_station":
self._draw_oxygen_station(x, y)
elifcell_type == "surface":
self._draw_surface(x, y)
def _draw_water(self, x, y):
px, py = x * CELL_SIZE, y * CELL_SIZE
self.canvas.create_rectangle(
px, py, px + CELL_SIZE, py + CELL_SIZE,
fill=COLOR_WATER, outline=COLOR_GRID
)
def _draw_rock(self, x, y):
px, py = x * CELL_SIZE, y * CELL_SIZE
points = [
px + 6, py + CELL_SIZE - 6,
px + 12, py + 10,
px + CELL_SIZE // 2, py + 6,
px + CELL_SIZE - 10, py + 14,
px + CELL_SIZE - 4, py + CELL_SIZE - 6,
]
self.canvas.create_polygon(
points, fill=COLOR_ROCK, outline="#2a3138", width=2
)
def _draw_seaweed(self, x, y):
px, py = x * CELL_SIZE, y * CELL_SIZE
for offset in (10, CELL_SIZE // 2, CELL_SIZE - 10):
self.canvas.create_line(
px + offset, py + CELL_SIZE - 4,
px + offset - 3, py + CELL_SIZE // 2,
px + offset + 2, py + 10,
fill=COLOR_SEAWEED, width=3, smooth=True
)
def _draw_crystal(self, x, y):
px, py = x * CELL_SIZE, y * CELL_SIZE
cx = px + CELL_SIZE // 2
cy = py + CELL_SIZE // 2
s = 12
self.canvas.create_polygon(
cx, cy - s, cx + s, cy, cx, cy + s, cx - s, cy,
fill=COLOR_CRYSTAL, outline="#ffffff", width=2
)
def _draw_pearl(self, x, y):
px, py = x * CELL_SIZE, y * CELL_SIZE
cx = px + CELL_SIZE // 2
cy = py + CELL_SIZE // 2
r = 12
self.canvas.create_oval(
cx - r, cy - r, cx + r, cy + r,
fill=COLOR_PEARL, outline="#888", width=1
)
self.canvas.create_oval(
cx - 5, cy - 6, cx - 1, cy - 2,
fill="#ffffff", outline=""
)
def _draw_gold(self, x, y):
px, py = x * CELL_SIZE, y * CELL_SIZE
pad = 8
self.canvas.create_rectangle(
px + pad, py + pad + 4,
px + CELL_SIZE - pad, py + CELL_SIZE - pad - 4,
fill=COLOR_GOLD, outline="#a07a00", width=2
)
self.canvas.create_line(
px + pad + 2, py + pad + 7,
px + CELL_SIZE - pad - 2, py + pad + 7,
fill="#fff3a0", width=2
)
def _draw_mine(self, x, y):
px, py = x * CELL_SIZE, y * CELL_SIZE
cx = px + CELL_SIZE // 2
cy = py + CELL_SIZE // 2
r = 10
for dx, dy in [(-14, 0), (14, 0), (0, -14), (0, 14),
(-10, -10), (10, -10), (-10, 10), (10, 10)]:
self.canvas.create_line(
cx, cy, cx + dx, cy + dy,
fill=COLOR_MINE, width=3
)
self.canvas.create_oval(
cx - r, cy - r, cx + r, cy + r,
fill=COLOR_MINE, outline="#5f0e0e", width=2
)
def _draw_oxygen_station(self, x, y):
px, py = x * CELL_SIZE, y * CELL_SIZE
cx = px + CELL_SIZE // 2
cy = py + CELL_SIZE // 2
r = 14
self.canvas.create_oval(
cx - r, cy - r, cx + r, cy + r,
fill=COLOR_OXYGEN, outline="#1a6a94", width=2
)
self.canvas.create_text(
cx, cy, text="O2",
font=("Arial", 10, "bold"), fill="#0b1d33"
)
def _draw_surface(self, x, y):
px, py = x * CELL_SIZE, y * CELL_SIZE
pad = 5
self.canvas.create_rectangle(
px + pad, py + pad,
px + CELL_SIZE - pad, py + CELL_SIZE - pad,
fill=COLOR_SURFACE, outline="#2a6e1a", width=2
)
cx = px + CELL_SIZE // 2
cy = py + CELL_SIZE // 2
self.canvas.create_polygon(
cx, cy - 8, cx + 7, cy + 2, cx - 7, cy + 2,
fill="#2a6e1a"
)
self.canvas.create_rectangle(
cx - 2, cy + 2, cx + 2, cy + 10,
fill="#2a6e1a", outline=""
)
class StatsPanel(tk.Frame):
def __init__(self, parent):
super().__init__(parent, bg=COLOR_PANEL)
title = tk.Label(self, text="Панельуправления",
bg=COLOR_PANEL, fg=COLOR_TEXT,
font=("Arial", 13, "bold"))
title.pack(anchor="w")
self.level_label = tk.Label(self, text="Уровень: —",
bg=COLOR_PANEL, fg=COLOR_TEXT,
font=("Arial", 11), anchor="w")
self.level_label.pack(fill="x", pady=(8, 2))
self.score_label = tk.Label(self, text="Очки: 0",
bg=COLOR_PANEL, fg="#ffd17a",
font=("Arial", 14, "bold"), anchor="w")
self.score_label.pack(fill="x", pady=2)
self.moves_label = tk.Label(self, text="Ходов: 0",
bg=COLOR_PANEL, fg=COLOR_TEXT,
font=("Arial", 11), anchor="w")
self.moves_label.pack(fill="x", pady=2)
tk.Label(self, text="Кислород:",
bg=COLOR_PANEL, fg=COLOR_TEXT,
font=("Arial", 10), anchor="w").pack(fill="x", pady=(10, 0))
self.oxygen_bar = ttk.Progressbar(self, orient="horizontal",
length=180, maximum=START_OXYGEN)
self.oxygen_bar.pack(fill="x")
self.oxygen_value = tk.Label(self,
text=f"{START_OXYGEN}/{START_OXYGEN}",
bg=COLOR_PANEL, fg="#7ed3f7",
font=("Arial", 10), anchor="e")
self.oxygen_value.pack(fill="x")
tk.Label(self, text="Батарея:",
bg=COLOR_PANEL, fg=COLOR_TEXT,
font=("Arial", 10), anchor="w").pack(fill="x", pady=(8, 0))
self.battery_bar = ttk.Progressbar(self, orient="horizontal",
length=180, maximum=START_BATTERY)
self.battery_bar.pack(fill="x")
self.battery_value = tk.Label(self,
text=f"{START_BATTERY}/{START_BATTERY}",
bg=COLOR_PANEL, fg="#f5d97a",
font=("Arial", 10), anchor="e")
self.battery_value.pack(fill="x")
tk.Label(self, text="Инвентарь:",
bg=COLOR_PANEL, fg=COLOR_TEXT,
font=("Arial", 11, "bold"),
anchor="w").pack(fill="x", pady=(10, 2))
self.inventory_label = tk.Label(self, text="— пусто —",
bg=COLOR_PANEL, fg="#d7e6ff",
font=("Arial", 10),
anchor="w", justify="left")
self.inventory_label.pack(fill="x")
self.message_label = tk.Label(self, text="",
bg=COLOR_PANEL, fg="#b5d9ff",
font=("Arial", 10, "italic"),
anchor="w", wraplength=200,
justify="left")
self.message_label.pack(fill="x", pady=(10, 0))
def update_values(self, level, level_name, score, moves,
oxygen, battery, inventory):
self.level_label.config(text=f"Уровень: {level} — {level_name}")
self.score_label.config(text=f"Очки: {score}")
self.moves_label.config(text=f"Ходов: {moves}")
self.oxygen_bar["value"] = oxygen
self.oxygen_value.config(text=f"{oxygen}/{START_OXYGEN}")
self.battery_bar["value"] = battery
self.battery_value.config(text=f"{battery}/{START_BATTERY}")
self.inventory_label.config(text=self._format_inventory(inventory))
def set_message(self, text):
self.message_label.config(text=text)
@staticmethod
def _format_inventory(inventory):
if not inventory:
return "— пусто —"
names = {"crystal": "Кристаллы", "pearl": "Жемчуг", "gold": "Золото"}
lines = []
for key, count in inventory.items():
label = names.get(key, key)
lines.append(f" {label}: {count}")
return "\n".join(lines)
class BathyscapheApp:
def __init__(self, root):
self.root = root
self.root.title(WINDOW_TITLE)
self.root.configure(bg=COLOR_BG)
self.root.resizable(False, False)
self.current_level = 0
self.game_over = False
self.score = 0
self.moves = 0
self._create_menu()
self._create_widgets()
self._start_level(self.current_level)
self._bind_keys()
def _create_menu(self):
menu_bar = tk.Menu(self.root)
game_menu = tk.Menu(menu_bar, tearoff=0)
game_menu.add_command(label="Новаяигра", command=self._new_game)
game_menu.add_command(label="Перезапуститьуровень",
command=self._restart_level)
game_menu.add_separator()
game_menu.add_command(label="Сохранитьрезультат",
command=self._save_result)
game_menu.add_separator()
game_menu.add_command(label="Выход", command=self.root.quit)
menu_bar.add_cascade(label="Игра", menu=game_menu)
level_menu = tk.Menu(menu_bar, tearoff=0)
for idx, level in enumerate(LEVELS):
level_menu.add_command(
label=f"Уровень {idx + 1}: {level['name']}",
command=lambda i=idx: self._start_level(i)
)
menu_bar.add_cascade(label="Уровень", menu=level_menu)
help_menu = tk.Menu(menu_bar, tearoff=0)
help_menu.add_command(label="Правила", command=self._show_rules)
help_menu.add_command(label="Опрограмме", command=self._show_about)
menu_bar.add_cascade(label="Справка", menu=help_menu)
self.root.config(menu=menu_bar)
def _create_widgets(self):
main_frame = tk.Frame(self.root, bg=COLOR_BG)
main_frame.pack(padx=10, pady=10)
canvas_width = GRID_COLS * CELL_SIZE
canvas_height = GRID_ROWS * CELL_SIZE
self.canvas = tk.Canvas(
main_frame, width=canvas_width, height=canvas_height,
bg=COLOR_BG, highlightthickness=2,
highlightbackground=COLOR_GRID
)
self.canvas.grid(row=0, column=0, rowspan=2, padx=(0, 10))
side_frame = tk.Frame(main_frame, bg=COLOR_PANEL, padx=10, pady=10)
side_frame.grid(row=0, column=1, sticky="ns")
self.stats_panel = StatsPanel(side_frame)
self.stats_panel.pack(fill="x", pady=(0, 10))
self._create_control_buttons(side_frame)
help_label = tk.Label(
main_frame,
text="Управление: стрелки / WASD. Пробел — всплыть, R — рестарт.",
bg=COLOR_BG, fg=COLOR_TEXT, font=("Arial", 10)
)
help_label.grid(row=1, column=1, pady=(10, 0), sticky="s")
def _create_control_buttons(self, parent):
btn_frame = tk.LabelFrame(
parent, text=" Управление ",
bg=COLOR_PANEL, fg=COLOR_TEXT,
font=("Arial", 11, "bold"), padx=5, pady=5
)
btn_frame.pack(fill="x")
btn_style = {
"width": 4, "height": 2,
"font": ("Arial", 12, "bold"),
"bg": "#2a6da8", "fg": "white",
"activebackground": "#3885c9",
"relief": "raised", "bd": 2
}
up_btn = tk.Button(btn_frame, text="▲",
command=lambda: self._move("up"), **btn_style)
up_btn.grid(row=0, column=1, padx=2, pady=2)
left_btn = tk.Button(btn_frame, text="◄",
command=lambda: self._move("left"), **btn_style)
left_btn.grid(row=1, column=0, padx=2, pady=2)
down_btn = tk.Button(btn_frame, text="▼",
command=lambda: self._move("down"), **btn_style)
down_btn.grid(row=1, column=1, padx=2, pady=2)
right_btn = tk.Button(btn_frame, text="►",
command=lambda: self._move("right"), **btn_style)
right_btn.grid(row=1, column=2, padx=2, pady=2)
surface_btn = tk.Button(
btn_frame, text="Всплыть",
command=self._try_surface,
bg="#d97a2b", fg="white",
activebackground="#e89a5c",
font=("Arial", 10, "bold"),
relief="raised", bd=2
)
surface_btn.grid(row=2, column=0, columnspan=3,
sticky="ew", padx=2, pady=(8, 2))
def _bind_keys(self):
self.root.bind("<Up>", lambda e: self._move("up"))
self.root.bind("<Down>", lambda e: self._move("down"))
self.root.bind("<Left>", lambda e: self._move("left"))
self.root.bind("<Right>", lambda e: self._move("right"))
for key, direction in [("w", "up"), ("s", "down"),
("a", "left"), ("d", "right")]:
self.root.bind(f"<KeyPress-{key}>",
lambda e, dr=direction: self._move(dr))
self.root.bind(f"<KeyPress-{key.upper()}>",
lambda e, dr=direction: self._move(dr))
self.root.bind("<Key>", self._on_key_press)
self.root.bind("<r>", lambda e: self._restart_level())
self.root.bind("<R>", lambda e: self._restart_level())
self.root.bind("<space>", lambda e: self._try_surface())
def _on_key_press(self, event):
ch = event.char.lower() if event.char else ""
ru_map = {
"ц": "up", "ы": "down", "ф": "left", "в": "right",
}
if ch in ru_map:
self._move(ru_map[ch])
elifch == "к": # русская К на месте R
self._restart_level()
def _start_level(self, level_index):
if level_index< 0 or level_index>= len(LEVELS):
messagebox.showinfo(
"Поздравляем!",
f"Вы прошли все уровни игры!\n"
f"Итоговый счёт: {self.score}"
)
return
self.current_level = level_index
self.game_over = False
self.moves = 0
level_cfg = LEVELS[level_index]
self.world = World(
cols=GRID_COLS, rows=GRID_ROWS,
obstacles_count=level_cfg["obstacles"],
resources_count=level_cfg["resources"],
mines_count=level_cfg["mines"]
)
self.world.generate()
start_x, start_y = self.world.start_position
self.bathyscaphe = Bathyscaphe(
x=start_x, y=start_y,
oxygen=START_OXYGEN, battery=START_BATTERY
)
self.renderer = Renderer(self.canvas, self.world, self.bathyscaphe)
self._update_stats()
self.renderer.draw_world()
self.renderer.draw_bathyscaphe()
def _move(self, direction):
if self.game_over:
return
dx, dy = self._direction_to_delta(direction)
new_x = self.bathyscaphe.x + dx
new_y = self.bathyscaphe.y + dy
if not self.world.is_inside(new_x, new_y):
self.stats_panel.set_message("Границамира!")
return
cell_type = self.world.get_cell(new_x, new_y)
if cell_type == "rock":
self.stats_panel.set_message("Впередискала — непройти.")
return
self.bathyscaphe.move_to(new_x, new_y)
self.bathyscaphe.oxygen -= OXYGEN_COST
self.bathyscaphe.battery -= BATTERY_COST
self.moves += 1
self._handle_cell(new_x, new_y, cell_type)
self.renderer.draw_world()
self.renderer.draw_bathyscaphe()
self._update_stats()
self._check_game_over()
@staticmethod
def _direction_to_delta(direction):
mapping = {
"up": (0, -1), "down": (0, 1),
"left": (-1, 0), "right": (1, 0),
}
return mapping.get(direction, (0, 0))
def _handle_cell(self, x, y, cell_type):
if cell_type in RESOURCE_SCORES:
points = RESOURCE_SCORES[cell_type]
self.score += points
self.bathyscaphe.inventory[cell_type] = \
self.bathyscaphe.inventory.get(cell_type, 0) + 1
self.world.set_cell(x, y, "empty")
self.stats_panel.set_message(f"Собранресурс: +{points} очков.")
elifcell_type == "seaweed":
self.bathyscaphe.oxygen -= OXYGEN_COST
self.stats_panel.set_message(
"Водоросли: батискафпотратилбольшекислорода."
)
elifcell_type == "mine":
penalty = OBSTACLE_PENALTIES["mine"]
self.score = max(0, self.score + penalty)
self.bathyscaphe.battery -= 20
self.world.set_cell(x, y, "empty")
self.stats_panel.set_message(
"Столкновениесминой! Повреждение корпуса."
)
elifcell_type == "oxygen_station":
self.bathyscaphe.oxygen = min(
START_OXYGEN, self.bathyscaphe.oxygen + 40
)
self.world.set_cell(x, y, "empty")
self.stats_panel.set_message(
"Кислородная станция: запас восполнен."
)
def _check_game_over(self):
if self.bathyscaphe.oxygen<= 0:
self.game_over = True
messagebox.showwarning(
"Конец миссии",
"Кислород закончился. Батискаф не смог вернуться."
)
elifself.bathyscaphe.battery<= 0:
self.game_over = True
messagebox.showwarning(
"Конец миссии",
"Батарея разряжена. Батискаф потерял управление."
)
def _try_surface(self):
if self.game_over:
return
current_type = self.world.get_cell(
self.bathyscaphe.x, self.bathyscaphe.y
)
if current_type == "surface":
bonus = int(self.bathyscaphe.oxygen * 0.2 +
self.bathyscaphe.battery * 0.2)
self.score += bonus
messagebox.showinfo(
"Уровеньпройден",
f"Батискафуспешновсплыл.\n"
f"Бонус за ресурсы: +{bonus} очков.\n"
f"Общий счёт: {self.score}"
)
self._start_level(self.current_level + 1)
else:
self.stats_panel.set_message(
"Всплыть можно только из точки подъёма."
)
def _new_game(self):
self.score = 0
self._start_level(0)
def _restart_level(self):
self._start_level(self.current_level)
def _update_stats(self):
self.stats_panel.update_values(
level=self.current_level + 1,
level_name=LEVELS[self.current_level]["name"],
score=self.score,
moves=self.moves,
oxygen=max(0, self.bathyscaphe.oxygen),
battery=max(0, self.bathyscaphe.battery),
inventory=self.bathyscaphe.inventory
)
def _save_result(self):
data = {
"level": self.current_level + 1,
"score": self.score,
"moves": self.moves,
"inventory": self.bathyscaphe.inventory,
}
try:
with open("result.json", "w", encoding="utf-8") as fp:
json.dump(data, fp, ensure_ascii=False, indent=2)
messagebox.showinfo(
"Сохранено",
f"Результат записан в файл:\n"
f"{os.path.abspath('result.json')}"
)
except OSError as exc:
messagebox.showerror("Ошибка", f"Неудалосьсохранить: {exc}")
@staticmethod
def _show_rules():
rules = (
"Правилаигры 'Батискаф':\n\n"
"1. Батискаф перемещается по подводному миру, "
"разделённому на клетки.\n"
"2. Нужно собирать ресурсы: кристаллы, жемчуг, золото.\n"
"3. Следите за уровнем кислорода и заряда батареи.\n"
"4. Избегайте мин — они повреждают корпус.\n"
"5. Скалы непроходимы, их нужно обходить.\n"
"6. Водоросли проходимы, но расходуют больше кислорода.\n"
"7. Для завершения уровня найдите точку подъёма "
"и нажмите 'Всплыть'."
)
messagebox.showinfo("Правила", rules)
@staticmethod
def _show_about():
about = (
"Управляемая модель исполнителя 'Батискаф'\n\n"
"Курсовая работа по дисциплине МДК 01.01\n"
"Разработка программных модулей\n\n"
"Среда разработки: PyCharm\n"
"Язык программирования: Python 3.11\n"
"Графическая библиотека: Tkinter\n\n"
"Версия программы: 1.0"
)
messagebox.showinfo("О программе", about)
def main():
root = tk.Tk()
app = BathyscapheApp(root)
root.mainloop()
if __name__ == "__main__":
main()