diff --git a/CourseApp.Tests/PetTest.cs b/CourseApp.Tests/PetTest.cs new file mode 100644 index 0000000..26ae1e6 --- /dev/null +++ b/CourseApp.Tests/PetTest.cs @@ -0,0 +1,47 @@ +namespace CourseApp.Tests +{ + using CourseApp.Entities; + using Xunit; + + public class PetTest + { + [Fact] + public void BirdTest() + { + var bird = new Bird("Кеша", "зелёный", 5); + var expectedText = @" зелёный попугай Кеша + \\ + \\ (o> + (o> //\ + _(()_____V_/_____ + || || + ||"; + Assert.Equal(expectedText, bird.GetInfo()); + } + + [Fact] + public void DogTest() + { + var dog = new Dog("Рэкс", "черный", 6); + var expectedText = @" черный пёс Рэкс + ,-.___,-. + \\_/_ _\\_/ + )O_O( + { (_) } + `-^-' +"; + Assert.Equal(expectedText, dog.GetInfo()); + } + + [Fact] + public void CatTest() + { + var cat = new Cat("Гаф", "чёрный", 5); + var expectedText = @" чёрный котёнок Гаф + /\_/\ + ( o.o ) + > ^ <"; + Assert.Equal(expectedText, cat.GetInfo()); + } + } +} \ No newline at end of file diff --git a/CourseApp.sln b/CourseApp.sln index 12714a0..700b4d9 100644 --- a/CourseApp.sln +++ b/CourseApp.sln @@ -7,6 +7,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CourseApp", "CourseApp\Cour EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CourseApp.Tests", "CourseApp.Tests\CourseApp.Tests.csproj", "{3F66714D-FFFA-4512-A62B-4D038AB148AD}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RpgSage", "RpgSage\RpgSage.csproj", "{922CF869-B07C-498A-A5F3-ACAF56C07DFA}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -21,6 +23,10 @@ Global {3F66714D-FFFA-4512-A62B-4D038AB148AD}.Debug|Any CPU.Build.0 = Debug|Any CPU {3F66714D-FFFA-4512-A62B-4D038AB148AD}.Release|Any CPU.ActiveCfg = Release|Any CPU {3F66714D-FFFA-4512-A62B-4D038AB148AD}.Release|Any CPU.Build.0 = Release|Any CPU + {922CF869-B07C-498A-A5F3-ACAF56C07DFA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {922CF869-B07C-498A-A5F3-ACAF56C07DFA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {922CF869-B07C-498A-A5F3-ACAF56C07DFA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {922CF869-B07C-498A-A5F3-ACAF56C07DFA}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/CourseApp/Entities/Bird.cs b/CourseApp/Entities/Bird.cs new file mode 100644 index 0000000..60b3507 --- /dev/null +++ b/CourseApp/Entities/Bird.cs @@ -0,0 +1,23 @@ +namespace CourseApp.Entities +{ + using System; + + public class Bird : Pet + { + public Bird(string nick, string color, int age) + : base(nick, color, age) + { + } + + public override string GetInfo() + { + return $" {Color} попугай {Nick}" + @" + \\ + \\ (o> + (o> //\ + _(()_____V_/_____ + || || + ||"; + } + } +} \ No newline at end of file diff --git a/CourseApp/Entities/Cat.cs b/CourseApp/Entities/Cat.cs new file mode 100644 index 0000000..34bcc4d --- /dev/null +++ b/CourseApp/Entities/Cat.cs @@ -0,0 +1,17 @@ +namespace CourseApp.Entities; + +public class Cat : Pet +{ + public Cat(string nick, string color, int age) + : base(nick, color, age) + { + } + + public override string GetInfo() + { + return $" {Color} котёнок {Nick}" + @" + /\_/\ + ( o.o ) + > ^ <"; + } +} \ No newline at end of file diff --git a/CourseApp/Entities/Dog.cs b/CourseApp/Entities/Dog.cs new file mode 100644 index 0000000..e21b69b --- /dev/null +++ b/CourseApp/Entities/Dog.cs @@ -0,0 +1,20 @@ +namespace CourseApp.Entities; + +public class Dog : Pet +{ + public Dog(string nick, string color, int age) + : base(nick, color, age) + { + } + + public override string GetInfo() + { + return $" {Color} пёс {Nick}" + @" + ,-.___,-. + \\_/_ _\\_/ + )O_O( + { (_) } + `-^-' +"; + } +} \ No newline at end of file diff --git a/CourseApp/Entities/Pet.cs b/CourseApp/Entities/Pet.cs new file mode 100644 index 0000000..0f8cc0d --- /dev/null +++ b/CourseApp/Entities/Pet.cs @@ -0,0 +1,43 @@ +namespace CourseApp.Entities +{ + using System; + + public abstract class Pet + { + private int age; // поле + + public Pet(string nick, string color, int age) // конструктор + { + Nick = nick; + Color = color; + Age = age; + } + + public string Nick { get; set; } // свойство + + public string Color { get; set; } // свойство + + public int Age + { + get + { + return age; + } + + set + { + if (value != 1 && value > 0) + { + this.age = value; + } + } + } + + public virtual string GetInfo() => "It's a pet"; // крактая запись return, стрелочная функция, в JS пригодится) + /* + * public virtual string GetInfo() { + * return "It's a pet"; + * } + */ + } +} diff --git a/CourseApp/Program.cs b/CourseApp/Program.cs index d6d2c87..99953d0 100644 --- a/CourseApp/Program.cs +++ b/CourseApp/Program.cs @@ -1,12 +1,28 @@ namespace CourseApp { using System; + using System.Collections.Generic; + using CourseApp.Entities; // эту штуку заставил создать семён, я не виновата, спасите public class Program { - public static void Main(string[] args) + public static void Main() { - Console.WriteLine("Hello World"); + Pet gaf = new Cat("Гаф", "чёрный", 5); + Pet rex = new Dog("Рэкс", "черный", 6); + Pet kesha = new Bird("Кеша", "зелёный", 2); + + var petList = new List + { + gaf, + rex, + kesha, + }; + + foreach (var pet in petList) + { + Console.WriteLine(pet.GetInfo()); + } } } } diff --git a/RpgSage/Program.cs b/RpgSage/Program.cs new file mode 100644 index 0000000..c5eae01 --- /dev/null +++ b/RpgSage/Program.cs @@ -0,0 +1,6 @@ +using KornilichRpgSage; + +Console.WriteLine("Старт игры РПГ-Сага"); + +var game = new Game(); +game.Start(); \ No newline at end of file diff --git a/RpgSage/RpgSage.csproj b/RpgSage/RpgSage.csproj new file mode 100644 index 0000000..b9de063 --- /dev/null +++ b/RpgSage/RpgSage.csproj @@ -0,0 +1,10 @@ + + + + Exe + net6.0 + enable + enable + + + diff --git a/RpgSage/bl/Fight.cs b/RpgSage/bl/Fight.cs new file mode 100644 index 0000000..3484675 --- /dev/null +++ b/RpgSage/bl/Fight.cs @@ -0,0 +1,79 @@ +using KornilichRpgSage.enums; +using KornilichRpgSage.interfaces; + +namespace KornilichRpgSage; + +public static class Fight +{ + public static List Round(List players) + { + var winners = new List(); + while (players.Count > 1) + { + var random = new Random(); + var firstPlayer = players[random.Next(players.Count)]; + players.Remove(firstPlayer); + var secondPlayer = players[random.Next(players.Count)]; + players.Remove(secondPlayer); + + winners.Add(HeroesFight(firstPlayer, secondPlayer)); // добавляем в список победителей + } + return winners; + } + + private static IHero HeroesFight(IHero firstPlayer, IHero secondPlayer) + { + + // вывод информации о сражение двух героев + Console.WriteLine(""); + Console.WriteLine($"{firstPlayer.ClassName} {firstPlayer.Name} сражается с {secondPlayer.ClassName} {secondPlayer.Name}"); + Console.WriteLine(""); + + IHero attacker = firstPlayer; + IHero attacked = secondPlayer; + do + { + if (attacker.Effect == EffectEnum.Fire) + { + attacker.Health -= 2; + Console.WriteLine($"{attacker.Name} горит и получает урон 2"); + } + + if (attacker.Effect == EffectEnum.Skip) + { + (attacker, attacked) = (attacked, attacker); + Attack(attacked, attacker); + attacker.Effect = EffectEnum.None; + } + else if (!attacker.UseAbility(attacked)) + { + Attack(attacker, attacked); + } + + (attacker, attacked) = (attacked, attacker); + + } while (firstPlayer.Health > 0 && secondPlayer.Health > 0); + + + if (firstPlayer.Health <= 0) + { + Console.WriteLine($"Победил {firstPlayer.ClassName} {secondPlayer.Name}"); + Console.WriteLine(""); + secondPlayer.Health = secondPlayer.MaxHealth; + firstPlayer.Effect = EffectEnum.None; + return secondPlayer; + } + Console.WriteLine(""); + Console.WriteLine($"Победил {firstPlayer.ClassName} {firstPlayer.Name}"); + Console.WriteLine(""); + firstPlayer.Health = firstPlayer.MaxHealth; + firstPlayer.Effect = EffectEnum.None; + return firstPlayer; + } + + private static void Attack(IHero attacker, IHero attacked) + { + Console.WriteLine($"{attacker.Name} ({attacker.Health}) атакует {attacked.Name} ({attacked.Health})"); + attacked.Health -= attacker.Power; + } +} \ No newline at end of file diff --git a/RpgSage/bl/Game.cs b/RpgSage/bl/Game.cs new file mode 100644 index 0000000..e383901 --- /dev/null +++ b/RpgSage/bl/Game.cs @@ -0,0 +1,21 @@ +using KornilichRpgSage.factory; +using KornilichRpgSage.handlers; + +namespace KornilichRpgSage; + +public class Game +{ + public void Start() + { + var playersCount = PlayersCountHandler.GetPlayersCount(); + var players = HeroesFactory.GenerateHeroes(playersCount); // генерируем список игроков + + for (var i = 0; i < (int)Math.Log2(playersCount); i++) // по формуле мы считаем количество раундов + { + Console.WriteLine($"НАЧАЛСЯ РАУНД {i + 1}"); + Console.WriteLine("----------------------"); + players = Fight.Round(players); // здесь происходит ранунд у бойцов + Console.WriteLine("----------------------"); + } + } +} diff --git a/RpgSage/entities/Archer.cs b/RpgSage/entities/Archer.cs new file mode 100644 index 0000000..780f1e9 --- /dev/null +++ b/RpgSage/entities/Archer.cs @@ -0,0 +1,32 @@ +using KornilichRpgSage.enums; +using KornilichRpgSage.interfaces; + +namespace KornilichRpgSage.entities; + +public class Archer : IHero +{ + public int Health { get; set; } + public int MaxHealth { get; set; } + public int Power { get; set; } + public string Name { get; set; } + + public string ClassName { get; set; } + + public EffectEnum Effect { get; set; } + + private bool IsFireArrowsWasUse { get; set; }= false; + + public bool UseAbility(IHero attacked) + { + var random = new Random().Next(10); + if (random > 6 && IsFireArrowsWasUse == false) + { + Console.WriteLine($"{Name} использовал суперспособность горящие стрелы"); + attacked.Effect = EffectEnum.Fire; + IsFireArrowsWasUse = true; + return true; + } + + return false; + } +} \ No newline at end of file diff --git a/RpgSage/entities/Knight.cs b/RpgSage/entities/Knight.cs new file mode 100644 index 0000000..b979b0b --- /dev/null +++ b/RpgSage/entities/Knight.cs @@ -0,0 +1,29 @@ +using KornilichRpgSage.enums; +using KornilichRpgSage.interfaces; + +namespace KornilichRpgSage.entities; + +public class Knight : IHero +{ + public int Health { get; set; } + public int MaxHealth { get; set; } + public int Power { get; set; } + public string Name { get; set; } + + public string ClassName { get; set; } + + public EffectEnum Effect { get; set; } + + public bool UseAbility(IHero attacked) + { + var random = new Random().Next(10); + if (random > 7) + { + attacked.Health -= (int)(Power * 1.3); + Console.WriteLine($"{Name} использовал суперспособность удар возмездия и наносит {(int)(Power * 1.3)} урона"); + return true; + } + + return false; + } +} \ No newline at end of file diff --git a/RpgSage/entities/Mage.cs b/RpgSage/entities/Mage.cs new file mode 100644 index 0000000..c7f84d5 --- /dev/null +++ b/RpgSage/entities/Mage.cs @@ -0,0 +1,28 @@ +using KornilichRpgSage.enums; +using KornilichRpgSage.interfaces; + +namespace KornilichRpgSage.entities; + +public class Mage : IHero +{ + public int Health { get; set; } + public int MaxHealth { get; set; } + public int Power { get; set; } + public string Name { get; set; } + + public string ClassName { get; set; } + + public EffectEnum Effect { get; set; } + + public bool UseAbility(IHero attacked) + { + var random = new Random().Next(10); + if (random > 7) + { + attacked.Effect = EffectEnum.Skip; + Console.WriteLine($"{Name} использовал суперспособность оглушение"); + return true; + } + return false; + } +} \ No newline at end of file diff --git a/RpgSage/enums/EffectEnum.cs b/RpgSage/enums/EffectEnum.cs new file mode 100644 index 0000000..632be96 --- /dev/null +++ b/RpgSage/enums/EffectEnum.cs @@ -0,0 +1,8 @@ +namespace KornilichRpgSage.enums; + +public enum EffectEnum +{ + None = 0, + Fire = 1, + Skip = 2 +} \ No newline at end of file diff --git a/RpgSage/enums/HeroesEnum.cs b/RpgSage/enums/HeroesEnum.cs new file mode 100644 index 0000000..f0d6f35 --- /dev/null +++ b/RpgSage/enums/HeroesEnum.cs @@ -0,0 +1,12 @@ +namespace KornilichRpgSage.enums; + +// id класс персонажа + +public enum HeroesEnum +{ + MAGE = 0, + KNIGHT = 1, + ARCHER = 2 +} + +// enumeration - перечисление не как бы) \ No newline at end of file diff --git a/RpgSage/factory/HeroesFactory.cs b/RpgSage/factory/HeroesFactory.cs new file mode 100644 index 0000000..4351690 --- /dev/null +++ b/RpgSage/factory/HeroesFactory.cs @@ -0,0 +1,62 @@ +using KornilichRpgSage.entities; +using KornilichRpgSage.enums; +using KornilichRpgSage.interfaces; + +namespace KornilichRpgSage.factory; + +public static class HeroesFactory +{ + public static List GenerateHeroes(int count) + { + var heroes = new List(); + var random = new Random(); + + string[] names = { "Гарри", "Мари", "Томас", "Элис", "Джон", "Сара", "Аарон", "Абрам", "Аваз", "Аввакум", "Август", "Августа", "Августин", "Августина", "Авдей", "Авдий", "Авдотья", "Авигея", "Авксентий", "Авраам", "Аврор", "Аврора", "Автандил", "Автоноя", "Агап", "Агапия", "Агата", "Агафон", "Агафья", "Аггей", "Аглая", "Агнес", "Агнесса", "Агнета", "Агния", "Агриппина", "Агунда", "Ада", "Адам", "Аделаида", "Аделина", "Аделия", "Адель", "Адельфина", "Адиля", "Адис", "Адольф", "Адриан", "Адриана", "Адриенна", "Аза", "Азалия", "Азамат", "Азарий", "Азат", "Азиза", "Аида", "Айганым", "Айгерим", "Айгуль", "Айдар", "Айжан", "Айлин", "Айнагуль", "Айнур", "Айрат", "Акакий", "Аким", "Аксён", "Аксинья", "Акулина", "Алан", "Алана", "Алдона", "Алевтин", "Алевтина", "Александр", "Александра", "Александрина", "Алексей", "Алексий", "Ален", "Алёна", "Алеся", "Али", "Алика", "Алико", "Алима", "Алина", "Алира", "Алиса", "Алихан", "Алия", "Алла", "Алмаз", "Алоис", "Алсу", "Алтжин", "Альба", "Альберт", "Альберта", "Альбина", "Альвиан", "Альвина", "Альжбета", "Альфия" , "Аарон", "Абрам", "Аваз", "Аввакум", "Август", "Августа", "Августин", "Августина", "Авдей", "Авдий", "Авдотья", "Авигея", "Авксентий", "Авраам", "Аврор", "Аврора", "Автандил", "Автоноя", "Агап", "Агапия", "Агата", "Агафон", "Агафья", "Аггей", "Аглая", "Агнес", "Агнесса", "Агнета", "Агния", "Агриппина", "Агунда", "Ада", "Адам", "Аделаида", "Аделина", "Аделия", "Адель", "Адельфина", "Адиля", "Адис", "Адольф", "Адриан", "Адриана", "Адриенна", "Аза", "Азалия", "Азамат", "Азарий", "Азат", "Азиза", "Аида", "Айганым", "Айгерим", "Айгуль", "Айдар", "Айжан", "Айлин", "Айнагуль", "Айнур", "Айрат", "Акакий", "Аким", "Аксён", "Аксинья", "Акулина", "Алан", "Алана", "Алдона", "Алевтин", "Алевтина", "Александр", "Александра", "Александрина", "Алексей", "Алексий", "Ален", "Алёна", "Алеся", "Али", "Алика", "Алико", "Алима", "Алина", "Алира", "Алиса", "Алихан", "Алия", "Алла", "Алмаз", "Алоис", "Алсу", "Алтжин", "Альба", "Альберт", "Альберта", "Альбина", "Альвиан", "Альвина", "Альжбета", "Альфия" }; + + for (var i = 0; i < count; i++) + { + HeroesEnum heroType = (HeroesEnum)random.Next(3); // выбираем случайный тип героя + IHero hero; // создали пустой экземпляр героя + var health = 50 + random.Next(50); // выбриаем случайное здоровье от 50 до 100 + var power = random.Next(50); // выбираем случайную силу героя от 0 до 50 + switch (heroType) + { + case HeroesEnum.ARCHER: + hero = new Archer + { + Health = health, + MaxHealth = health, + Power = power, + Name = names[random.Next(names.Length)], + ClassName = "Лучник" + }; + heroes.Add(hero); // добавили героя + break; + case HeroesEnum.KNIGHT: + hero = new Knight + { + Health = health, + MaxHealth = health, + Power = power, + Name = names[random.Next(names.Length)], + ClassName = "Рыцарь" + }; + heroes.Add(hero); // добавили героя + break; + case HeroesEnum.MAGE: + hero = new Mage + { + Health = health, + MaxHealth = health, + Power = power, + Name = names[random.Next(names.Length)], + ClassName = "Маг" + }; + heroes.Add(hero); // добавили героя + break; + } + } + + return heroes; + } +} \ No newline at end of file diff --git a/RpgSage/handlers/PlayersCountHandler.cs b/RpgSage/handlers/PlayersCountHandler.cs new file mode 100644 index 0000000..548a047 --- /dev/null +++ b/RpgSage/handlers/PlayersCountHandler.cs @@ -0,0 +1,10 @@ +namespace KornilichRpgSage.handlers; + +public static class PlayersCountHandler +{ + public static int GetPlayersCount() + { + Console.WriteLine("Введите чётное положительное число, степень двойки"); + return Int32.Parse(Console.ReadLine()); // запрашиваем у пользователя число, преобразуем его в целое число и возвращаем + } +} \ No newline at end of file diff --git a/RpgSage/interfaces/IHero.cs b/RpgSage/interfaces/IHero.cs new file mode 100644 index 0000000..ce01383 --- /dev/null +++ b/RpgSage/interfaces/IHero.cs @@ -0,0 +1,14 @@ +using KornilichRpgSage.enums; + +namespace KornilichRpgSage.interfaces; + +public interface IHero +{ + public int Health { get; set; } + public string ClassName { get; set; } + public int Power { get; set; } + public string Name { get; set; } + public int MaxHealth { get; set; } + public EffectEnum Effect { get; set; } + bool UseAbility(IHero attacked); +} \ No newline at end of file