program VRD;

uses CRT, sysutils, Math;

//Классы
type
  SpecsClass = class
    strength, health: integer;
  end;
  PlayerClass = class(SpecsClass)
    damage, armor, maxHealth: integer;
  end;
  EquipmentClass = class(SpecsClass)
    equipLevel: integer;
  end;

label m, m2;

var
  //Игрок
  player: PlayerClass;
  dragon, goblin, wolf, rat, bat, bear, skeleton: SpecsClass;
  //Показатели и монеты
  coins, weaponDamage, weaponEquipLevel, armorEquipLevel, helmetEquipLevel, chestArmor, helmetArmor, playerLevel, playerEXP, playerMaxEXP: integer;
  //Оружие и броня
  dagger, shortSword, longSword, leatherArmor, leatherHelmet, chainArmor, chainHelmet, heavyArmor, heavyHelmet: EquipmentClass;
  //Направления
  choise, left, up, right: string;
  dragonDefeated: boolean;
const
    //Массив всего
    withoutDragon: array[0..7] of string = ('Гоблин','Волк','Крыса','Летучая мышь','Медведь','Скелет','Ядовитая ловушка','Шипастая ловушка');
    withDragon: array[0..8] of string = ('Дракон','Гоблин','Волк','Крыса','Летучая мышь','Медведь','Скелет','Ядовитая ловушка','Шипастая ловушка');
    itemsAndEasyEnemies: array[0..10] of string = ('Волк','Крыса','Летучая мышь','Монеты','Кинжал','Кожаная броня','Кожаный шлем','Ядовитая ловушка','Шипастая ловушка','Костёр', 'Гоблин-торговец');

procedure newPlayer();
begin
  playerLevel := 1;
  playerEXP := 0;
  playerMaxEXP := 6;
  weaponDamage := 0;
  weaponEquipLevel := 0;
  armorEquipLevel := 0;
  helmetEquipLevel := 0;
  chestArmor := 0;
  helmetArmor := 0;
  player := PlayerClass.Create;
  player.strength := 2;
  player.health := 10;
  player.maxhealth := 10;
  coins := 0;
  dragonDefeated := false;
end;

procedure loadGame();
begin
  //Враги
  dragon := SpecsClass.Create;
  dragon.strength := 20;
  dragon.health := 50;

  goblin := SpecsClass.Create;
  goblin.strength := 4;
  goblin.health := 8;

  wolf := SpecsClass.Create;
  wolf.strength := 3;
  wolf.health := 4;

  rat := SpecsClass.Create;
  rat.strength := 2;
  rat.health := 3;

  bat := SpecsClass.Create;
  bat.strength := 2;
  bat.health := 4;

  bear := SpecsClass.Create;
  bear.strength := 10;
  bear.health := 10;

  skeleton := SpecsClass.Create;
  skeleton.strength := 5;
  skeleton.health := 10;

  //Оружие и броня
  dagger := EquipmentClass.Create;
  dagger.equipLevel := 1;
  dagger.strength := 2;

  shortSword := EquipmentClass.Create;
  shortSword.equipLevel := 2;
  shortSword.strength := 4;

  longSword := EquipmentClass.Create;
  longSword.equipLevel := 3;
  longSword.strength := 6;

  leatherArmor := EquipmentClass.Create;
  leatherArmor.equipLevel := 1;
  leatherArmor.strength := 1;

  chainArmor := EquipmentClass.Create;
  chainArmor.equipLevel := 2;
  chainArmor.strength := 4;

  heavyArmor := EquipmentClass.Create;
  heavyArmor.equipLevel := 3;
  heavyArmor.strength := 6;

  leatherHelmet := EquipmentClass.Create;
  leatherHelmet.equipLevel := 1;
  leatherHelmet.strength := 1;

  chainHelmet := EquipmentClass.Create;
  chainHelmet.equipLevel := 2;
  chainHelmet.strength := 2;

  heavyHelmet := EquipmentClass.Create;
  heavyHelmet.equipLevel := 3;
  heavyHelmet.strength := 4;
end;

procedure directions();
begin
  left := withoutDragon[random(8)];
  writeln('Слева ' + left);
  up := withDragon[random(9)];
  writeln('Впереди ' + up);
  right := itemsAndEasyEnemies[random(11)];
  writeln('Справа ' + right + LineEnding);
end;

function ConvertToCoins(YourItemLVL, ItemLVL: integer): boolean;
begin
  if YourItemLVL >= ItemLVL then
    begin
      case(ItemLVL) of
        1: coins := coins + 25;
        2, 3: writeln('Этот или более качественный предмет у вас уже есть.');
      end;
      ConvertToCoins := True;
    end
  else
      ConvertToCoins := False;
end;

procedure battle(enemyStrength, enemyHealth: integer);
var hit, armorInBattle: integer;
begin
  ClrScr;
  repeat
    writeln('Ваше здоровье ' + IntToStr(player.health) + '/' + IntToStr(player.maxHealth) + ' Броня ' + IntToStr(player.armor));
    writeln(choise + ': ' + ' Здоровье ' + IntToStr(enemyHealth) + ' Сила ' + IntToStr(enemyStrength) + LineEnding);
    hit := random(enemyStrength + 1);
    armorInBattle := RandomRange((player.armor div 2), player.armor + 1);
    if armorInBattle <= hit then
      begin
        hit := hit - armorInBattle;
        player.health := player.health - hit;
        writeln(choise + ' наносит ' + IntToStr(hit) + ' урона.' + LineEnding + 'Броня отразила ' + IntToStr(armorInBattle) + ' урона.');
      end
    else writeln('Враг ' + choise + ' не пробил броню.');
    hit := random(player.damage + 1);
    enemyHealth := enemyHealth - hit;
    writeln('Вы наносите ' + IntToStr(hit) + ' урона.');
  until (player.health <= 0) or (enemyHealth <= 0);
  if enemyHealth <= 0 then
    begin
      writeln('Враг ' + choise + ' повержен!' + LineEnding);
      if choise = 'Дракон' then
        begin
          dragonDefeated := true;
          writeln('Вы не только выжили, но и победили дракона!!!' + LineEnding + 'Вас посвятили в рыцари!' + LineEnding + 'Нажмите ENTER чтобы уйти. Ваша миссия здесь выполнена!');
          readln();
          Exit;
        end;
      //Прокачка
      case(choise) of
        'Гоблин': playerEXP := playerEXP + 4;
        'Волк': playerEXP := playerEXP + 3;
        'Крыса': playerEXP := playerEXP + 1;
        'Летучая мышь': playerEXP := playerEXP + 2;
        'Медведь': playerEXP := playerEXP + 6;
        'Скелет': playerEXP := playerEXP + 5;
      end;
      if playerEXP >= playerMaxEXP then
        begin
          player.maxHealth := player.maxHealth + 2;
          player.strength := player.strength + 1;
          player.health := player.maxHealth;
          playerLevel := playerLevel +1;
          playerEXP := 0;
          playerMaxEXP := playerMaxEXP + 2;
          writeln('Вы достигли уровня ' + IntToStr(playerLevel));
        end;
    end;
  writeln('Нажмите ENTER чтобы продолжить.');
  readln();
end;

procedure trading();
begin
    ClrScr;
    writeln('Привет, здоровяк! У меня кое-что найдется для тебя, если тебе есть чем заплатить.' + LineEnding + '1) Зелье здоровья (восстанавливает 5 очков здоровья) - 50 монет' + LineEnding + '2) Зелье силы (добавляет 1 очко силы) - 75 монет' + LineEnding + '3) Кольчуга (даёт 4 очка брони) - 100 монет' + LineEnding + '4) Кольчужный шлем (даёт 2 очка брони) - 75 монет' + LineEnding + '5) Короткий меч (даёт 4 очка силы) - 100 монет' + LineEnding +'6) Тяжелая броня (даёт 6 очков брони) - 200 монет' + LineEnding + '7) Тяжелый шлем (даёт 4 очка брони) - 150 монет' + LineEnding + '8) Длинный меч (даёт 6 очков силы) - 200 монет' + LineEnding + 'Q) Отойти от прилавка' + LineEnding);
    repeat
    writeln('Монеты: ' + IntToStr(coins));
    readln(choise);
    case(choise) of
      '1': if coins >= 50 then
              begin
                coins := coins - 50;
                if player.health < (player.maxHealth - 5) then
                        begin
                          player.health := player.health + 5;
                          writeln('Вы выпили зелье здоровья');
                        end
                else if player.health = player.maxHealth then writeln('Вы полностью здоровы.')
                else
                    begin
                      player.health := player.maxHealth;
                      writeln('Вы выпили зелье здоровья');
                    end;
              end
              else
                   writeln('Не хватает монет! Выбери другой товар... или иди зарабатывай монеты!!!');

      '2': if coins >= 75 then
              begin
                coins := coins - 75;
                player.strength := player.strength + 1;
                writeln('Вы выпили зелье силы');
              end
           else
               writeln('Не хватает монет! Выбери другой товар... или иди зарабатывай монеты!!!');

      '3': if coins >= 100 then
              begin
                   if ConvertToCoins(armorEquipLevel, chainArmor.equipLevel) = False then
                           begin
                             chestArmor := chainArmor.strength;
                             armorEquipLevel := chainArmor.equipLevel;
                             coins := coins - 100;
                             writeln('Вы надели кольчугу');
                           end;
              end
              else
                  writeln('Не хватает монет! Выбери другой товар... или иди зарабатывай монеты!!!');

      '4': if coins >= 75 then
              begin
                   if ConvertToCoins(helmetEquipLevel, chainHelmet.equipLevel) = False then
                           begin
                             helmetArmor := chainHelmet.strength;
                             helmetEquipLevel := chainHelmet.equipLevel;
                             coins := coins - 75;
                             writeln('Вы надели кольчужный шлем');
                           end;
              end
              else
                  writeln('Не хватает монет! Выбери другой товар... или иди зарабатывай монеты!!!');

      '5': if coins >= 100 then
              begin
                   if ConvertToCoins(weaponEquipLevel, shortSword.equipLevel) = False then
                           begin
                             weaponDamage := shortSword.strength;
                             weaponEquipLevel := shortSword.equipLevel;
                             coins := coins - 100;
                             writeln('Вы взяли в руки короткий меч');
                           end;
              end
              else
                  writeln('Не хватает монет! Выбери другой товар... или иди зарабатывай монеты!!!');



      '6': if coins >= 200 then
              begin
                   if ConvertToCoins(armorEquipLevel, heavyArmor.equipLevel) = False then
                           begin
                             chestArmor := heavyArmor.strength;
                             armorEquipLevel := heavyArmor.equipLevel;
                             coins := coins - 200;
                             writeln('Вы надели тяжелую броню');
                           end;
              end
              else
                  writeln('Не хватает монет! Выбери другой товар... или иди зарабатывай монеты!!!');

      '7': if coins >= 150 then
              begin
                   if ConvertToCoins(helmetEquipLevel, heavyHelmet.equipLevel) = False then
                           begin
                             helmetArmor := heavyHelmet.strength;
                             helmetEquipLevel := heavyHelmet.equipLevel;
                             coins := coins - 150;
                             writeln('Вы надели тяжелый шлем');
                           end;
              end
              else
                  writeln('Не хватает монет! Выбери другой товар... или иди зарабатывай монеты!!!');

      '8': if coins >= 200 then
              begin
                   if ConvertToCoins(weaponEquipLevel, longSword.equipLevel) = False then
                           begin
                             weaponDamage := longSword.strength;
                             weaponEquipLevel := longSword.equipLevel;
                             coins := coins - 200;
                             writeln('Вы взяли в руки длинный меч');
                           end;
              end
              else
                  writeln('Не хватает монет! Выбери другой товар... или иди зарабатывай монеты!!!');

    end;
  until (choise = 'Q') or (choise = 'q');
end;

procedure action();
begin
  case(choise) of
    'Дракон': battle(dragon.strength, dragon.health);
    'Гоблин': battle(goblin.strength, goblin.health);
    'Волк': battle(wolf.strength, wolf.health);
    'Крыса': battle(rat.strength, rat.health);
    'Летучая мышь': battle(bat.strength, bat.health);
    'Медведь': battle(bear.strength, bear.health);
    'Скелет': battle(skeleton.strength, skeleton.health);
    'Монеты': coins := coins + 50;
    'Кинжал': if ConvertToCoins(weaponEquipLevel, dagger.equipLevel) = False then
      begin
        weaponDamage := dagger.strength;
        weaponEquipLevel := dagger.equipLevel;
      end;
    'Кожаная броня': if ConvertToCoins(armorEquipLevel, leatherArmor.equipLevel) = False then
      begin
        chestArmor := leatherArmor.strength;
        armorEquipLevel := leatherArmor.equipLevel;
      end;
    'Кожаный шлем': if ConvertToCoins(helmetEquipLevel, leatherHelmet.equipLevel) = False then
      begin
        helmetArmor := leatherHelmet.strength;
        helmetEquipLevel := leatherHelmet.equipLevel;
      end;
    'Ядовитая ловушка': if player.strength > 0 then
      player.strength := player.strength - 1;
    'Шипастая ловушка': if player.health > 0 then
      player.health := player.health - 2;
    'Костёр': player.health := player.maxHealth;
    'Гоблин-торговец': trading();
  end;
end;



begin
  randomize;
  m:
  ClrScr;
  writeln(LineEnding + 'xXxXxXxXxXxXxXxxxXxx' + LineEnding + 'XxXxx ________ xxXxx' + LineEnding + 'xXx //        \\ xXx' + LineEnding + 'Xxx ||        || Xxx' + LineEnding + 'xXX ||  ____  || xXx' + LineEnding + 'xXx || /    \ || xXx' + LineEnding + 'XXx ||/      \|| XxX' + LineEnding + '^^^^^^^^^^^^^^^^^^^^');
  writeln(LineEnding + 'ВЕСЬМА СЛУЧАЙНОЕ ПОДЗЕМЕЛЬЕ' + LineEnding + 'N) Новая игра' + LineEnding + 'Q) Выйти из игры (данную команду можно использовать в любой момент игры, кроме боя)' + LineEnding);
  readln(choise);
      case(choise) of
        'N', 'n': newPlayer();
        'Q', 'q': Exit;
        else
          writeln('Выберите из списка выше');
          GOTO m;
      end;

  loadGame();
  writeln(LineEnding +'Вы живёте на земле, которую заполонили злые драконы.'+ LineEnding +'Большие и малые особи одинаково агрессивны.'+ LineEnding +'Большие живут на вершинах гор, а малые могут прятаться в подземельях...'+ LineEnding +'Вы новичок, который мечтает стать рыцарем!'+ LineEnding +'Чтобы пройти посвящение, вам надо убить хотя бы одного малого дракона...'+ LineEnding +'Или умереть, пытаясь.'+ LineEnding + 'Вы спускаетесь в подземелье. Кругом темно и идти придётся почти наугад.' + LineEnding + 'Нажмите ENTER чтобы продолжить');
  readln();
  ClrScr;
  //Основной цикл игры
  repeat
    if player.health <= 0 then
      begin
        writeln('      _______' + LineEnding + '    //VVVVVVV\\' + LineEnding + '  _//--     --\\_' + LineEnding + ' / /( x ) ( x )\ \' + LineEnding + '( (     /_\     ) )' + LineEnding + ' \_\   _____   /_/' + LineEnding + '    \ /WWWWW\ /' + LineEnding + '     \ (___) /' + LineEnding + '      \MMMMM/' + LineEnding);
        writeln('ВЫ УМЕРЛИ!' + LineEnding + 'Нажмите ENTER чтобы начать заново.');
        readln();
        GOTO m;
      end;
    player.damage := player.strength + weaponDamage;
    player.armor := chestArmor + helmetArmor;
    writeln('Здоровье: ' + IntToStr(player.health) + '/' + IntToStr(player.maxHealth) + ' Броня: ' + IntToStr(player.armor) + ' (нагрудник - ' + IntToStr(chestArmor) + ', шлем - ' + IntToStr(helmetArmor) + ')' + ' Наносимый урон: ' + IntToStr(player.damage) + ' (сила - ' + IntToStr(player.strength) + ', оружие - ' + IntToStr(weaponDamage) + ')' + LineEnding + 'Монеты: ' + IntToStr(coins) + ' Уровень: ' + IntToStr(playerLevel) + ' Опыт: ' + IntToStr(playerEXP) + '/' + IntToStr(playerMaxEXP) + LineEnding);
    writeln('       W'  + LineEnding + '       ^' + LineEnding + 'A <--  |  --> D' + LineEnding + '      \|/' + LineEnding + '       |' + LineEnding);
    directions();
    writeln('A) Налево' + LineEnding + 'W) Вперед' + LineEnding + 'D) Направо' + LineEnding);
    m2:
    readln(choise);
    case(choise) of
      'A', 'a': choise := left;
      'W', 'w': choise := up;
      'D', 'd': choise := right;
      'Q', 'q': Exit;
      'G': begin
        weaponDamage := 100;
        chestArmor := 100;
      end
      else
        writeln('Выберите из списка выше');
        GOTO m2;
    end;
    action();
    ClrScr;
  until dragonDefeated = true;
end.

