Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 

Repository files navigation

🚀 SpaceQuest: Космическое приключение

Обучающая текстовая игра на Swift для macOS. Создана, чтобы помочь новичкам освоить основы языка Swift через практику — читай код, играй, разбирайся!


📋 Содержание


🚀 Как запустить

Убедись, что у тебя установлен Swift 5.9+:

swift --version

Сборка и запуск:

cd SpaceQuest
swift run

Или собери, а потом запусти бинарник:

swift build
.build/debug/SpaceQuest

📖 Сюжет

Ты — капитан космического корабля «Комета». Корабль терпит крушение на неизвестной планете (это Земля, но ты ещё не знаешь 😉).

Двигатель повреждён. Чтобы улететь, нужно найти 5 деталей:

  1. ⚙️ Топливный насос
  2. 🌡️ Термостат
  3. 🧲 Катушка зажигания
  4. 🧠 Процессор
  5. 🔩 Уплотнитель

Каждая деталь — на отдельном уровне-испытании. Собери все 5 — почини двигатель и улетай!


🎮 Уровни

# Уровень Что нужно делать
1 Крушение Выбраться из обломков. Выбрать направление
2 Лес Сразиться с диким волком
3 Завод Угадать код сейфа (подсказка: 42)
4 Страж Битва с босс-роботом
5 Запуск Разобрать завал, найти последнюю деталь

📁 Структура проекта

SpaceQuest/
├── Package.swift           # Конфигурация Swift Package Manager
├── README.md               # Этот файл (документация)
└── Sources/SpaceQuest/
    ├── main.swift          # Точка входа (минимальный код)
    ├── Game.swift          # Игровой движок (class, Dictionary, циклы)
    ├── Player.swift        # Модель игрока (struct, didSet, lazy)
    ├── Enemy.swift         # Враги и бой (class, наследование, inout)
    ├── Levels.swift        # 5 уровней (функции, switch, while)
    └── Utils.swift         # Шпаргалка по Swift (closures, async, enum, и т.д.)

Важно: Utils.swift не используется в игре. Это шпаргалка с примерами синтаксиса. Открывай её, когда хочешь вспомнить, как работает конкретная конструкция.


📚 Swift: конструкции по файлам

📄 Package.swift

Конструкция Описание
import PackageDescription Подключение модуля SPM
let Константа (неизменяемое значение)
Package(name:platforms:targets:) Структура с именованными параметрами
[.macOS(.v13)] Массив с элементами-значениями

📄 main.swift

Конструкция Описание
import Foundation Подключение стандартной библиотеки Foundation
let + Game() Создание константы через инициализатор
game.start() Вызов метода через точку

📄 Game.swift

Конструкция Описание
class Game class — ссылочный тип (хип, ARC, наследование)
var player = Player(...) var — изменяемое свойство
var foundParts: [String: Bool] Dictionary — словарь «ключ: значение»
var allPartsFound: Bool { ... } Computed property — вычисляемое свойство
foundParts.values.allSatisfy { } Метод с closure — allSatisfy принимает замыкание
let levels: [(Game) -> Void] Массив функций — функции как значения
levels[levelIndex](self) Вызов функции из массива
while isRunning && ... while — цикл с условием
if let name = readLine() if let — безопасное извлечение Optional
"\(player.name)" Интерполяция строк — подстановка значений
private func private — модификатор доступа (только внутри)
player.heal(30) Вызов mutating метода у struct через var-свойство class

Почему Game — class, а не struct? Игра — единственный «центр управления». Мы хотим, чтобы все ссылались на один и тот же объект, а не на копии.

📄 Player.swift

Конструкция Описание
struct Player struct — значениевый тип (стек, копируется)
let id = UUID() let — константа (неизменяемая после создания)
var name: String { didSet { } } Property observer — наблюдение за изменениями
var health: Int { didSet { } } didSet для валидации (не даём уйти за 0 или max)
var isAlive: Bool { health > 0 } Computed property — без хранения, только get
lazy var greeting: String = { }() Lazy var — инициализация при первом доступе
init(name:health:maxHealth:) init — инициализатор (конструктор)
mutating func takeDamage() mutating func — метод, изменяющий struct

Почему Player — struct, а не class? Игрок — это модель данных. struct копируется при присвоении, что безопаснее для конкурентности. Плюс стек быстрее хипа.

didSet vs willSet:

  • didSet — вызывается ПОСЛЕ изменения (есть oldValue)
  • willSet — вызывается ДО изменения (есть newValue)

📄 Enemy.swift

Конструкция Описание
class Enemy class — базовый класс
init(name:health:attackPower:) Designated init — главный инициализатор
convenience init(name: String) Convenience init — вспомогательный, вызывает self.init
func attack() -> Int Обычный метод
deinit { } deinit — вызывается при удалении объекта (ARC)
class BossEnemy: Enemy Наследование — класс-потомок
override func attack() override — переопределение метода родителя
super.init(...) super — вызов родительского инициализатора
func fight(player: inout Player) inout — передача параметра по ссылке
switch choice { case 1: ... } switch — множественное ветвление с default
guard let ... else { return } guard — ранний выход из функции
continue continue — переход к следующей итерации цикла

Про weak и ARC (подробнее в Utils.swift):

  • weak — слабая ссылка (не увеличивает счётчик ARC)
  • unowned — как weak, но краш при обращении к удалённому объекту
  • deinit — подтверждает, что объект удалён из памяти

📄 Levels.swift

Конструкция Описание
func levelCrash(game: Game) Функция верхнего уровня (не в классе)
readLine() Чтение строки из терминала (возвращает String?)
Int(input) Преобразование String в Int (возвращает Int?)
switch choice { case 1: ... } switch с разными case + default
while attempts > 0 { } while с счётчиком
rubble.randomElement() randomElement() — случайный элемент массива
rubble.firstIndex(of: "камень") firstIndex(of:) — поиск индекса
rubble.remove(at: idx) remove(at:) — удаление по индексу
Bool.random() Случайный true/false
_ = readLine() _ (wildcard) — игнорируем返回值
return Выход из функции (с return и без)
break Выход из цикла

📄 Utils.swift

Шпаргалка с примерами. Содержит:

Раздел Конструкции
1. Функции Параметры, return, default, variadic, inout
2. Closures Анонимные функции, @escaping, trailing, capture
3. Memory / ARC class, weak, unowned, deinit
4. async / await async func, await, Task, Task.sleep
5. Enum enum, rawValue, associated values, computed property
6. Switch Диапазоны, where, exhaustiveness
7. Optionals ?, !, ??, if let, guard let
8. Error handling throws, do-catch, try?, try!
9. Protocol + Extension protocol, struct: Protocol, extension Int
10. Generics , where T: Equatable

🗺️ Карта обучения

Если ты совсем новичок — изучай в таком порядке:

Этап 1: База (файлы: Game, Player, Levels)

  1. Переменные: var vs let (Game.swift:38-41)
  2. Типы данных: String, Int, Bool, [String] (Player.swift:24-57)
  3. Функции: func name(param: Type) -> Return (Levels.swift:20)
  4. Условные операторы: if, guard, switch (Enemy.swift:120)
  5. Циклы: while, for-in (Levels.swift:104, 172)
  6. Optional: ?, !, ??, if let, guard let (Game.swift:114)

Этап 2: Структуры и классы (файлы: Player, Enemy)

  1. struct — значениевый тип (Player.swift:24)
  2. class — ссылочный тип (Enemy.swift:21)
  3. Разница struct vs class (таблица в Game.swift:25-32)
  4. Инициализаторы: init, convenience init (Enemy.swift:30-47)
  5. Наследование: class BossEnemy: Enemy (Enemy.swift:70)
  6. override — переопределение (Enemy.swift:86)

Этап 3: Продвинутые концепции (файлы: все)

  1. Computed properties (Game.swift:55, Player.swift:57)
  2. Property observers: didSet (Player.swift:35)
  3. mutating func в struct (Player.swift:78)
  4. Closures — замыкания (Utils.swift:69-114)
  5. inout параметры (Enemy.swift:99)
  6. deinit — удаление из памяти (Enemy.swift:62)
  7. Dictionary [Key: Value] (Game.swift:45)
  8. lazy var — ленивая инициализация (Player.swift:61)

Этап 4: Шпаргалка (файл: Utils.swift)

  1. Error handling: throws, do-catch (Utils.swift:278-314)
  2. async/await: Task, асинхронность (Utils.swift:163-179)
  3. weak/unowned: ARC, память (Utils.swift:116-157)
  4. Protocol: контракты для типов (Utils.swift:321-336)
  5. Extension: расширение типов (Utils.swift:340-344)
  6. Generics <T>: обобщённое программирование (Utils.swift:354-372)

❓ Частые вопросы

Q: Игра не запускается, что делать? A: Проверь Swift: swift --version (нужна версия 5.9+). Если нет Swift — установи Xcode или brew install swift.

Q: Можно играть на Linux/Windows? A: Swift есть на Linux (без readLine могут быть нюансы). На Windows — через WSL или Swift For Windows.

Q: Почему комментарии на русском? A: Чтобы новичкам было понятнее. Программирование — сложная штука, незачем усложнять её английским на старте.

Q: Как добавить новый уровень? A: 1. Напиши функцию в Levels.swift: func level6(game: Game) 2. Добавь её в массив levels в Game.swift

Q: Как изменить сложность? A: Измени maxHealth игрока (Player.swift:69) или health/attackPower врагов (Enemy.swift:30-47).


📝 Лицензия

Учебный проект. Можно копировать, менять, распространять. Единственная цель — помочь людям выучить Swift. 🚀

About

# 🚀 SpaceQuest: Космическое приключение > Обучающая текстовая игра на Swift для macOS. > Создана, чтобы помочь новичкам освоить основы языка Swift > через практику — читай код, играй, разбирайся!

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages