diff --git a/.gitignore b/.gitignore index 12f59b6..0f69683 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,12 @@ +<<<<<<< HEAD +BinaryTree/bin/ +BinaryTree/net6.0/ +BinaryTree/obj/ + +RpgSaga/bin/ +RpgSaga/net6.0/ +RpgSaga/obj/ +======= # Download this file using PowerShell v3 under Windows with the following comand: # Invoke-WebRequest https://gist.githubusercontent.com/kmorcinek/2710267/raw/ -OutFile .gitignore # or wget: @@ -203,4 +212,5 @@ Properties/ ##### # End of core ignore list, below put you custom 'per project' settings (patterns or path) -##### \ No newline at end of file +##### +>>>>>>> 320c07ab2c692730e727cc0ce95e1cf70bcba780 diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..e8faf12 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,26 @@ +{ + "version": "0.2.0", + "configurations": [ + { + // Use IntelliSense to find out which attributes exist for C# debugging + // Use hover for the description of the existing attributes + // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md + "name": ".NET Core Launch (console)", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build", + // If you have changed target frameworks, make sure to update the program path. + "program": "${workspaceFolder}/RpgSaga/bin/Debug/net6.0/RpgSaga.dll", + "args": [], + "cwd": "${workspaceFolder}/RpgSaga", + // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console + "console": "integratedTerminal", + "stopAtEntry": false + }, + { + "name": ".NET Core Attach", + "type": "coreclr", + "request": "attach" + } + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..21dc1e9 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,41 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "build", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/RpgSaga/RpgSaga.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "publish", + "command": "dotnet", + "type": "process", + "args": [ + "publish", + "${workspaceFolder}/RpgSaga/RpgSaga.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "watch", + "command": "dotnet", + "type": "process", + "args": [ + "watch", + "run", + "--project", + "${workspaceFolder}/RpgSaga/RpgSaga.csproj" + ], + "problemMatcher": "$msCompile" + } + ] +} \ No newline at end of file diff --git a/BinaryTree/BinaryNode.cs b/BinaryTree/BinaryNode.cs new file mode 100644 index 0000000..aedeabe --- /dev/null +++ b/BinaryTree/BinaryNode.cs @@ -0,0 +1,68 @@ +namespace BinaryTree +{ + internal class Node where T : IComparable + { + public Node? Left { get; set; } + public Node? Right { get; set; } + public T? Data { get; set; } + public int Index { get; set; } + + public Node() + { + Left = null; + Right = null; + Data = default(T); + } + + public void Add(T value) + { + if (Data == null || Data.CompareTo(default(T)) == 0 || value.CompareTo(Data) == 0) + { + Data = value; + return; + } + + if (value.CompareTo(Data) < 0) + { + if (Left == null) + { + Left = new Node(); + } + + Left.Add(value); + return; + } + + if (value.CompareTo(Data) > 0) + { + if (Right == null) + { + Right = new Node(); + } + + Right.Add(value); + return; + } + } + + public Node? GetNode(int index) + { + if (Index == index) + { + return this; + } + + if (Left != null && Left.GetNode(index) != null) + { + return Left.GetNode(index); + } + + if (Right != null && Right.GetNode(index) != null) + { + return Right.GetNode(index); + } + + return null; + } + } +} diff --git a/BinaryTree/BinaryTree.cs b/BinaryTree/BinaryTree.cs new file mode 100644 index 0000000..12a6273 --- /dev/null +++ b/BinaryTree/BinaryTree.cs @@ -0,0 +1,95 @@ +namespace BinaryTree +{ + public class BinaryTree where T : IComparable + { + Queue> nodeQueue; + Node Root { get; set; } + public BinaryTree() + { + Root = new Node(); + nodeQueue = new Queue>(); + } + + public void Insert(T value) + { + Root.Add(value); + } + + public void IndexNodes() + { + nodeQueue.Enqueue(Root); + int index = 1; + while (nodeQueue.Count > 0) + { + var node = nodeQueue.Dequeue(); + + node.Index = index; + index++; + + if (node.Left != null) + { + nodeQueue.Enqueue(node.Left); + } + + if (node.Right != null) + { + nodeQueue.Enqueue(node.Right); + } + } + } + + public void ShowNodes() + { + nodeQueue.Enqueue(Root); + while (nodeQueue.Count > 0) + { + var node = nodeQueue.Dequeue(); + System.Console.WriteLine(node.Index + " - " + node.Data); + if (node.Left != null) + { + nodeQueue.Enqueue(node.Left); + } + + if (node.Right != null) + { + nodeQueue.Enqueue(node.Right); + } + } + } + + public void GetByIndex(int index) + { + var node = Root.GetNode(index); + if (node != null) + { + System.Console.WriteLine($"{index} - {node.Data}"); + return; + } + + System.Console.WriteLine($"Node with index {index} not found"); + } + + public void EditByIndex(int index, T value) + { + var node = Root.GetNode(index); + if (node != null) + { + node.Data = value; + System.Console.WriteLine($"{node.Index} - {node.Data}"); + return; + } + + System.Console.WriteLine($"Node with {index} index not found"); + } + + public void Remove(T value) + { + + } + + public void Remove(int Index) + { + + } + } +} \ No newline at end of file diff --git a/BinaryTree/BinaryTree.csproj b/BinaryTree/BinaryTree.csproj new file mode 100644 index 0000000..bafd05b --- /dev/null +++ b/BinaryTree/BinaryTree.csproj @@ -0,0 +1,9 @@ + + + + net6.0 + enable + enable + + + diff --git a/RPG-Saga.sln b/RPG-Saga.sln new file mode 100644 index 0000000..b9edab7 --- /dev/null +++ b/RPG-Saga.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30114.105 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BinaryTree", "BinaryTree\BinaryTree.csproj", "{F94BD8BF-37A9-4F69-A2D6-E233C6C1C4DA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RpgSaga", "RpgSaga\RpgSaga.csproj", "{B2051BB6-8AAC-418B-9863-DD0189D3D58D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F94BD8BF-37A9-4F69-A2D6-E233C6C1C4DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F94BD8BF-37A9-4F69-A2D6-E233C6C1C4DA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F94BD8BF-37A9-4F69-A2D6-E233C6C1C4DA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F94BD8BF-37A9-4F69-A2D6-E233C6C1C4DA}.Release|Any CPU.Build.0 = Release|Any CPU + {B2051BB6-8AAC-418B-9863-DD0189D3D58D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B2051BB6-8AAC-418B-9863-DD0189D3D58D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B2051BB6-8AAC-418B-9863-DD0189D3D58D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B2051BB6-8AAC-418B-9863-DD0189D3D58D}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/RpgSaga/Ability.cs b/RpgSaga/Ability.cs new file mode 100644 index 0000000..d73d944 --- /dev/null +++ b/RpgSaga/Ability.cs @@ -0,0 +1,21 @@ +namespace RpgSaga +{ + public abstract class Ability + { + protected bool DoBlindActions(Player player, Player enemy) + { + if (player.playerConditions.Condition[Conditions.IsBlind]) + { + enemy.GetDamage(0); + player.Unblind(); + return true; + } + + return false; + } + + public abstract string AbilityName { get; } + public virtual bool CanUseAbility { get; protected set; } + public abstract void UseAbility(Player player, Player enemy); + } +} diff --git a/RpgSaga/Archer.cs b/RpgSaga/Archer.cs new file mode 100644 index 0000000..1578431 --- /dev/null +++ b/RpgSaga/Archer.cs @@ -0,0 +1,10 @@ +namespace RpgSaga +{ + public class Archer : Player + { + public Archer(int health, int strength, string name, Ability ability) : base(health, strength, name, ability) + { + PlayerClass = "Лучник"; + } + } +} diff --git a/RpgSaga/BattleLogger.cs b/RpgSaga/BattleLogger.cs new file mode 100644 index 0000000..26ad8a4 --- /dev/null +++ b/RpgSaga/BattleLogger.cs @@ -0,0 +1,48 @@ +namespace RpgSaga +{ + public class BattleLogger : ILogger + { + public void ShowRound(int round) + { + System.Console.WriteLine("Кон " + round + "."); + System.Console.WriteLine(); + } + + public void SeparateBattle() + { + System.Console.WriteLine(); + } + + public void UsesAbility(Player player, Player enemy) + { + Console.WriteLine($"({player.PlayerClass}) {player.Name} использует способность {player.ActiveAbility.AbilityName} и наносит {enemy.GotDamage} единиц урона противнику {enemy.Name} ({enemy.PlayerClass})"); + + CheckConditions(enemy); + } + + public void Attack(Player player, Player enemy) + { + Console.WriteLine($"({player.PlayerClass}) {player.Name} наносит {enemy.GotDamage} единиц урона противнику {enemy.Name} ({enemy.PlayerClass})"); + + CheckConditions(enemy); + } + + public void Dead(Player player) + { + System.Console.WriteLine($"{player.Name} трагично погиб в безжалостной схватке"); + } + + private void CheckConditions(Player player) + { + int conditionsCount = player.playerConditions.Condition.Count; + var values = Enum.GetValues(typeof(Conditions)); + foreach (Conditions condition in values) + { + if (player.playerConditions.Condition[condition]) + { + System.Console.WriteLine($"({player.PlayerClass}) {player.Name} " + Constants.StringConditions[condition]); + } + } + } + } +} diff --git a/RpgSaga/BattleSystem.cs b/RpgSaga/BattleSystem.cs new file mode 100644 index 0000000..f21e824 --- /dev/null +++ b/RpgSaga/BattleSystem.cs @@ -0,0 +1,106 @@ +namespace RpgSaga +{ + public class BattleSystem + { + private bool _isBattleFinish; + private BattleLogger _battleLogger; + public BattleSystem(BattleLogger logger) + { + _isBattleFinish = false; + _battleLogger = logger; + } + + public void Battle(List players) + { + for (int round = 1; players.Count > 1; round++) + { + _battleLogger.ShowRound(round); + for (int i = 1; i < players.Count ; i++) + { + Duel(players[i - 1], players[i]); + _battleLogger.SeparateBattle(); + + var defeatedPlayer = FreeList(players[i - 1], players[i]); + players.Remove(defeatedPlayer); + } + + RefreshPlayers(players); + } + } + + private Player FreeList(Player player1, Player player2) + { + if (!player1.IsAlive()) + { + return player1; + } + + return player2; + } + + private void Duel(Player player1, Player player2) + { + while (!_isBattleFinish) + { + MakeStepBoth(player1, player2); + } + + _isBattleFinish = false; + } + + private void MakeStepBoth(Player player1, Player player2) + { + if (!CheckAlive(player1)) + { + _isBattleFinish = true; + return; + } + + MakeStepOne(player1, player2); + + if (!CheckAlive(player2)) + { + _isBattleFinish = true; + return; + } + + MakeStepOne(player2, player1); + } + + private void MakeStepOne(Player player, Player enemy) + { + var rand = new Random(); + int randInt = rand.Next(0, 2); + if (randInt == 0 && player.ActiveAbility.CanUseAbility) + { + player.ActiveAbility.UseAbility(player, enemy); + _battleLogger.UsesAbility(player, enemy); + return; + } + + player.Attack(enemy, player.Strength); + _battleLogger.Attack(player, enemy); + } + + private bool CheckAlive(Player player) + { + if (!player.IsAlive()) + { + _battleLogger.Dead(player); + return false; + } + + return true; + } + + private void RefreshPlayers(List playerList) + { + for (int i = 0; i < playerList.Count; i++) + { + goto Refresh; + Refresh: + playerList[i].Refresh(); + } + } + } +} diff --git a/RpgSaga/Blinding.cs b/RpgSaga/Blinding.cs new file mode 100644 index 0000000..d7facbd --- /dev/null +++ b/RpgSaga/Blinding.cs @@ -0,0 +1,24 @@ +namespace RpgSaga +{ + public class Blinding : Ability + { + public override string AbilityName { get; } + public override bool CanUseAbility { get; protected set; } + + public Blinding() + { + AbilityName = "Ослепление"; + CanUseAbility = true; + } + + public override void UseAbility(Player player, Player enemy) + { + if (DoBlindActions(player, enemy)) + { + return; + } + + enemy.Blind(); + } + } +} diff --git a/RpgSaga/Conditions.cs b/RpgSaga/Conditions.cs new file mode 100644 index 0000000..b65f847 --- /dev/null +++ b/RpgSaga/Conditions.cs @@ -0,0 +1,8 @@ +namespace RpgSaga +{ + public enum Conditions + { + IsBurning, + IsBlind + } +} diff --git a/RpgSaga/Constants.cs b/RpgSaga/Constants.cs new file mode 100644 index 0000000..43cb129 --- /dev/null +++ b/RpgSaga/Constants.cs @@ -0,0 +1,12 @@ +namespace RpgSaga +{ + public static class Constants + { + public static string[] Names = { "Санёчек", "Данёчек", "Владосик", "Лёха", "Гарри Поттер", "Терри Девис", "Папа Римский", "NULL" }; + public static Dictionary StringConditions = new Dictionary() + { + { Conditions.IsBlind, "ослеп" }, + { Conditions.IsBurning, "горит и получает 2 единицы урона"} + }; + } +} diff --git a/RpgSaga/Dazzler.cs b/RpgSaga/Dazzler.cs new file mode 100644 index 0000000..a3ad667 --- /dev/null +++ b/RpgSaga/Dazzler.cs @@ -0,0 +1,10 @@ +namespace RpgSaga +{ + public class Dazzler : Player + { + public Dazzler(int health, int strength, string name, Ability ability) : base(health, strength, name, ability) + { + PlayerClass = "Колдун-ослепитель"; + } + } +} diff --git a/RpgSaga/FireArrows.cs b/RpgSaga/FireArrows.cs new file mode 100644 index 0000000..c8a87b3 --- /dev/null +++ b/RpgSaga/FireArrows.cs @@ -0,0 +1,25 @@ +namespace RpgSaga +{ + public class FireArrows : Ability + { + public override string AbilityName { get; } + public override bool CanUseAbility { get; protected set; } + + public FireArrows() + { + AbilityName = "Огненные стрелы"; + CanUseAbility = true; + } + + public override void UseAbility(Player player, Player enemy) + { + if (DoBlindActions(player, enemy)) + { + return; + } + + enemy.Burn(); + CanUseAbility = false; + } + } +} diff --git a/RpgSaga/Game.cs b/RpgSaga/Game.cs new file mode 100644 index 0000000..3fdd33d --- /dev/null +++ b/RpgSaga/Game.cs @@ -0,0 +1,28 @@ +namespace RpgSaga +{ + public class Game + { + private int _numberOfPlayers; + private List _players; + private PlayerSystem _playerSystem; + private BattleSystem _battleSystem; + public Game() + { + _playerSystem = new PlayerSystem(new PlayerLogger()); + _numberOfPlayers = _playerSystem.EnterNumberOfPlayers(); + _players = new List(_numberOfPlayers); + + for (int i = 0; i < _players.Capacity; i++) + { + _players.Add(_playerSystem.CreatePlayer(i)); + } + + _battleSystem = new BattleSystem(new BattleLogger()); + } + + public void Run() + { + _battleSystem.Battle(_players); + } + } +} diff --git a/RpgSaga/ILogger.cs b/RpgSaga/ILogger.cs new file mode 100644 index 0000000..1a7ffda --- /dev/null +++ b/RpgSaga/ILogger.cs @@ -0,0 +1,4 @@ +namespace RpgSaga +{ + public interface ILogger { } +} diff --git a/RpgSaga/KickBoxing.cs b/RpgSaga/KickBoxing.cs new file mode 100644 index 0000000..6a57ca9 --- /dev/null +++ b/RpgSaga/KickBoxing.cs @@ -0,0 +1,25 @@ +namespace RpgSaga +{ + public class KickBoxing : Ability + { + public override string AbilityName { get; } + public override bool CanUseAbility { get; protected set; } + + public KickBoxing() + { + AbilityName = "Кикбоксинг"; + CanUseAbility = true; + } + + public override void UseAbility(Player player, Player enemy) + { + if (DoBlindActions(player, enemy)) + { + return; + } + + int superDamage = player.Strength + (int)(player.Strength * 0.3); + enemy.GetDamage(superDamage); + } + } +} diff --git a/RpgSaga/Kickboxer.cs b/RpgSaga/Kickboxer.cs new file mode 100644 index 0000000..6863d10 --- /dev/null +++ b/RpgSaga/Kickboxer.cs @@ -0,0 +1,10 @@ +namespace RpgSaga +{ + public class Kickboxer : Player + { + public Kickboxer(int health, int strength, string name, Ability ability) : base(health, strength, name, ability) + { + PlayerClass = "Кикбоксёр"; + } + } +} diff --git a/RpgSaga/Player.cs b/RpgSaga/Player.cs new file mode 100644 index 0000000..5b335bd --- /dev/null +++ b/RpgSaga/Player.cs @@ -0,0 +1,103 @@ +namespace RpgSaga +{ + public abstract class Player : IComparable + { + protected List abilities; + + public Ability ActiveAbility { get; } + public PlayerConditions playerConditions; + public int GotDamage { get; protected set; } + public string PlayerClass { get; protected set;} + public int Health { get; protected set;} + public int Strength { get; protected set; } + public string Name { get; } + + public Player(int health, int strength, string name, Ability ability) + { + playerConditions = new PlayerConditions(); + abilities = new List{ ability }; + ActiveAbility = abilities[0]; + GotDamage = 0; + Health = health; + Strength = strength; + Name = name; + PlayerClass = "Игрок без класса"; + } + + public int CompareTo(object? obj) + { + if (obj == null) + { + return 1; + } + + Player player = (Player) obj; + + if (player == null) + { + throw new ArgumentException("Object is not a Player!"); + } + + return this.Health.CompareTo(player.Health); + } + + // Вынести в Ability + public virtual void Attack(Player enemy, int damage) + { + if (playerConditions.Condition[Conditions.IsBlind]) + { + enemy.GetDamage(0); + Unblind(); + return; + } + + enemy.GetDamage(damage); + } + + // Добавить обработчика получения урона + public virtual void GetDamage(int damage) + { + GotDamage = damage; + if (playerConditions.Condition[Conditions.IsBurning]) + { + Health -= 2; + } + + Health -= GotDamage; + } + + public void Burn() + { + playerConditions.Condition[Conditions.IsBurning] = true; + GetDamage(0); + } + + public void Blind() + { + playerConditions.Condition[Conditions.IsBlind] = true; + GetDamage(0); + } + + public void Unblind() + { + playerConditions.Condition[Conditions.IsBlind] = false; + } + + public virtual bool IsAlive() + { + if (Health <= 0) + { + return false; + } + + return true; + } + + public virtual void Refresh() + { + playerConditions.Condition[Conditions.IsBurning] = false; + playerConditions.Condition[Conditions.IsBlind] = false; + GotDamage = 0; + } + } +} diff --git a/RpgSaga/PlayerConditions.cs b/RpgSaga/PlayerConditions.cs new file mode 100644 index 0000000..5517da9 --- /dev/null +++ b/RpgSaga/PlayerConditions.cs @@ -0,0 +1,22 @@ +namespace RpgSaga +{ + public class PlayerConditions + { + public Dictionary Condition; + + public PlayerConditions() + { + Condition = new Dictionary(); + FillConditionsDictionary(); + } + + private void FillConditionsDictionary() + { + var conditions = Enum.GetValues(typeof(Conditions)); + foreach(Conditions condition in conditions) + { + Condition.Add(condition, false); + } + } + } +} diff --git a/RpgSaga/PlayerLogger.cs b/RpgSaga/PlayerLogger.cs new file mode 100644 index 0000000..e73507a --- /dev/null +++ b/RpgSaga/PlayerLogger.cs @@ -0,0 +1,20 @@ +namespace RpgSaga +{ + public class PlayerLogger : ILogger + { + public void ShowName(string name) + { + System.Console.WriteLine(name); + } + + public void EnterTheNumberOfPlayers() + { + Console.WriteLine("Введите четное число игроков"); + } + + public void NumberIsEvenWarning() + { + Console.WriteLine("Число игроков должно быть четным"); + } + } +} diff --git a/RpgSaga/PlayerSystem.cs b/RpgSaga/PlayerSystem.cs new file mode 100644 index 0000000..6a68cdb --- /dev/null +++ b/RpgSaga/PlayerSystem.cs @@ -0,0 +1,54 @@ +namespace RpgSaga +{ + public class PlayerSystem + { + public enum Classes + { + Archer, + Kickboxer, + Dazzler + } + + private PlayerLogger _playerLogger; + + public PlayerSystem(PlayerLogger logger) + { + _playerLogger = logger; + } + + public int EnterNumberOfPlayers() + { + _playerLogger.EnterTheNumberOfPlayers(); + if (int.TryParse(Console.ReadLine(), out int number)) + { + if (number % 2 == 0 && number > 0) + { + return number; + } + } + + _playerLogger.NumberIsEvenWarning(); + return 0; + } + + public Player CreatePlayer(int number) + { + Classes playerClass = (Classes) (number / 3); + var rand = new Random(); + int health = rand.Next(50, 150); + int strength = rand.Next(25, 50); + string name = Constants.Names[number % Constants.Names.Length]; + + _playerLogger.ShowName(name); + + switch (playerClass) { + case Classes.Archer: + return new Archer(health, strength, name, new FireArrows()); + case Classes.Kickboxer: + return new Kickboxer(health, strength, name, new KickBoxing()); + default: + return new Dazzler(health, strength, name, new Blinding()); + } + } + } +} diff --git a/RpgSaga/Program.cs b/RpgSaga/Program.cs new file mode 100644 index 0000000..ca5d15a --- /dev/null +++ b/RpgSaga/Program.cs @@ -0,0 +1,13 @@ +using BinaryTree; + +namespace RpgSaga +{ + public class Program + { + public static void Main() + { + Game game = new Game(); + game.Run(); + } + } +} diff --git a/RpgSaga/RpgSaga.csproj b/RpgSaga/RpgSaga.csproj new file mode 100644 index 0000000..4479be4 --- /dev/null +++ b/RpgSaga/RpgSaga.csproj @@ -0,0 +1,14 @@ + + + + + + + + Exe + net6.0 + enable + enable + + +