ASCII текстовая RPG игра в C ++

== «Чемпион») {//Чемпионский раздел         cost = inte * (уровень);         cout <"[1] Раскачивающий удар [" <стоимость <"mana" "<епсИ;         cout <"[2] Тонкость плавления [" <стоимость <"mana" "<епсИ;         cout <"[3] Критический Bash [" <стоимость <"mana" "<епсИ;         cost = inte * (уровень + 1);         cout <"[4] Очистить [" <стоимость <"mana" "<епсИ;         cost = inte * (уровень);         cin> вход;         if (input == "1") {             способность = «раскалывание»;             if (мана> = стоимость) {                 mana = мана - стоимость;                 return {способность, мана};             } else {                 способность = "нет";                 return {способность, мана};             }         } else if (input == "2") {             способность = «плавление тяги»;             if (мана> = стоимость) {                 mana = мана - стоимость;                 return {способность, мана};             } else {                 способность = "нет";                 return {способность, мана};             }         } else if (input = "3") {             способность = "критический удар";             if (мана> = стоимость) {                 mana = мана - стоимость;                 return {способность, мана};             } else {                 способность = "нет";                 return {способность, мана};             }         } else if (input == "4") {             способность = "очищать";             if (мана> = стоимость) {                 cost = inte * (уровень + 1);                 mana = мана - стоимость;                 return {способность, мана};             } else {                 способность = "нет";                 return {способность, мана};             }         } else {             способность = "нет";             return {способность, мана};         }     } else if (pclass == "Некромант") {//Секция некромантов         cost = inte * (уровень);         cout <"[1] Shadow Strike [" <<стоимость <"mana" "<епсИ;         cout <"[2] Cripple [" <стоимость <"mana" "<епсИ;         cout <"[3] Мутилат [" <стоимость <"mana" "<епсИ;         cost = inte * (уровень + 2);         cout <"[4] Life Tap [" <<стоимость <"mana" "<епсИ;         cost = inte * (уровень);         cin> вход;         if (input == "1") {             способность = "теневой удар";             if (мана> = стоимость) {                 mana = мана - стоимость;                 return {способность, мана};             } else {                 способность = "нет";                 return {способность, мана};             }         } else if (input == "2") {             способность = "калека";             if (мана> = стоимость) {                 mana = мана - стоимость;                 return {способность, мана};             } else {                 способность = "нет";                 return {способность, мана};             }         } else if (input = "3") {             способность = "калечить";             if (мана> = стоимость) {                 mana = мана - стоимость;                 return {способность, мана};             } else {                 способность = "нет";                 return {способность, мана};             }         } else if (input == "4") {             способность = «срок службы»;             if (мана> = стоимость) {                 cost = inte * (уровень + 2);                 mana = мана - стоимость;                 return {способность, мана};             } else {                 способность = "нет";                 return {способность, мана};             }         } else {             способность = "нет";             return {способность, мана};         }     } else if (pclass == "Assassin") {//Assassin Section         cost = inte * (уровень);         cout <"[1] Back Stab [" <стоимость <"mana" "<епсИ;         cout <"[2] Головной убор [" <стоимость <"mana" "<епсИ;         cout <"[3] Яд [" <стоимость <"mana" "<епсИ;         cost = inte * 10;         cout <"[4] Убийство [" <стоимость <"mana" "<епсИ;         cost = inte * (уровень);         cin> вход;         if (input == "1") {             способность = "назад stab";             if (мана> = стоимость) {                 mana = мана - стоимость;                 return {способность, мана};             } else {                 способность = "нет";                 return {способность, мана};             }         } else if (input == "2") {             способность = «хедтрек»;             if (мана> = стоимость) {                 mana = мана - стоимость;                 return {способность, мана};             } else {                 способность = "нет";                 return {способность, мана};             }         } else if (input = "3") {             способность = "яд";             if (мана> = стоимость) {                 mana = мана - стоимость;                 return {способность, мана};             } else {                 способность = "нет";                 return {способность, мана};}         } else if (input == "4") {             способность = "убивать";             if (мана> = стоимость) {                 cost = inte * 10;                 mana = мана - стоимость;                 return {способность, мана};             } else {                 способность = "нет";                 return {способность, мана};             }         } else {             способность = "нет";             return {способность, мана};         }     } else if (pclass == "Cleric") {//Cleric Section         cost = inte * (уровень);         cout <"[1] Smite [" <стоимость <"mana" "<епсИ;         cout <"[2] Enflame [" <стоимость <"mana" "<епсИ;         cout <"[3] Искупление [" <стоимость <"mana" "<епсИ;         cout <"[4] Вспышка исцеляет [" <<стоимость <"mana" "<епсИ;         cin> вход;         if (input == "1") {             способность = "поразить";             if (мана> = стоимость) {                 mana = мана - стоимость;                 return {способность, мана};             } else {                 способность = "нет";                 return {способность, мана};             }         } else if (input == "2") {             способность = "enflame";             if (мана> = стоимость) {                 mana = мана - стоимость;                 return {способность, мана};             } else {                 способность = "нет";                 return {способность, мана};             }         } else if (input = "3") {             способность = "искупление";             if (мана> = стоимость) {                 mana = мана - стоимость;                 return {способность, мана};             } else {                 способность = "нет";                 return {способность, мана};             }         } else if (input == "4") {             способность = "исцеление вспышкой";             if (мана> = стоимость) {                 mana = мана - стоимость;                 return {способность, мана};             } else {                 способность = "нет";                 return {способность, мана};             }         } else {             способность = "нет";             return {способность, мана};         }     } else {         способность = "нет";         return {способность, мана};     }     } int main () {     srand ((без знака) Время (0));     //Строки     строковый код; //Код сохранения игры     имя строки; //Имя игрока     string etype; //Тип врага (паук, гигант)     string pclass; //Класс игрока     строковое действие; //Способность игрока /действие     //Подземелья     Строковый статус = "арена"; //Статус, если в Dungeon или просто Arena     int ckills; //Текущее количество убийств в Dungeon     int rkills; //Требуемое количество убийств для создания Подземелья     //Броня /Оружие     int bhp = 0; //Бонус hp     double bphp = 0; //Превосходность бонуса hp     double goldb = 0; //Бонус Золото     int slimychestplate = 0; //Slimy Chestplate (TRUE или FALSE)     int slimyhelmet = 0; //Slimy Helmet (TRUE или FALSE)     int oozinglegplates = 0; //Изношенные ножные латы     int oozingboots = 0; //Озирая сапоги     string head = "Open"; //Что на голове     string chest = "Open"; //Что на груди     string legs = "Open"; //Что на ногах     string feet = "Open"; //Что на ногах     //Переменные игрока     int piclass = 0;     int level = 1; //Уровень     int xp = 0; //Текущий XP     int rxp; //Награда XP     int xpb = 50; //Увеличивает каждый уровень, добавляет к max hp, чтобы увеличить его     int xpl = 25; //XP Требуется до следующего уровня     int stre = 5; //Прочность     int inte = 5; //Интеллект     int dext = 5; //Ловкость     int skill = 0; //Точки умения (используемые для увеличения силы, интеллекта, ловкости)     int dmg; //Наносить ущерб     int hp = stre * 20; //Текущий hp     int mhp = stre * 20; //Макс. Л.с.     int shp = stre * 20; //hp используется для установки вражеского hp     int mana = inte * 10; //Мана     int mmana = inte * 10; //Макс Мана     //Инвентарь /Магазин     int hpotion = 1; //Исцеляющие зелья     int price; //Цена товара (ов)     //Ресурсы     int gold = 25; //Золото     int rgold; //Награда Золотом     //Сохранение /загрузка строк     int x = 0;     int y = 0;     string sslimychestplate = std :: to_string (slimychestplate);     string sslimyhelmet = std :: to_string (slimyhelmet);     string soozinglegplates = std :: to_string (oozinglegplates);     string soozingboots = std :: to_string (oozingboots);     string spiclass = std :: to_string (piclass);     string slevel = std :: to_string (уровень);     string sxp = std :: to_string (xp);     string sxpb = std :: to_string (xpb);     string sxpl = std :: to_string (xpl);     string sstre = std :: to_string (stre);     string sinte = std :: to_string (inte);     string sdext = std :: to_string (dext);     string shpotion = std :: to_string (hpotion);     string sgold = std :: to_string (золото);     string sskill = std :: to_string (умение);     //Квестхолл     int quest = 0; //Квест     int questr = 0; //Требования к квесту (убиты 6 кабанов)     int questc = 0; //Текущее положение по требованиям (3/6 кабанов убито)     int questreward = 0;//Награда квеста     string questmob; //Враг, который должен быть убит для завершения квеста     строка questdisplay; //Отображает квест     int qxpr; //Quest xp вознаграждение     int qgoldr; //Золотая награда Задания     //Переменные монстров     int elevel; //Уровень врага     int ehp; //Враг hp     int mehp; //Макс Враг hp     int edmg; //Enemy dmg     струнная безопасность; //Враждебность     //Другие переменные     int random; //Случайное целое число # 1     int random2; //Random Integer # 2     //Оружие     //Входы     ввод строки; //Стандартный ввод     //Настроить     neworload:     Чисто();     cout <«Привет, пожалуйста, выберите вариант» <<епсИ;     cout <«1- Новая игра» <епсИ;     cout <«2- Загружаемая игра» <епсИ;     cin> вход;     if (input == "1") {         goto setup;     } else if (input == "2") {         goto loadgame;     } else {         goto neworload;     }     настроить:     Чисто();     cout <«Привет, как тебя зовут?» & Л; & л; епсИ;     cin> вход;     name = input;     cout <«Ах, это» <вход <"[y /n]" <<епсИ;     cin> вход;     if (input == "n") {         Чисто();         goto setup;     }     //Настройка класса     csetup:     cout <епсИ;     cout <«Выберите свой класс» <епсИ;     cout <"==================" <<епсИ;     cout <«[1] Чемпион« <епсИ;     cout <«[2] Некромант» <епсИ;     cout <"[3] Assassin" <епсИ;     cout <"[4] Cleric" <епсИ;     cin> вход;     if (input == "1") {         pclass = "Чемпион";         piclass = 1;     } else if (input == "2") {         pclass = "Некромант";         piclass = 2;     } else if (input = "3") {         pclass = "Assassin";         piclass = 3;     } else if (input == "4") {         pclass = "Клирик";         piclass = 4;     }     goto menue;     //Главное меню     НАЖМИТЕ:     Чисто();     if (pclass == "Assassin") {         goldb = 1,25;     } else {         goldb = 1;     }     cout <Р"( ___ ___ _____ _ _ _ _ | \ /|| ___ | \ | | | | | | , , || | __ | \ | | | | | | | \ /| || __ || , `| | | | | | | || | ___ | | \ | | _ | | \ _ | | _ /\ ____ /\ _ | \ _ /\ ___ /     ) "<<endl;     cout <pclass <"" <имя <епсИ;     cout <«[1]« Встреча путешественника »<епсИ;     cout <"[2] Инвентарь" <епсИ;     cout <"[3] Отдых (возвращает вас к полному здоровью /мане)" <<епсИ;     cout <"[4] Назначить точки умения [" <<умение <"доступно" "<епсИ;     cout <"[5] Магазин" <епсИ;     cout <"[6] Questhall" <епсИ;     cout <«[7] Подземелья» <епсИ;     cout <«[98] Сохранить игру» <епсИ;     cout <"[99] Выход" <епсИ;     cin> вход;     if (input == "1") {         goto sarena;     } else if (input == "99") {         отпуск;     } else if (input == "2") {         goto инвентарь;     } else if (input = "3") {         mhp = stre * 20;         mmana = inte * 10;         hp = mhp;         hp = hp * (bphp + 1);         hp = hp + bhp;         mana = mmana;         goto menue;     } else if (input == "4") {         goto askill;     } else if (input == "5") {         идти в магазин;     } else if (input == "6") {         goto questhall;     } else if (input == "7") {         goto dungeonmenue;     } else if (input == "98") {         goto savegame;     }     goto menue;     //Настройка Enemys     Sarena:     mmana = inte * 10;     shp = stre * 20;     mhp = stre * 20;     random = rand ()% 5 + 1;     переключатель (случайный) {         Дело 1:             etype = "Lion";             random2 = rand ()% 2 + 1;             eability = "gnaw";             if (random2 == 1) {                 ehp = shp + rand ()% (уровень * 5);             } else {                 ehp = shp - rand ()% (уровень * 5);             }             mehp = ehp;         ломать;         случай 2:             etype = «Кабан»;             random2 = rand ()% 2 + 1;             eability = "goar";             if (random2 == 1) {                 ehp = shp + rand ()% (уровень * 3);             } else {                 ehp = shp - rand ()% (уровень * 3);             }             mehp = ehp;         ломать;         случай 3:             etype = «Паук»;             random2 = rand ()% 2 + 1;             eability = "webspin";             elevel = rand ()% (уровень + 3) +1;             if (random2 == 1) {                 ehp = shp + rand ()% (уровень * 2);             } else {                 ehp = shp - rand ()% (уровень * 2);             }             mehp = ehp;         ломать;         случай 4:             etype = "Wolf";             random2 = rand ()% 2 + 1;             eability = «рычание»;             elevel = rand ()% (уровень + 3) +1;             if (random2 == 1) {                 ehp = shp + rand ()% (уровень * 4);             } else {                 ehp = shp - rand ()% (уровень * 4);             }             mehp =э.л.с.;         ломать;         случай 5:             etype = "Elephant";             random2 = rand ()% 2 + 1;             eability = "топать";             if (random2 == 1) {                 ehp = shp + rand ()% (уровень * 6);             } else {                 ehp = shp - rand ()% (уровень * 3);             }             mehp = ehp;         ломать;     }     elevel = rand ()% (уровень + 3) +1;     if ((elevel <(level-3)) || (elevel> (уровень + 3))) {         elevel = level;     }     goto aarena;     //Арена Главная     aarena:     Чисто();     рисовать (ETYPE);     cout <"[" <etype <"" <elevel <"]>> <<ehp <"/" <mehp <епсИ;     cout <"[" <имя <"" <уровень <"]>> <<hp <"/" <mhp <епсИ;     cout <"-Мана->> <<мана <"/" <mmana <епсИ;     cout <«[1] Атака« <епсИ;     cout <«[2] Способность« <епсИ;     cout <"[3] Инвентарь" <епсИ;     cout <«[99] Бег» <епсИ;     cin> вход;     if (input == "1") {         dmg = (stre + inte) + rand ()% (dext * 2);         ehp = ehp - dmg;         //Если враг ehp <0 затем         если (ehp <= 0) {             Чисто();             cout <«[*] Вы убили« <etype <епсИ;             cout <«Тип [1] для продолжения« <епсИ;             cin> вход;             goto rarena;         }         random2 = rand ()% 2 + 1;         edmg = dmg;         //Настройка урона врага         if (random2 == 1) {                 edmg = edmg + rand ()% (dext * 2);             } else {                 edmg = edmg - rand ()% (dext * 2);             }         hp = hp - edmg;         //Если игрок hp <0 затем         если (hp <= 0) {             Чисто();             cout <«[*] Вы умерли» <епсИ;             cout <«Тип [1] для продолжения« <епсИ;             cin> вход;             if (status! = "arena") {                 статус = "арена";             }             goto menue;         }         goto aarena;     } else if (input == "99") {         goto menue;     } else if (input == "2") {         goto darena;     } else if (input = "3") {         goto iarena;     } else {         goto aarena;     }     //Использование элементов из инвентаря     iarena:     Чисто();     cout <«Инвентарь» <епсИ;     cout <"[1] Зелье здоровья," <hpotion <"(Исцеляет вас до максимального состояния здоровья)" <епсИ;     cout <"[99] Выход" <епсИ;     cin> вход;     if (input == "1") {         если (hpotion> 0) {             hpotion = hpotion - 1;             hp = mhp;         }     } else if (input == "99") {         goto aarena;     }     goto iarena;     //Выбор заклинаний и нанесение урона     Darena:     Чисто();     tie (action, mana) = getability (pclass, mana, inte, level);     //Заклинания чемпиона     if (действие == "расщепление удара") {         dmg = (stre + inte + dext) + rand ()% (dext * 2);     } else if (действие == "плавление тяги") {         dmg = (stre + inte + dext) + rand ()% (stre * 2);     } else if (action == "critical bash") {         dmg = (stre + inte + dext) + rand ()% (inte * 2);     } else if (действие == "очистить") {         hp = hp + inte * (уровень) + (rand ()% inte);         если (hp> mhp) {             hp = mhp;         }         goto aarena;     } else if (action == "none") {         goto aarena;     } else if (action == "shadow strike") {         dmg = (stre + inte + dext) + rand ()% (dext * 2);     } else if (action == "cripple") {         dmg = (stre + inte + dext) + rand ()% (stre * 2);     } else if (action == "mutilate") {         dmg = (stre + inte + dext) + rand ()% (inte * 2);     } else if (action == "life tap") {         dmg = (stre + inte) + rand ()% (inte);         hp = hp + dmg;         если (hp> mhp) {             hp = mhp;         }         ehp = ehp - dmg;         //Если враг ehp <0 затем         если (ehp <= 0) {             Чисто();             cout <«[*] Вы убили« <etype <епсИ;             cout <«Тип [1] для продолжения« <епсИ;             cin> вход;             goto rarena;         }         goto aarena;     } else if (action == "back stab") {         dmg = (stre + inte + dext) + rand ()% (dext * 2);     } else if (action == "headcrack") {         dmg = (stre + inte + dext) + rand ()% (stre * 2);     } else if (action == "poison") {         dmg = (stre + inte + dext) + rand ()% (inte * 2);     } else if (action == "assassinate") {         dmg = (stre + inte + dext) + rand ()% ((inte + stre) * 3);         ehp = ehp - dmg;         //Если враг ehp <0 затем         если (ehp <= 0) {             Чисто();             cout <«[*] Вы убили« <etype <епсИ;             cout <«Тип [1] для продолжения« <епсИ;             cin> вход;             goto rarena;         }         goto aarena;     } else if(action == "smite") {         dmg = (stre + inte + dext) + rand ()% (dext);     } else if (action == "enflame") {         dmg = (stre + inte + dext) + rand ()% (stre);     } else if (действие == "искупление") {         dmg = (stre + inte + dext) + rand ()% (inte);     } else if (action == "flash heal") {         hp = hp + ((уровень стрелки *) + (rand ()% (inte * 2)));         если (hp> mhp) {             hp = mhp;         }         goto aarena;     }     //Выполнение урона (Враг)     ehp = ehp - dmg;     //Если враг ehp <0 затем     если (ehp <= 0) {         Чисто();         cout <«[*] Вы убили« <etype <епсИ;         cout <«Тип [1] для продолжения« <епсИ;         cin> вход;         goto rarena;     }     random2 = rand ()% 2 + 1;     dmg = (stre + inte) + rand ()% (dext * 2);     edmg = dmg;     //Настройка урона врага     if (random2 == 1) {         edmg = edmg + rand ()% (dext * 2);     } else {         edmg = edmg - rand ()% (dext * 2);     }     hp = hp - edmg;     //Если игрок hp <0 затем     если (hp <= 0) {         Чисто();         cout <«[*] Вы умерли» <епсИ;         cout <«Тип [1] для продолжения« <епсИ;         cin> вход;         if (status! = "arena") {             статус = "арена";         }         goto menue;     }     goto aarena;     //Здесь вы получаете награды за арены     rarena:     Чисто();     rxp = rand ()% (уровень * 2) +5;     rgold = rand ()% (уровень * 5);     rgold = rgold * goldb;     cout <Р"( ************************************************** *****************************           | | | |  _________ | ________________ = "" _;. = .______________ | _____________________ | _______ | | , - "_, =" "` "=. | | | ___________________ | __ "= ._ o`" -._ `" = .______________ | ___________________           | `" = ._ o` "= ._ _`" = ._ |  _________ | _____________________: = ._ o "= ._." _.- = "'" =. __________________ | _______ | | __.-- ",;" = ._ o. ", -" "" -._ ". | | ___________________ | _._ ",.` `` `,` "-._" -._ ". «__ | ___________________           | | o` "= ._`, "` `; . ".," -._ "-._;;; |  _________ | ___________ | ; `-.o`" = ._;. " `` `." \ `." -._ /_______________ | _______ | | | О; `` -.o` "= ._` `` `", __.-- o; | | ___________________ | _ | ; (#) `-.o` "= .` _.--" _ o.-; ; ___ | ___________________ ____ /______ /______ /___ | o;. "" ".o | o _.--"; o; ____ /______ /______ /____ /______/______/______/_"=._o--._; |;; /______ /______ /______ /_ ____ /______ /______ /______ /__ "= ._ o --._; o | o; _._; o; ____ /______ /______ /____ /______/______/______/______/____"=._o._; |; _.-- "o .--" _ /______ /______ /______ /_ ____ /______ /______ /______ /______ /_____ "= о |. О _.--" "___ /______ /______ /______ /____ /______ /______ /______ /______ /______ /______ /______ /______ /______ /______ /______ /_ ************************************************** *****************************     ) "<endl; //Этот сундук выглядит потрясающе     if (status == "oozeworks") {         goto oozeworksr;     } else {         goto rrarena;     }     rrarena:     cout <«Вы получили» <rxp <"xp" <епсИ;     cout <«Вы получили» <rgold <«золото» <епсИ;     xp = xp + rxp;     золото = золото + rgold;     если (xp> = xpl) {         level = level + 1;         xpl = xpl + xpb;         xpb = xpb + 50;         умение = умение + 5;         cout <«Вы выровнены до уровня» <уровень <епсИ;     }     cout <«Введите [1], чтобы продолжить меню« <епсИ;     if (etype == questmob) {         questc = questc + 1;     }     cin> вход;     goto menue;     //Инвентаризация     инвентарь:     Чисто();     cout <Р"(        ___        ) _ (_        | | [_]      .-'-'-. _ .- '. -.     /- :: _..- \ _ [_] _ /:; /_.- '\     ) _ _ (/_ _ \ [-] |: ._ .- |     |; :: | ) _``` _ (.-'-'-. (-) |: ._ |     |; :: | | ;: | : -...-:.-'-'-. |: ._ |     |; :: | | ;: | | ;: | | -...- | |: ._ |     |; :: -.._ | |;: .._ | |;: .._ | |;: .._ | |: ._ |     `-.._..- '` -...-' `-...- '` -...-' `-.____.- '     ) "<<endl;     levelalert:     если (xp> = xpl) {         level = level + 1;         xpl = xpl + xpb;         xpb = xpb + 50;         умение = умение + 5;         goto levelalert;     } else {         goto inventory2;     }     inventory2:     cout <"[Уровень]>> <<уровень <епсИ;     cout <"[XP]>> <<xp <"/" <xpl <епсИ;     cout <"[Золото]>>>>& Л; & л; золото <епсИ;     cout <"[Целебные зелье]>> <<hpotion <епсИ;     cout <"================================ епсИ;     cout <«Голова-» <головка <епсИ;     cout <«Грудь-» <грудь <епсИ;     cout <«Ноги-» <ножки <епсИ;     cout <"Feet-" <футы <епсИ;     cout <"================================ епсИ;     cout <«1- Оружейная» <епсИ;     cout <«99-Выход» <епсИ;     cin> вход;     if (input == "99") {         goto menue;     } else if (input == "1") {         goto armory;     }     goto инвентарь;     оружейный:     Чисто();     cout <Р"(    , A {}   /\, | , .--.  | = | => /.--. \   \ /`| `| ==== |    `| | `::` |        | .-; '\ .... /`; _.- ^ -._       /\\ //| ... :: .. | `:` |       |: '\ | /'' '::' '| .:. |        \ /\; -, /\ :: | ..: .. |        | \ <`> & Гт ._ :: _ |. ': '|        | `` "` /^^ | ':' |     ) "<<endl;     cout <«1 - Слистная нагрудник>> [10% увеличения HP]»;     if (slimychestplate == 1) {         cout <">>> [Владеет]";         если (грудь == "slimychestplate") {             cout <>> <> <<> епсИ;         } else {             cout <епсИ;         }     } else {         cout <епсИ;     }     cout <«2-Slimy Helmet>> [5% увеличения HP]»;     if (slimyhelmet == 1) {         cout <">>> [Владеет]";         if (head == "slimyhelmet") {             cout <>> <> <<> епсИ;         } else {             cout <епсИ;         }     } else {         cout <епсИ;     }     cout <«3 Oozing Legplates>> [15% увеличения HP]»;     if (oozinglegplates == 1) {         cout <">>> [Владеет]";         if (legs == "oozinglegplates") {             cout <>> <> <<> епсИ;         } else {             cout <епсИ;         }     } else {         cout <епсИ;     }     cout <«4 Осаждение сапог>>> [10% увеличения HP]»;     if (oozingboots == 1) {         cout <">>> [Владеет]";         if (feet == "oozingboots") {             cout <>> <> <<> епсИ;         } else {             cout <епсИ;         }     } else {         cout <епсИ;     }     cout <«99-Назад» <епсИ;     cin> вход;     if (input == "99") {         goto armor2;     } else if (input == "1") {         если (грудь == "slimychestplate") {             сундук = «открытый»;             goto armory;         } else if (slimychestplate == 1) {             грудь = "slimychestplate";             goto armory;         } else {             goto armory;         }     } else if (input == "2") {         if (head == "slimyhelmet") {             head = "Open";             goto armory;         } else if (slimyhelmet == 1) {             head = "slimyhelmet";             goto armory;         } else {             goto armory;         }     } else if (input = "3") {         if (legs == "oozinglegplates") {             legs = "Open";             goto armory;         } else if (oozinglegplates == 1) {             legs = "oozinglegplates";             goto armory;         } else {             goto armory;         }     } else if (input == "4") {         if (feet == "oozingboots") {             feet = "Open";             goto armory;         } else if (oozingboots == 1) {             feet = "oozingboots";             goto armory;         } else {             goto armory;         }     }     armor2:     bhp = 0;     bphp = 0;     //Глава     if (head == "slimyhelmet") {         bphp = bphp + .10;     }     //Сундук     если (грудь == "slimychestplate") {         bphp = bphp + .05;     }     //Ноги     if (legs == "oozinglegplates") {         bphp = bphp + .15;     }     //Ноги     if (feet == "oozingboots") {         bphp = bphp + .10;     }     goto инвентарь;     навык:     Чисто();     cout <Р"(               .__ = \ __ .__ == __,             jf '~~ = \, _ = /~' `\,         ._jZ '`\ q, /= ~` \ __        j5 (/`\ ./V \\,      .Z)) '_____ | .____, \) /\     j5 (K = ~~~~~~ \ = _, | _ /= ~~~~ `` ~~ + K \\,   .Z) \ /`~ = L | _ = /~ t \ ZL  j5 (_ /.__ /=========== \ __ ~ q | j /.__ ============ ___ /\ J (N, 4L # XXXL _________________ XGm, \ P .mXL _________________ JXXXW8L ~~~~~~~~~~~~~~~~~~~~~~~~~ YKWmmWmmW @ ~~~~~~~~~~~~~~~~~~~~~~~ ~~~     ) »& quot; <endl; //Истории спать в постели?     cout <«Доступные точки умения [" <<умение <"]" <епсИ;     cout <"1- Сила [" <stre <"]" <епсИ;     cout <"2- Интеллект [" <inte <"]" <епсИ;     cout <"3-ловкость [" <dext <"]" <епсИ;     cout <«99-Выход» <епсИ;     cin> вход;     if (skill> 0) {         if (input == "1") {             stre = stre + 1;             skill = skill - 1;         } else if (input == "2") {             inte = inte + 1;             skill = skill - 1;         } else if (input = "3") {             dext = dext + 1;             skill = skill - 1;         } else if (input == "99") {             goto menue;         }     } else {         goto menue;     }     goto askill;     магазин:     Чисто();     cout <Р"(                                ____                   _ | --- || _                   || __________ | --- || ___________ ||                  /_ _ _ _ _ _ |: ._ | '_ _ _ _ _ _ _ \ `.                 /_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \: `.                /_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \ :: `.               /:.___________________________________\:::`-.__.-_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _`:: `-.._       _.- '_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ `: `-._     , '_: ._________________________________________________ `: _.- ';'      `. '/|| |:. '' /`. '/`. '/:: | .` '/.. | : |       || || |:: ||:: ||:: ||::: | .. || .. | ||       || || | __ || :: ___ || :: __ || :: | .. ||; || ||       || || | | :: | || :: | ::: | || :: | :: | || :: |. |||: || _____ || __       || || | | :: | || :: | ::: | || :: | :: | || :: |. |||: || _ | _ | _ ||, (       || _. || | | :: | || :: | ::: | || :: | :: | || :: |. '|| .. | _ ||, |    . .- ':: _:': -. - .- :: --.-: .--: -. :: --. - - .- :: --. - .- :. :: .- '- .'_ || |     ) || _ | __ || _ | __ | _ || __ | _ || :: | _ || __ | __ | __ | _ || __ | __ | _ |; - '| __ | _ ( , '||' -     |||| || |. , , ||. , , , , ||. , , , , ||. , , . | :: ||; '' || ||:»     |||| .; _ | ._._._ || ._._._._._ || ._._._._._ || ._._._. |: '|| ,, || ,,     '' '' '' '-' '-' '-' '' '' '     ) "<<endl;     цена = уровень * 5;     cout <"[Золото]>> <<золото <епсИ;     cout <"1- Зелье здоровья (" <цена <<"золото) <<епсИ;     cout <«99-Выход» <епсИ;     cin> вход;     if (input == "1") {         цена = уровень * 5;         если (золото> = цена) {             hpotion = hpotion + 1;             золото = золото - цена;             идти в магазин;         } else {             goto menue;         }     } else if (input == "99") {         goto menue;     }     идти в магазин;     //Получить /«Поворот» в квестах     questhall:     Чисто();     cout <Р"(          _______________     () == ((@ == ()          '______________' |            | |            | |          __) _____________ |     () == ((@ == ()          '--------------'     ) "<<endl;     cout <«Current Quest>>>»;     if (quest == 0) {         quest = rand ()% 5 + 1;         переключатель (квест) {             Дело 1:                 questc = 0;                 questr = 6;                 questmob = «Кабан»;                 questreward = rand ()% 4 + 1;                 questdisplay = "Slay Boars";             ломать;             случай 2:                 questc = 0;                 questr = 6;                 questmob = «Лев»;                 questreward = rand ()% 4 + 1;                 questdisplay = "Slay Lions";             ломать;             случай 3:                 questc = 0;                 questr = 6;                 questmob = "Слон";                 questreward = rand ()% 4 + 1;                 questdisplay = "Slay Elephants";             ломать;             случай 4:                 questc = 0;                 questr = 6;                 questmob = "Волк";                 questreward = rand ()% 4 + 1;                 questdisplay = "Slay Wolves";             ломать;             случай 5:                 questc = 0;                 questr = 6;                 questmob = "Паук";                 questreward = rand ()% 4 + 1;                 questdisplay = "Slay Spiders";             ломать;         }     }     cout <questdisplay <"[" <questc <"/" <questr <"]" <епсИ;     cout <«Награда>>>»;     switch (questreward) {         Дело 1:             qgoldr = rand ()% (уровень * 10) + (уровень * 10);             cout <qgoldr <«Золото» <епсИ;         ломать;         случай 2:             qxpr = rand ()% (уровень * 5) + (уровень * 5);             cout <qxpr <«XP» <епсИ;         ломать;         случай 3:             cout <«Слизистая нагрудница>> [Увеличение 10% HP]» <епсИ;         ломать;         случай 4:             cout <«Слизный шлем>> [5% HP увеличен]» <епсИ;         ломать;     }     if (questc> = questr) {         квест = 0;         switch (questreward) {             Дело 1:                 золото = золото + qgoldr;                 goto questhall;             ломать;             случай 2:                 xp = xp + qxpr;                 goto questhall;             ломать;             случай 3:                 slimychestplate = 1;                 goto questhall;             ломать;             случай 4:                 slimyhelmet = 1;                 goto questhall;             ломать;         }     }     cout <«99-Выход» <епсИ;     cin> вход;     goto menue;     dungeonmenue:     Чисто();     cout <Р"(    _________________________________________________________   | , |   | .- '`` `` `` ``.' '(`.-'` `` `` `` '-. |   | .` | `. `) '.` | `. |   | /| () \ U /| () \ |   | | | ; | o T o | | ; | |   | | | ; | , | , | | ; | |   | | | ; | , | , | | ; | |   | | | ; | . |. | | ; | |   | | | ____; _________ | | | | ____; _________ | |   | | /__; - | ! | /`'() _ - | |   | | /__ () - | - | /__-- - | |   | | /__-- _ | _-_ - | /__ - _ | || __ | /__________________ | ___________ | /__________________ | __ |  /_ - lc \ /-_- _ _ _ _ _-- -_____ \     ) "<<endl;     cout <«Доступные подземелья» <епсИ;     cout <"[1] Излучение Oozeworks>> [150 Gold, Oozing Gear]" <епсИ;     cout <"[99] Возврат к Menue" <епсИ;     cin> вход;     if (input == "99") {         goto menue;     } else if (input == "1") {         если (gold> = 150) {             status = "oozeworks";             золото = золото - 150;             ckills = 0;             rkills = 6;             goto oozeworks;         } else {             goto menue;         }     }     goto dungeonmenue;     oozeworks:     Чисто();     cout <Р"(  _____ _ _____ _ | _ | (_) | _ | | | | | | | ___ _____ _ __ __ _ | | | | ___ ______ _____ _ __ | | _____ | | | | /_ \ _ /| '_ \ /_` | | | | | /_ \ _ /\ \ /\ //_ \ | «__ | | //__ | \ \ _ //(_) //| | | | | (_ | | \ \ _ //(_) //\ V V /(_) | | | <\ __ \  \ ___ /\ ___ /___ | _ | _ | | _ | \ __, | \ ___ /\ ___ /___ | \ _ /\ _ /\ ___ /| _ | | _ | \ _ \ ___ /                          __ /|                         | ___ /     ) "<<endl;     если (ckills> = rkills) {         goto oozeworksc;     }     cout <"[1] Продолжить [" <ckills <"/" <rkills <«слизи убиты» »<епсИ;     cout <«[2] Адреналин (исцеляет все отсутствующие hp /mana)» <епсИ;     cout <"[99] Выход" <епсИ;     cin> вход;     if (input == "1") {         mmana = inte * 10;         shp = stre * 20;         mhp = stre * 20;         etype = "Slime";         random2 = rand ()% 2 + 1;         eability = "ил";         if (random2 == 1) {             ehp = shp + rand ()% (уровень * 8);         } else {             ehp = shp + rand ()% (уровень * 6);         }         mehp = ehp;         elevel = rand ()% (уровень + 3) +1;         if ((elevel <(level-3)) || (elevel> (уровень + 3))) {             elevel = level;         }         goto aarena;     } else if (input == "99") {         goto menue;     } else if (input == "2") {         mhp = stre * 20;         mmana = inte * 10;         hp = mhp;         hp = hp * (bphp + 1);         hp = hp + bhp;         mana = mmana;     }     goto oozeworks;     oozeworksc:     статус = "арена";     cout <«Вы закончили Oozing Oozworks» <епсИ;     rxp = rand ()% (уровень * 6) +5;     rgold = rand ()% (уровень * 9);     cout <«Вы получили» <rxp <"xp" <епсИ;     cout <«Вы получили» <rgold <«золото» <епсИ;     xp = xp + rxp;     золото = золото + rgold;     random = rand ()% 2 + 1;     переключатель (случайный) {         Дело 1:             cout <«Новые ножные лапы разблокированы! & Gt;>> [Озирая ножные латы, увеличивает hp на 15%]» <епсИ;             oozinglegplates = 1;         ломать;         случай 2:             cout <«Новые загрузки разблокированы! & Gt;>>> [Озирая сапоги, увеличивает hp на 10%]» <епсИ;             oozingboots = 1;         ломать;     }     cout <«Введите [1], чтобы вернуться в меню« <епсИ;     cin> вход;     goto menue;     oozeworksr:     ckills = ckills + 1;     rxp = rand ()% (уровень * 4) +5;     rgold = rand ()% (уровень * 7);     rgold = rgold * goldb;     cout <«Вы получили» <rxp <"xp" <епсИ;     cout <«Вы получили» <rgold <«золото» <епсИ;     xp = xp + rxp;     золото = золото + rgold;     если (xp> = xpl) {         level = level + 1;         xpl = xpl + xpb;         xpb = xpb + 50;         умение = умение + 5;         cout <«Вы выровнены до уровня» <уровень <епсИ;     }     cout <«Введите [1], чтобы продолжить свое приключение» <епсИ;     cin> вход;     goto oozeworks;     сохранить игру:     Чисто();     //Сохранение /загрузка строк     sslimychestplate = std :: to_string (slimychestplate);     sslimyhelmet = std :: to_string (slimyhelmet);     soozinglegplates = std :: to_string (oozinglegplates);     soozingboots = std :: to_string (oozingboots);     spiclass = std :: to_string (piclass);     slevel = std :: to_string (уровень);     sxp = std :: to_string (xp);     sxpb = std :: to_string (xpb);     sxpl = std :: to_string (xpl);     sstre = std :: to_string (stre);     sinte = std :: to_string (inte);     sdext = std :: to_string (dext);     shpotion = std :: to_string (hpotion);     sgold = std :: to_string (золото);     sskill = std :: to_string (умение);     code = "";     code = code + sgold + ":" + sstre + ":" + sinte + ":" + sdext + ":" + sskill + ":" + sxp + ":" + sxpl + ":" + sxpb + ": "+ slevel +": ";     code = code + shpotion + ":";     code = code + spiclass + sslimyhelmet +sslimichestplate + soozinglegplates + soozingboots;     cout <код <епсИ;     cout <«Введите [1], чтобы вернуться в меню« <епсИ;     cin> вход;     goto menue;     //Загрузка введенного игрового кода     загрузить игру:     Чисто();     sslimichestplate = "";     sslimyhelmet = "";     soozinglegplates = "";     soozingboots = "";     spiclass = "";     slevel = "";     sxp = "";     sxpb = "";     sxpl = "";     sstre = "";     sinte = "";     sdext = "";     shpotion = "";     sgold = "";     sskill = "";     cout <«Пожалуйста, введите ваш игровой код ТОЧНО (если вы этого не сделаете, это может привести к повреждению вашей игры)» <епсИ;     cin> вход;     код = ввод;     goto компилировать;     cout <код <епсИ;     //Загрузка игры Сохранить ФАЙЛ     компиляции:     x = 0;     goldr:     cout <sgold <епсИ;     if (code [x] == ':') {//Если символ является каналом         х = х + 1; //Перейти к следующей переменной         goto strer;     } else {         sgold = sgold + code [x]; //Если не добавлять переменные         х = х + 1; //Перейти к следующему символу         goto goldr;     }     strer:     if (code [x] == ':') {//Если символ является каналом         х = х + 1; //Перейти к следующей переменной         goto inter;     } else {         sstre = sstre + code [x]; //Если не добавлять переменные         х = х + 1; //Перейти к следующему символу         goto strer;     }     в том:     if (code [x] == ':') {//Если символ является каналом         х = х + 1; //Перейти к следующей переменной         goto dextr;     } else {         sinte = sinte + code [x]; //Если не добавлять переменные         х = х + 1; //Перейти к следующему символу         goto inter;     }     dextr:     if (code [x] == ':') {//Если символ является каналом         х = х + 1; //Перейти к следующей переменной         goto skillr;     } else {         sdext = sdext + code [x]; //Если не добавлять переменные         х = х + 1; //Перейти к следующему символу         goto dextr;     }     skillr:     if (code [x] == ':') {//Если символ является каналом         х = х + 1; //Перейти к следующей переменной         goto xpr;     } else {         sskill = sskill + code [x]; //Если не добавлять переменные         х = х + 1; //Перейти к следующему символу         goto skillr;     }     XPR:     if (code [x] == ':') {//Если символ является каналом         х = х + 1; //Перейти к следующей переменной         goto xplr;     } else {         sxp + = код [x]; //Если не добавлять переменные         х = х + 1; //Перейти к следующему символу         goto xpr;     }     xplr:     if (code [x] == ':') {//Если символ является каналом         х = х + 1; //Перейти к следующей переменной         goto xpbr;     } else {         sxpl = sxpl + code [x]; //Если не добавлять переменные         х = х + 1; //Перейти к следующему символу         goto xplr;     }     xpbr:     if (code [x] == ':') {//Если символ является каналом         х = х + 1; //Перейти к следующей переменной         goto levelr;     } else {         sxpb = sxpb + code [x]; //Если не добавлять переменные         х = х + 1; //Перейти к следующему символу         goto xpbr;     }     levelr:     if (code [x] == ':') {//Если символ является каналом         х = х + 1; //Перейти к следующей переменной         goto hpotionr;     } else {         slevel = slevel + code [x]; //Если не добавлять переменные         х = х + 1; //Перейти к следующему символу         goto levelr;     }     hpotionr:     if (code [x] == ':') {//Если символ является каналом         х = х + 1; //Перейти к следующей переменной         товары goto;     } else {         shpotion = shpotion + code [x]; //Если не добавлять переменные         х = х + 1; //Перейти к следующему символу         goto hpotionr;     }     Предметы:     spiclass + = code [x];     х = х + 1;     sslimyhelmet + = код [x];     х = х + 1;     sslimichestplate + = код [x];     х = х + 1;     soozinglegplates + = code [x];     х = х + 1;     soozingboots + = код [x];     goto settingvaribles;     settingvaribles:     gold = atoi (sgold.c_str ()); //Золото     stre = atoi (sstre.c_str ()); //Прочность     inte = atoi (sinte.c_str ()); //Интеллект     dext = atoi (sdext.c_str ()); //Ловкость     skill = atoi (sskill.c_str ()); //Очки навыка     xp = atoi (sxp.c_str ()); //Xp     xpl = atoi (sxpl.c_str ()); //Xp до уровня     xpb = atoi (sxpb.c_str ()); //Увеличивает количество xpl     level = atoi (slevel.c_str ()); //Уровень     hpotion = atoi (shpotion.c_str ()); //Зелье HP     piclass = atoi (spiclass.c_str ()); //Класс     slimyhelmet = atoi (sslimyhelmet.c_str ()); //Слизный шлем     slimychestplate = atoi (sslimichestplate.c_str ()); //Слизистая нагрудник     oozinglegplates = atoi (soozinglegplates.c_str ()); //Изношенные ножные латы     oozingboots = atoi (soozingboots.c_str ()); //Озирая сапоги     if (piclass == 1) {         pclass = "Чемпион";     } else if (piclass == 2) {         pclass = "Некромант";     } else if (piclass == 3) {         pclass = "Assassin";     } else if (piclass == 4) {         pclass = "Клирик";     }     /*     gold = arr [1];     stre = arr [2];     inte = arr [3];     dext = arr [4];     skill = arr [5];     xp = arr [6];     xpl = arr [7];     xpb = arr [8];     level = arr [9];     hpotion = arr [10];     piclass = arr [11];     slimyhelmet = arr [12];slimychestplate = arr [13];     oozinglegplates = arr [14];     oozingboots = arr [15];     * /     goto compilend;     compilend:     Чисто();     loadingload:     cout <Р"( db .d88b. .d8b. d8888b. d888888b d8b db d888b 88 .8P Y8. d8 '`8b 88` 8D `88' 888o 88 88 'Y8b 88 88 88 88ooo88 88 88 88 88V8o 88 88 88 88 88 88 ~~~ 88 88 88 88 88 V8o88 88 ooo 88booo. `8b d8 '88 88 88 .8D .88. 88 V888 88. ~ 8 ~ Y88888P `Y88P 'YP YP Y8888D' Y888888P VP V8P Y888P     ) "<<endl;     y = 0;     loadingload2:     если (y <101) {         y = y + 1;         goto loadingload2;     }     Чисто();     cout <"------- ~ Процесс завершен ~ -------" <<епсИ;     cout <«Повторно введите свое имя» <<епсИ;     cin> вход;     name = input;     goto menue;     оставлять:     Чисто();     cout <"Увидимся!" & Л; & л; епсИ;     return 0; }
45 голосов | спросил Handge 5 PM00000050000001031 2017, 17:58:10

6 ответов


43

Прежде всего, позвольте мне присоединиться к другим, указав, что sweet ASCII искусство вы сделали. Это определенно имеет начало much более приятной текстовой игры, чем большинство.

Я бы начал с определения некоторых структур для хранения данных о конкретных вещах в игре. Для нескольких примеров:

struct Ability {
    std::string name;
    int level_adder;

    int cost(int level, int inte) { 
        return (level + level_adder) * inte;
    }

    bool can_afford(int level, int inte, int manna) { 
        return cost(level, inte) <= manna;
    }

    void show(int level, int inte) { 
        std::cout << name << "[" << cost() << " manna]\n";
    }       
};

class PlayerClass {
    std::string name;
    std::vector<Ability> abilities;
    size_t ability_count() { return abilities.size(); }

    void show(int level, int inte) {
        for (int i=0; i<abilities.size(); i++)
            std::cout << "[" << i << "] ";
            abilities[i].show(level, inte);
    }

    Ability const &operator[](size_t index) const { 
        return abilities.at(index);
    }
};

С их помощью мы можем определить все данные для классов Игрока примерно так:

PlayerClass Champion{
    "Champion",
    { "Cleaving Strike", 0},
    { "Melting Thrust", 0},
    {"Critical Bash", 0},
    {"Purify", 1}
};

PlayerClass Necromancer{
    "Necromancer",
    { "Shadow Strike", 0},
    { "cripple", 0},
    { "Mutilate", 0},
    { "Life Tap", 2}
};

... и т. д. для других классов игроков. Только для одного примера это значительно упростит much добавить дополнительные классы игроков в будущем - например, я могу сесть и решить, что хочу добавить класс «вор»:

PlayerClass Thief { 
    "Thief",
    { "Pick Pocket", 0},
    { "Grab Purse", 0},
    { "Rob Business", 1},
    { "Rob Bank", 4}
};

... и большая часть остальной части игры может работать с этим новым классом игроков без каких-либо изменений. Аналогичным образом, я могу добавить новую способность к существующему классу игроков, просто решив имя и относительную стоимость использования этой способности - мне не нужно изменять всю логику, связанную с возможностями, чтобы учитывать вновь добавленную способность .

Затем мы можем определить игрока для хранения (например) ссылки на объект PlayerClass:

class Player { 
    PlayerClass &pclass;
    // ...
};

При этом getability явно возвращает (возможно, указатель или ссылку) объект Ability и выглядит примерно так:

player.pclass.show();
cin >> input;

// This logic isn't complete--we need to add a call to `can_afford` to see 
// whether the player can afford to use an ability.
if (input > player.pclass.ability_count()
    ability = None;
else { 
    ability = player.pclass[input];
    player.manna -= ability.cost();
}

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

Предотвращение ошибок

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

Нейминг

Некоторые из имен, которые вы использовали, сокращены до такой степени, что я не уверен, что они предназначены для обозначения. Только для нескольких примеров, inte и stre - я бы сократил их до такой степени, что кто-то, читающий код, может легко понять, что они должны действительно означает.

ответил Jerry Coffin 5 PM00000080000005231 2017, 20:09:52
29

Есть хорошие новости и плохие новости об этом коде. Плохая новость в том, что это не очень хороший код. Хорошая новость заключается в том, что это не будет слишком сложно, чтобы улучшить его, и искусство ASCII является удивительным! Вот несколько замечаний, которые могут помочь вам улучшить код.

Не злоупотребляйте using namespace std

Ввод using namespace std в верхней части каждой программы плохая привычка , которую вы бы хорошо избежали.

Рассмотрим разделение ввода-вывода от алгоритма

Сейчас все делается в основном. Лучшая практика состоит в том, чтобы разделить вещи на функции. В частности, я бы рекомендовал разделить подпрограммы ввода /вывода на отдельные функции. Прямо сейчас поток управления слишком сложный, и трудно сказать, что происходит в коде.

Избегайте использования goto

Наличие размножения операторов goto обычно является признаком плохого дизайна. Лучше было бы полностью их устранить - это делает код более легким для восприятия и менее подверженным ошибкам. В этом коде вероятно, что вместо этого вы могли бы использовать оператор состояния и switch, что сделало бы код намного проще для отслеживания и гораздо менее подвержен ошибкам.

Использовать объекты

Поскольку вы пишете на C ++, имеет смысл использовать объекты. Например, у вас может быть класс Player, который содержит все переменные, которые в настоящее время помечены только комментарием «переменные игрока» и классом состояния игры, чтобы упростить загрузку и сохранение состояния игры.

Рассмотрим использование лучшего генератора случайных чисел

В настоящее время вы используете

random = rand()%5+1;

Существует проблема с этим подходом: младшие разряды генератора случайных чисел не являются особенно случайными, поэтому не будет random. На моей машине есть небольшое, но измеримое смещение к 0 с этим. Лучшим решением, если ваш компилятор и библиотека его поддерживает, было бы использовать C ++ 11 `std :: uniform_int_distribution . Он выглядит сложным, но на самом деле он довольно прост в использовании.

class Die {
public:
    Die(int min, int max) : min{min}, max{max} {}
    Die(int max=6) : min{1}, max{max} {}
    int operator()() { 
        std::uniform_int_distribution<> dist(min,max);
        return dist(eng);
    }

private:
    int min; 
    int max;
    static std::mt19937 eng;
};

std::mt19937 Die::eng{std::random_device{}()};

Если вы хотите, как в этом примере, некоторое число от 1 до 6, просто назовите его следующим образом:

int main() {
    Die die{6};   // create conventional 6-sided die
    for (int i=20; i; --i) {
        std::cout << die();
    }
}

Устранить «магические числа»

В коде есть числа, которые посыпаются по всему коду, например 5 и 6, которые имеют конкретное значение в их конкретном контексте. Используя именованные константы, программа становится легче читать и поддерживать. Для случаев, когда константа имеет смысл только по отношению к определенному объекту, рассмотрим возможность сделать эту постоянную часть объекта.

Omit return 0

Когда программа C или C ++ достигает конца main, компилятор автоматически сгенерирует код для возврата 0, поэтому нет необходимости явно помещать return 0; в конец main.

ответил Edward 5 PM00000070000003131 2017, 19:54:31
15

Управляющий поток

Я хочу одобрить и изложить немного совета Эдварда по удалению операторов goto. Более подходящий подход здесь - это своего рода конечный автомат . У вас есть какое-то игровое состояние, которое отслеживает, в каком режиме вы находитесь, например, выбираете ли вы способность, передвигаетесь, начинаете встречу и т. Д.

Вы рисуете любой экран, соответствующий текущему состоянию. (Скажем, карта в сухопутном режиме, искусство ASCII монстра в боевом режиме, возможно, созданное в коробке подземелье от первого лица, если вы отдаете дань уважения Wizardry или Ultima em>?) Отображаемые параметры зависят от игрового режима, от того, какие у вас есть способности, и от того, что у вас есть (например, какие предметы находятся в вашем инвентаре, может быть, или сколько энергии у вас есть, или период перезарядки). При выборе любой опции обновляется состояние игры. Например, победа в битве может отправить вас на экран лута. Логика программы представляет собой цикл, подобный этому:

while ( !state.hasQuit() ) {
  state.displayScreen();
  state.getActionAndUpdate();
}

Намного проще и проще следовать, чем набор операторов goto!

Затем displayScreen() может, скажем, очистить экран, распечатать строку состояния, распечатать искусство ASCII, посмотреть, какие способности у вас есть, распечатать их и дать вам приглашение меню.

Если состояние становится большим и громоздким, вы больше не хотите держать все состояние игры в одном «Божьем объекте», что все должно обманывать. Статистика игроков может попасть в один объект, карты мира в другой, статистика врагов в других. Однако отдельные подсистемы имеют смысл. Но такой вид представляет собой приятный простой шаблон для отслеживания того, какой игровой режим вы сейчас используете и действуете соответствующим образом.

Использование OO для очистки кода

Вариант состоит в том, чтобы сделать последнюю строку чем-то вроде state = state->getNewState(), где state - это указатель, тип которого является базовым классом всех состояния. Это позволяет разделить абстрактную концепцию игрового режима на конкретные экземпляры, например, режим сухопутного режима или режим боя . Это могут быть дочерние классы, функции-члены которых реализуют правильное поведение для этого режима. Затем каждая из этих функций-членов будет короче и четче, чем одна большая функция, которая содержит все пути кода для каждого режима. Вы выбираете между ними, возвращая ссылку на другой объект состояния, без if, switch или goto.

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

Если вам нужно создать новые объекты состояния, например, чтобы хранить различную информацию для каждого боя, вы хотите управлять ими с помощью интеллектуальных указателей, таких как std::unique_ptr. Это делает все управление памятью для вас, что в противном случае является одной из самых сложных вещей, чтобы получить право.

Если у вас есть какие-либо оставшиеся разделы кода, которые соответствуют шаблону серии тестов для выбора другой ветви кода для каждого из многих случаев, классическим решением является определение enum с помощью константа для каждого возможного случая, а затем напишите оператор switch. Ваш компилятор может даже предупредить вас, если вы забудете или ошиблись в одном из случаев.

Избегать глобальных переменных

Это очень сложно отладить вашу программу, поскольку любая часть кода могла бы их изменить. Лучшее решение состоит в том, чтобы иметь состояние магазина в государственном хранилище, например, количество здоровых зелий, которые у вас есть. Затем только код для использования уменьшает счетчик, и только код для проверки инвентаря просматривает его и отображает его.

Вы также хотели бы хранить числовые данные как число, а не как строку, которую вы повторно конвертируете обратно в число.

Использование структур данных

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

Но, например, ваше феноменальное искусство ASCII и другие данные монстра могут быть сохранены как значения в хеш-таблице (std::unordered_map в STL) с именами, которые вы используете для выберите их как ключи. Это будет иметь несколько преимуществ. Одним из самых важных является то, что если вы добавите другого монстра, вам просто нужно добавить его запись в таблицу в одном месте.

Лечение каждой новой способности и каждого нового монстра в качестве особого случая, требующего специальной обработки в каждом фрагменте кода, который имеет дело с ними, становится настоящим кошмаром: вам всегда нужно проверять, чтобы вы помнили о них повсюду и рассматривали их последовательно. Если вы поместите все данные в одном месте и напишите код в другом месте, которое может обрабатывать любую часть данных, добавляя материалстановится намного проще.

Некоторые технические характеристики

В этом случае вы можете подумать о сохранении своего искусства ASCII в качестве векторов строк. (Так как двумерный массив может означать несколько разных вещей, хорошим однозначным именем для этого является прямоугольный массив .) Это позволило бы, например, отображать изображение монстра в коробке и обернуть вокруг него инфоподумент или показать его статистику слева или справа от изображения или наложить надпись под надписью «-999 HP» на фрейме.

Я хочу повторить и подчеркнуть совет, чтобы отделить данные от отображаемого кода. Вы хотите, чтобы код был ортогонален вашим игровым данным. Вы не должны переписывать код отображения для каждого вида монстра, потому что это делает кошмар когда-либо измененным. Не повторись! Это также позволяет вам делать гораздо больше вещей с вашими данными или запускать свой код на произвольные новые данные.

Если вы создадите массивы массивов с широкими символами, используйте std::wcout, вы можете использовать искусство Unicode, а не только искусство ASCII. Возможно, вы не захотите этого. Ваше искусство впечатляет. В классических играх вы снова вернетесь к использованию символов рисования и геометрических фигур в Unicode. Но вариант есть. Обратите внимание, что Windows нуждается в небольшом нестандартном коде инициализации внутри блока #ifdef, чтобы это работало, но я могу поделиться им, если вы хотите.

Во многих системах даже сегодня вы также можете вставлять цветовые коды ANSI (16 цветов, переднего плана и фона, а также некоторые специальные функции, такие как полужирный и подчеркивающий, например, в конце 8-битной или ранней 16-разрядной эры и точно так же классические терминалы Unix через telnet) или цвет xterm (более 200). Canâ € ™ t получить более достоверно ретро, ​​чем это. Консоль Linux поддерживает эти коды изначально, и я думаю, что OSX-терминал тоже делает.

ответил Davislor 6 AM00000040000005431 2017, 04:02:54
10

Возможно, вы захотите загрузить искусство ascii из отдельных текстовых файлов, чтобы вы могли редактировать те, не входя в функциональный код.

ответил Rchn 7 PM00000020000000731 2017, 14:14:07
5

Отделите код от коротких и простых функций

Ваши текущие функции слишком длинны: например, main() имеет 1282 строки. Это гораздо более приемлемо. Хотя точное максимальное количество строк является субъективным, есть несколько хороших эмпирических правил. Например, этот вопрос упоминает от 100 до 200 строк как верхнюю границу. В идеале каждая функция должна делать только одну вещь и делать это хорошо - это называется SRP, единоличная ответственность принцип . Во многих программах main() является чем-то исключением из этого, так как обычно он выполняет как инициализацию (путем вызова init() или аналогичной функции), так и основного цикла. Тем не менее, основной цикл должен состоять в основном из вызовов других функций и /или логики конечных автоматов. Я считаю, что другие ответы дают более подробную информацию о его структурировании.

ответил kfx 7 PM00000050000000031 2017, 17:16:00
3

Из всех ответов одна вещь, которую я бы выделил больше всего, - это использование объектов . Об этом уже ответили, но опять же, я хотел бы подчеркнуть его подробно. Если вы только узнаете об этом, это стоит больше, чем остальные ответы, объединенные.

Вы, кажется, думаете в процедурах и алгоритмах. Это хорошо, если вы делаете C, но если вы хотите сделать C ++, научитесь думать об объектах. У объектов есть четкие обязанности, в которых вы доверяете вслепую (пока работают их модульные тесты), и вам не нужно знать, КАК они делают вещи. Объекты работают как автономные объекты. Я бы рекомендовал, чтобы вы вообще не использовали никаких функций, лучше всего, только когда вам нужно расширить функциональность стандартного типа библиотеки, например std :: vector.

В конце концов, ваш главный должен выглядеть следующим образом:

int main() {
    Game game;
    game.run();
    return 0;
}

Класс Game (или, тем не менее, вы хотите его назвать) создает другие классы, которые, в свою очередь, могут создать еще что-то в иерархии. Методы такого класса вызывают методы других классов и не намного больше, чем заставить дочерние объекты работать вместе. Фактические алгоритмы как можно короче, в методах большинства базовых классов.

Все, что является содержимым - как искусство ASCII, имена классов персонажей RPG, имена мест и так далее - не должно быть в самом коде.

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

ответил Aziuth 7 PM00000060000001731 2017, 18:09:17

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132