{}const=>[]async()letfn</>var
РазработкаПрактика

🐍 Pascal жив, и он опасен: пишем мини-игры на чистой логике без движков и регистрации

Думаете, Pascal — это мёртвый язык из школьных учебников? Как бы не так. В этой статье мы докажем, что на нём можно создавать настоящие мини-игры — без движков, фреймворков и лишних зависимостей.

К

Кодик

Автор

12 мин чтения

Думаете, Pascal — это мёртвый язык из школьных учебников? Как бы не так. Создаём настоящие игры на чистой логике — без движков, фреймворков и лишних зависимостей.

💡Почему Pascal в 2025 году — это не стыдно

Каждый раз, когда кто-то произносит слово «Pascal», в комнате повисает тишина. Кто-то вспоминает школу, кто-то — Turbo Pascal на синем экране, а кто-то уверенно заявляет: «Это мёртвый язык». Но давайте разберёмся.

Pascal был создан Никлаусом Виртом в 1970 году с одной целью — научить людей программировать правильно. Не быстро, не модно, а правильно. Строгая типизация, понятный синтаксис, обязательное объявление переменных — всё это заставляет думать перед тем, как писать код.

🧠 Факт: многие топовые программисты начинали именно с Pascal. Не потому что он был модным, а потому что он учит думать структурно. Когда ты понимаешь begin...end, тебе уже не страшны фигурные скобки ни в одном языке мира.

И самое главное — Pascal идеально подходит для того, чтобы писать игры на чистой логике. Никаких Unity, никаких Godot, никаких библиотек. Только ты, компилятор и твой мозг.

🔥 100 000+ учеников уже с нами

Устал читать теорию?
Пора кодить!

Кодик — приложение, где ты учишься программировать через практику. AI-наставник, интерактивные уроки, реальные проекты.

🤖 AI 24/7
🎓 Сертификаты
💰 Бесплатно
🚀 Начать учиться
Присоединились сегодня

🛠️Что нужно для старта

Для работы с Pascal в 2025 году не нужно откапывать дискету с Turbo Pascal. Есть вполне современные инструменты:

Free Pascal (FPC) — бесплатный компилятор, работает на Windows, Linux и macOS. Скачать можно с официального сайта freepascal.org. Это наш основной инструмент.

Lazarus IDE — полноценная среда разработки с визуальным дизайнером форм. Но для наших консольных игр она избыточна.

Онлайн-компиляторы — например, onlinegdb.com поддерживает Pascal. Удобно для быстрых экспериментов, если не хочется ничего устанавливать.

Рекомендация: установите Free Pascal — это займёт пару минут, зато вы получите полноценный опыт работы с компилятором. Файлы сохраняем с расширением .pas, компилируем командой fpc myfile.pas и запускаем.

🎲Игра #1: Угадай число

Классика жанра. Компьютер загадывает число, а игрок пытается его угадать. Простая механика, но за ней скрывается работа с циклами, условиями, генерацией случайных чисел и обработкой ввода.

Чему научимся

Работа с while-циклом, оператором if-then-else, функцией random и переменными. Это фундамент, без которого никуда.

Полный код игры

program GuessTheNumber;
var
  secret, guess, attempts: integer;
begin
  randomize;
  secret := random(100) + 1;
  attempts := 0;

  writeln('=================================');
  writeln('   УГАДАЙ ЧИСЛО от 1 до 100');
  writeln('=================================');
  writeln;

  repeat
    write('Твоя догадка: ');
    readln(guess);
    attempts := attempts + 1;

    if guess < secret then
      writeln('📈 Больше! Попробуй ещё.')
    else if guess > secret then
      writeln('📉 Меньше! Попробуй ещё.')
    else
      writeln('🎉 Угадал! Ты справился за ', attempts, ' попыток!');

  until guess = secret;

  writeln;
  if attempts <= 5 then
    writeln('🏆 Отличный результат! Ты настоящий телепат!')
  else if attempts <= 10 then
    writeln('👍 Неплохо! Но можно и лучше.')
  else
    writeln('🐢 Долговато... Попробуй стратегию бинарного поиска!');

  readln;
end.

Разбор логики

Всё начинается с randomize — эта процедура инициализирует генератор случайных чисел. Без неё random будет выдавать одно и то же число при каждом запуске программы.

Цикл repeat...until работает как «повторяй, пока условие не станет истинным». Это идеальная конструкция для игр, где мы заранее не знаем, сколько итераций понадобится.

В конце мы добавили систему оценки — это мотивирует игрока попробовать ещё раз и использовать более умную стратегию. Кстати, оптимальная стратегия здесь — бинарный поиск, который гарантирует угадывание максимум за 7 попыток.

💡 Задание для продвинутых: добавьте ограничение на количество попыток. Например, у игрока есть только 7 ходов. Если не угадал — проиграл. Подсказка: добавьте проверку attempts >= 7 в условие выхода из цикла.

❌⭕Игра #2: Крестики-нолики

Переходим на следующий уровень. Крестики-нолики — это уже полноценная игра с игровым полем, проверкой победы и игрой на двоих. Здесь мы столкнёмся с массивами, вложенными циклами и более сложной логикой.

Чему научимся

Двумерные массивы, процедуры и функции, сложные условия, валидация пользовательского ввода и организация игрового цикла.

Полный код игры

program TicTacToe;
var
  board: array[1..3, 1..3] of char;
  currentPlayer: char;
  row, col, moveCount: integer;
  gameOver: boolean;

procedure InitBoard;
var
  i, j: integer;
begin
  for i := 1 to 3 do
    for j := 1 to 3 do
      board[i][j] := ' ';
end;

procedure DrawBoard;
var
  i: integer;
begin
  writeln;
  writeln('    1   2   3');
  writeln('  +---+---+---+');
  for i := 1 to 3 do
  begin
    write(i, ' | ');
    write(board[i][1], ' | ');
    write(board[i][2], ' | ');
    writeln(board[i][3], ' |');
    writeln('  +---+---+---+');
  end;
  writeln;
end;

function CheckWin(player: char): boolean;
var
  i: integer;
begin
  CheckWin := false;

  { Проверка строк и столбцов }
  for i := 1 to 3 do
  begin
    if (board[i][1] = player) and
       (board[i][2] = player) and
       (board[i][3] = player) then
      CheckWin := true;

    if (board[1][i] = player) and
       (board[2][i] = player) and
       (board[3][i] = player) then
      CheckWin := true;
  end;

  { Проверка диагоналей }
  if (board[1][1] = player) and
     (board[2][2] = player) and
     (board[3][3] = player) then
    CheckWin := true;

  if (board[1][3] = player) and
     (board[2][2] = player) and
     (board[3][1] = player) then
    CheckWin := true;
end;

begin
  writeln('=================================');
  writeln('      КРЕСТИКИ-НОЛИКИ');
  writeln('=================================');
  writeln('Игрок 1: X  |  Игрок 2: O');
  writeln('Вводите номер строки и столбца.');

  InitBoard;
  currentPlayer := 'X';
  moveCount := 0;
  gameOver := false;

  repeat
    DrawBoard;
    writeln('Ходит игрок ', currentPlayer);

    { Ввод с валидацией }
    repeat
      write('Строка (1-3): ');
      readln(row);
      write('Столбец (1-3): ');
      readln(col);

      if (row < 1) or (row > 3) or
         (col < 1) or (col > 3) then
        writeln('⚠ Неверные координаты! Введите числа от 1 до 3.')
      else if board[row][col] <> ' ' then
        writeln('⚠ Клетка занята! Выберите другую.')
      else
        break;
    until false;

    board[row][col] := currentPlayer;
    moveCount := moveCount + 1;

    { Проверка победы }
    if CheckWin(currentPlayer) then
    begin
      DrawBoard;
      writeln('🎉 Игрок ', currentPlayer, ' победил!');
      gameOver := true;
    end
    else if moveCount = 9 then
    begin
      DrawBoard;
      writeln('🤝 Ничья! Оба играли достойно.');
      gameOver := true;
    end
    else
    begin
      { Смена игрока }
      if currentPlayer = 'X' then
        currentPlayer := 'O'
      else
        currentPlayer := 'X';
    end;

  until gameOver;

  readln;
end.

Разбор ключевых моментов

Двумерный массив board[1..3, 1..3] — это наше игровое поле. Каждая ячейка хранит символ: пробел (пусто), X или O. Это классический приём для хранения состояния игрового поля.

Функция CheckWin проверяет все возможные комбинации для победы: три строки, три столбца и две диагонали — всего 8 вариантов. Это выглядит объёмно, но логика предельно простая.

Обратите внимание на валидацию ввода — мы проверяем и границы поля, и занятость клетки. Без этого игра будет ломаться при некорректном вводе. Это важный навык, который пригодится в любом проекте.

⚠️ Частая ошибка: забыть про смену игрока после хода. Без строчки, переключающей currentPlayer, оба игрока будут ставить один и тот же символ.

🗡️Игра #3: Текстовый квест

А теперь самое интересное — текстовый квест с системой здоровья, инвентарём и ветвлением сюжета. Это уже настоящая игра с нарративом, где каждый выбор влияет на результат.

Чему научимся

Конечные автоматы (finite state machines), работа с перечислениями, оператор case, структурирование сложной логики и проектирование игровых систем.

Полный код игры

program TextQuest;
var
  health, gold: integer;
  hasKey, hasSword: boolean;
  room: integer;
  choice: integer;
  playerName: string;
  gameRunning: boolean;

procedure ShowStatus;
begin
  writeln;
  writeln('--- ', playerName, ' ---');
  writeln('❤️  Здоровье: ', health);
  writeln('💰 Золото: ', gold);
  write('🎒 Инвентарь:');
  if hasSword then write(' [Меч]');
  if hasKey then write(' [Ключ]');
  if (not hasSword) and (not hasKey) then
    write(' пусто');
  writeln;
  writeln('-------------------');
end;

begin
  { Инициализация }
  health := 100;
  gold := 10;
  hasKey := false;
  hasSword := false;
  room := 1;
  gameRunning := true;

  writeln('╔═══════════════════════════════════╗');
  writeln('║     ПОДЗЕМЕЛЬЯ ЗАБЫТОГО КОРОЛЯ    ║');
  writeln('╚═══════════════════════════════════╝');
  writeln;
  write('Как тебя зовут, искатель приключений? ');
  readln(playerName);
  writeln;
  writeln('Добро пожаловать, ', playerName, '!');
  writeln('Ты стоишь у входа в древнее подземелье...');

  while gameRunning and (health > 0) do
  begin
    ShowStatus;

    case room of
      { === Комната 1: Вход в подземелье === }
      1:
      begin
        writeln;
        writeln('🏰 Ты у входа в подземелье.');
        writeln('Перед тобой тёмный коридор,');
        writeln('а справа — тусклый свет факела.');
        writeln;
        writeln('1 → Идти вперёд по коридору');
        writeln('2 → Свернуть на свет');
        writeln('3 → Осмотреть стены');
        write('Выбор: ');
        readln(choice);

        case choice of
          1: room := 2;
          2: room := 3;
          3:
          begin
            writeln;
            writeln('🔍 Ты ощупываешь стены и находишь');
            writeln('   скрытый тайник с 15 золотыми!');
            gold := gold + 15;
          end;
        else
          writeln('❓ Непонятный выбор. Попробуй снова.');
        end;
      end;

      { === Комната 2: Тёмный коридор === }
      2:
      begin
        writeln;
        writeln('🌑 Тёмный коридор. Тихо капает вода.');
        writeln('Впереди развилка: лестница вниз');
        writeln('и дверь с ржавым замком.');
        writeln;
        writeln('1 → Спуститься по лестнице');
        writeln('2 → Попробовать открыть дверь');
        writeln('3 → Вернуться назад');
        write('Выбор: ');
        readln(choice);

        case choice of
          1: room := 4;
          2:
          begin
            if hasKey then
            begin
              writeln;
              writeln('🔓 Ключ подошёл! Дверь со скрипом');
              writeln('   открывается...');
              room := 5;
            end
            else
            begin
              writeln;
              writeln('🔒 Дверь заперта. Нужен ключ.');
            end;
          end;
          3: room := 1;
        else
          writeln('❓ Непонятный выбор.');
        end;
      end;

      { === Комната 3: Торговец === }
      3:
      begin
        writeln;
        writeln('🕯️ Ты нашёл комнату старого торговца.');
        writeln('"Приветствую, путник!" — говорит он.');
        writeln;
        writeln('1 → Купить меч (25 золотых)');
        writeln('2 → Купить ключ (15 золотых)');
        writeln('3 → Купить зелье лечения (10 золотых)');
        writeln('4 → Уйти обратно');
        write('Выбор: ');
        readln(choice);

        case choice of
          1:
          begin
            if gold >= 25 then
            begin
              gold := gold - 25;
              hasSword := true;
              writeln;
              writeln('⚔️ Ты купил острый меч!');
            end
            else
              writeln('💸 Не хватает золота...');
          end;
          2:
          begin
            if gold >= 15 then
            begin
              gold := gold - 15;
              hasKey := true;
              writeln;
              writeln('🗝️ Ты купил старый ключ!');
            end
            else
              writeln('💸 Не хватает золота...');
          end;
          3:
          begin
            if gold >= 10 then
            begin
              gold := gold - 10;
              health := health + 30;
              writeln;
              writeln('🧪 Ты выпил зелье. Здоровье восстановлено!');
            end
            else
              writeln('💸 Не хватает золота...');
          end;
          4: room := 1;
        else
          writeln('❓ Непонятный выбор.');
        end;
      end;

      { === Комната 4: Логово монстра === }
      4:
      begin
        writeln;
        writeln('👹 Ты спустился в логово!');
        writeln('Перед тобой — огромный тролль!');
        writeln;
        writeln('1 → Атаковать');
        writeln('2 → Попытаться убежать');
        write('Выбор: ');
        readln(choice);

        case choice of
          1:
          begin
            if hasSword then
            begin
              writeln;
              writeln('⚔️ Ты сражаешь тролля мечом!');
              writeln('   Он падает, роняя 50 золотых!');
              gold := gold + 50;
              health := health - 15;
              room := 5;
            end
            else
            begin
              writeln;
              writeln('👊 Без оружия тролль почти убил тебя!');
              writeln('   Ты едва сбежал...');
              health := health - 50;
              room := 2;
            end;
          end;
          2:
          begin
            writeln;
            writeln('🏃 Ты бежишь! Тролль царапает тебя.');
            health := health - 20;
            room := 2;
          end;
        else
          writeln('❓ Пока ты думал, тролль ударил!');
          health := health - 30;
        end;
      end;

      { === Комната 5: Сокровищница === }
      5:
      begin
        writeln;
        writeln('✨ ТЫ НАШЁЛ СОКРОВИЩНИЦУ!');
        writeln;
        writeln('╔═══════════════════════════════╗');
        writeln('║  Горы золота сверкают перед    ║');
        writeln('║  тобой. Ты победил подземелье! ║');
        writeln('╚═══════════════════════════════╝');
        writeln;
        writeln('📊 Итоги приключения:');
        writeln('   Здоровье: ', health);
        writeln('   Золото: ', gold + 100);
        writeln;
        if health >= 80 then
          writeln('🏆 Ранг: ЛЕГЕНДА')
        else if health >= 50 then
          writeln('🥈 Ранг: ВЕТЕРАН')
        else
          writeln('🩹 Ранг: ВЫЖИВШИЙ');

        gameRunning := false;
      end;
    end; { case room }
  end; { while }

  if health <= 0 then
  begin
    writeln;
    writeln('💀 Твоё здоровье иссякло...');
    writeln(playerName, ' погиб в подземелье.');
    writeln('Попробуй снова!');
  end;

  writeln;
  writeln('Спасибо за игру!');
  readln;
end.

Разбор архитектуры

Это уже не просто программа — это конечный автомат. Переменная room определяет текущее состояние игры, а выбор игрока переключает это состояние. Такая архитектура используется не только в играх, но и в парсерах, сетевых протоколах и системах управления.

Оператор case — настоящий герой этой программы. Он позволяет элегантно обрабатывать множество вариантов без цепочек if-else. Вложенные case внутри case делают код читаемым и расширяемым.

Обратите внимание на систему инвентаря — мы используем обычные булевы переменные. Для более сложных игр можно использовать массивы или записи (record), но для нашего квеста этого достаточно.

🚀 Идея для расширения: добавьте новые комнаты, врагов с разной силой, систему уровней или случайные события. Каждое такое добавление — это новый алгоритмический вызов.

🧠Почему именно игры учат программировать?

Написание игр — это не просто развлечение. Это один из самых эффективных способов изучить программирование. И вот почему.

Мгновенная обратная связь. Написал код — запустил — увидел результат. Не абстрактные числа в консоли, а живую, работающую игру. Мозг получает дофамин, и учёба превращается из рутины в удовольствие.

Все концепции в одном месте. В одной маленькой игре ты используешь переменные, циклы, условия, массивы, функции и процедуры. Это как тренажёрный зал для программиста — прокачиваешь всё сразу.

Креативное мышление. Ты не просто решаешь задачу — ты проектируешь опыт. Какой будет игра? Как реагировать на ввод? Что делать при ошибке? Это учит думать как разработчик, а не как исполнитель.

Отладка в действии. Когда твоя игра ведёт себя странно — тролль не получает урон или поле не рисуется — ты учишься искать и исправлять баги. Этот навык бесценен в реальной разработке.

🏁Итоги: Pascal как тренажёр мозга

Pascal — это не музейный экспонат. Это язык, который заставляет тебя думать. Строгая типизация не даёт халтурить, обязательные begin...end приучают к структуре, а отсутствие «магических» библиотек заставляет понимать каждую строку кода.

Мы написали три игры — от простой угадайки до полноценного текстового квеста. И каждая из них — это не просто программа, а набор паттернов и приёмов, которые работают в любом языке программирования.

Вот что мы освоили на практике:

Циклы — repeat...until и while для игрового цикла. Условия — if-then-else и case для обработки выбора. Массивы — двумерный массив для игрового поля. Процедуры и функции — для организации кода. Конечные автоматы — архитектурный паттерн для сложных сценариев. Валидация ввода — защита от некорректных данных.

Всё это — без единого движка, библиотеки или фреймворка. Чистая логика и работающий мозг.

🐍 Pascal жив. И если ты хочешь по-настоящему понять, как работает программирование — начни с него. А потом переноси эти знания куда хочешь: в Python, JavaScript, C++ или любой другой язык. Фундамент останется с тобой.

✨ А если ты не хочешь учиться в одиночку — у нас есть Кодик!

Кодик — это не просто приложение, а твой личный наставник в мире программирования. Он объясняет всё простыми словами, помогает закреплять знания на практике и даёт крутые ачивки за успехи 🏅

А ещё у нас тёплое и дружеское комьюнити в telegram, где каждый может задать вопрос и получить ответ — без осуждения и лишней теории. Мы вместе решаем задачи, разбираем ошибки и поддерживаем друг друга на пути к цели.

С Кодиком учиться программированию действительно приятно и интересно 💙

🎯Хватит откладывать

Понравилась статья?
Пора применять на практике!

В Кодик ты не просто читаешь — ты сразу пишешь код. Теория + практика = реальный скилл.

Мгновенная практика
🧠AI объяснит код
🏆Сертификат

Без регистрации • Без карты