#!/usr/bin/env ruby # encoding: utf-8 require 'json' require 'colorize' # для цветной вывода (установите: gem install colorize) class SpaceAdventure4K SAVE_FILE = 'savegame_4k.json' VERSION = '1.2.0' # Меню с расширенными опциями MAIN_MENU = { '1' => 'Проверить курс (координаты и статус)', '2' => 'Переместиться в сектор (X Y Z)', '3' => 'Исследовать текущий сектор', '4' => 'Поговорить с ИИ‑помощником «Эхо‑4K»', '5' => 'Проверить инвентарь и экипировку', '6' => 'Сохранить игру', '7' => 'Посетить космический рынок', '8' => 'Выйти из игры', '9' => 'Активировать сканер аномалий', '10' => 'Проверить журнал миссий', 'give_credits' => '[ОТЛАДКА] Начислить 8 888 888 888 CR', 'give_all' => '[ОТЛАДКА] Получить всё: топливо, кристаллы, артефакты' } def initialize load_game || reset_game @mission_log = [] end def reset_game @position = { x: 0, y: 0, z: 0 } @health = 100 @fuel = 150 # увеличено @credits = 100 # увеличено @crystals = 0 @inventory = ['сканер-прототип'] @game_over = false @sector_map = {} @level = 1 @target = { x: 8, y: -5, z: 4 } # дальше @ship = :phoenix_4k @shield_active = false @anomaly_level = 0 # уровень аномалий в текущем секторе @experience = 0 end def load_game if File.exist?(SAVE_FILE) data = JSON.parse(File.read(SAVE_FILE)) @position = data['position'] @health = data['health'] @fuel = data['fuel'] @credits = data['credits'] @crystals = data['crystals'] || 0 @inventory = data['inventory'] @sector_map = data['sector_map'] @level = data['level'] @target = data['target'] @ship = data['ship'] || :phoenix_4k @shield_active = data['shield_active'] || false @anomaly_level = data['anomaly_level'] || 0 @experience = data['experience'] || 0 @mission_log = data['mission_log'] || [] puts "✅ Игра загружена! Версия #{VERSION}".green return true end false end def save_game data = { position: @position, health: @health, fuel: @fuel, credits: @credits, crystals: @crystals, inventory: @inventory, sector_map: @sector_map, level: @level, target: @target, ship: @ship, shield_active: @shield_active, anomaly_level: @anomaly_level, experience: @experience, mission_log: @mission_log } File.write(SAVE_FILE, JSON.generate(data)) puts "💾 Игра сохранена в #{SAVE_FILE}!".blue end def show_status system_info = [ "🚀 КОСМИЧЕСКИЙ СИМУЛЯТОР «ГАЛАКТИКА‑4K» v#{VERSION}", "📍 Позиция: X=#{@position[:x]}, Y=#{@position[:y]}, Z=#{@position[:z]}", "🎯 Цель: X=#{@target[:x]}, Y=#{@target[:y]}, Z=#{@target[:z]}", "❤ Здоровье: #{bar(@health, 100, :red)} (#{@health}%)", "⛽ Топливо: #{bar(@fuel, 150, :yellow)} (#{@fuel} ед.)", "💰 Кредиты: #{@credits} CR", "💎 Кристаллы: #{@crystals} 🔮", "🛡 Защита: #{@shield_active ? 'активна' : 'выкл.'}", "🗺 Исследовано: #{@sector_map.size} секторов", "⭐ Опыт: #{@experience} XP", "📜 Уровень: #{@level}", "🧭 До цели: #{calc_distance(@position, @target).round(1)} ед." ] puts "\n! + "═" * 60 system_info.each { |line| puts "│ #{line}".light_white } puts "═! * 60 end def bar(value, max, color) filled = (value.to_f / max * 20).to_i bar = '█' * filled + '░' * (20 - filled) bar.colorize(color) end def ship_name(symbol) { phoenix_4k: 'Феникс‑4K (улучшенный)', warrior_4k: 'Воин‑4K', scout_4k: 'Скаут‑4K' }[symbol] || 'Неизвестный корабль' end def calc_distance(a, b) Math.sqrt((a[:x] - b[:x])**2 + (a[:y] - b[:y])**2 + (a[:z] - b[:z])**2) end def prompt print "\n▸ ".cyan gets.chomp.downcase end def display_menu puts "\n🚀 ЧТО ВЫ ХОТИТЕ СДЕЛАТЬ?" MAIN_MENU.each do |key, label| puts " #{key.rjust(3)}. #{label}".light_cyan end end def show_mini_map puts "\n🗺 МИНИ‑КАРТА (область ±2 от текущей позиции)".yellow (-2..2).each do |dz| line = [] (-2..2).each do |dy| (-2..2).each do |dx| abs_x = @position[:x] + dx abs_y = @position[:y] + dy abs_z = @position[:z] + dz key = "#{abs_x}-#{abs_y}-#{abs_z}" if abs_x == @position[:x] && abs_y == @position[:y] && abs_z == @position[:z] line << "[*]".green elsif @sector_map[key] line << "[.]".blue else line << "[...]".dark_gray end end end puts line.join(" ") end end def explore_sector(pos) key = "#{pos[:x]}-#{pos[:y]}-#{pos[:z]}" if @sector_map[key] puts "Этот сектор уже исследован. Данные в архиве.".yellow return end puts "\n🔍 Активирую 4K‑сканеры... Анализ сектора #{key}...".cyan sleep 0.7 event = weighted_random_event case event when :credit_cache gain = rand(50..150) @credits += gain log_mission("Найден кэш кредитов: +#{gain} CR") puts "✓ Обнаружен тайник с кредитами! +#{gain} CR.".green when :pirate_attack if @inventory.include?('щит‑4K') puts "⚔ Щит‑4K поглотил удар! Атака нейтрализована.".blue else damage = rand(20..4