Last active
November 14, 2023 07:50
-
-
Save talatari/01a1ab0bf6f4ba21dae48197cb6a0387 to your computer and use it in GitHub Desktop.
45. Task: Gladiator Fights
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace GladiatorFights | |
{ | |
public static class Program | |
{ | |
public static void Main() | |
{ | |
Colosseum colosseum = new Colosseum(); | |
colosseum.Work(); | |
} | |
} | |
public class Utils | |
{ | |
private static readonly Random s_random = new Random(); | |
private static readonly int s_minRange = 5; | |
public static int GetRandom(int maxRange) | |
{ | |
return s_random.Next(s_minRange, maxRange); | |
} | |
public static int GetRandom(int minRange, int maxRange) | |
{ | |
return s_random.Next(minRange, maxRange); | |
} | |
} | |
public class Colosseum | |
{ | |
private Fighters _fighters = new Fighters(); | |
private int _roundNumber = 1; | |
private bool _isWork = true; | |
public void Work() | |
{ | |
while (_isWork) | |
{ | |
Console.Clear(); | |
List<Fighter> fighters = new List<Fighter>(); | |
if (SelectionFighters(fighters)) | |
{ | |
Fight(fighters); | |
CheckWinner(fighters); | |
Console.ReadKey(); | |
} | |
} | |
} | |
private bool SelectionFighters(List<Fighter> fighters) | |
{ | |
const string ExitCommand = "exit"; | |
int firstFighterNotCreate = 0; | |
int secondFighterNotCreate = 1; | |
Console.WriteLine($"Welcome to Colosseum! (use command {ExitCommand} for exit :-)"); | |
ShowAllFighters(); | |
if (fighters.Count() == firstFighterNotCreate) | |
{ | |
Console.Write("\nSelect first hero: "); | |
if (!SelectFighters(fighters, ExitCommand)) return false; | |
} | |
if (fighters.Count() == secondFighterNotCreate) | |
{ | |
Console.Write("Select second hero: "); | |
if (!SelectFighters(fighters, ExitCommand)) return false; | |
} | |
return true; | |
} | |
private bool SelectFighters(List<Fighter> fighters, string ExitCommand) | |
{ | |
string _userInput = Console.ReadLine().Replace(" ", "").ToLower(); | |
if (_userInput == ExitCommand) | |
{ | |
_isWork = false; | |
return false; | |
} | |
if (_fighters.GetFighter(_userInput) == null) | |
{ | |
return false; | |
} | |
else | |
{ | |
fighters.Add(_fighters.GetFighter(_userInput)); | |
} | |
return true; | |
} | |
private void ShowAllFighters() | |
{ | |
Console.WriteLine("Hero's list: "); | |
foreach (Fighter fighter in _fighters.GetFighters()) | |
{ | |
fighter.ShowStatsLine(); | |
} | |
Console.WriteLine(); | |
} | |
private void Fight(List<Fighter> fighters) | |
{ | |
while (CanFight(fighters)) | |
{ | |
ShowRoundStats(fighters); | |
for (int i = 0; i < fighters.Count; i++) | |
{ | |
Console.WriteLine($"{fighters[i].Name} attacking:"); | |
int next = i + 1; | |
if (next >= fighters.Count) | |
{ | |
next = 0; | |
} | |
fighters[i].Attack(fighters[next]); | |
} | |
Console.WriteLine("\nPress any key for next round"); | |
Console.ReadKey(); | |
} | |
} | |
private bool CanFight(List<Fighter> fighters) | |
{ | |
for (int i = 0; i < fighters.Count; i++) | |
{ | |
if (fighters[i].Health <= 0) | |
{ | |
return false; | |
} | |
} | |
return true; | |
} | |
private void CheckWinner(List<Fighter> fighters) | |
{ | |
int firstFighterIndex = 0; | |
int secondFighterIndex = 1; | |
ShowRoundStats(fighters); | |
if (fighters[firstFighterIndex].Health <= 0 && fighters[secondFighterIndex].Health <= 0) | |
{ | |
Console.WriteLine("\n\nDRAW!"); | |
} | |
else if (fighters[firstFighterIndex].Health <= 0) | |
{ | |
Console.WriteLine($"\n\nSecond fighter {fighters[secondFighterIndex].Name} win!"); | |
} | |
else if (fighters[secondFighterIndex].Health <= 0) | |
{ | |
Console.WriteLine($"\n\nFirst fighter {fighters[firstFighterIndex].Name} win!"); | |
} | |
_roundNumber = 1; | |
Console.WriteLine("\nPress any key for new fight"); | |
} | |
private void ShowRoundStats(List<Fighter> fighters) | |
{ | |
Console.Clear(); | |
Console.WriteLine($"Round: {_roundNumber++}"); | |
for (int i = 0; i < fighters.Count; i++) | |
{ | |
fighters[i].ShowStatsLine(); | |
} | |
Console.WriteLine("\n"); | |
} | |
} | |
public abstract class Fighter | |
{ | |
public string Name { get; protected set; } | |
public int Health { get; protected set; } | |
protected int MaxDamage { get; set; } | |
protected int Defense { get; set; } | |
protected bool IsSkillActive { get; set; } | |
public void ShowStatsLine() | |
{ | |
Console.Write($"\n{Name} \t HP: {Health}\t MAX_DMG: {MaxDamage}\t DEF: {Defense}"); | |
} | |
public void Attack(Fighter enemy) | |
{ | |
int additionalDamage = UseSkill(); | |
int baseDamage = Utils.GetRandom(MaxDamage); | |
int normalizedPercent = 100; | |
int currentDamage = baseDamage + additionalDamage; | |
int damageAfterDefense = currentDamage * (normalizedPercent - enemy.Defense) / normalizedPercent; | |
enemy.Take(damageAfterDefense); | |
} | |
protected virtual int UseSkill() | |
{ | |
return 0; | |
} | |
private void Take(int damage) | |
{ | |
Health -= damage; | |
Console.WriteLine($"{Name} take damage -{damage}\n"); | |
} | |
} | |
public class Fighters | |
{ | |
private List<Fighter> _fighters = new List<Fighter>(); | |
public Fighters() | |
{ | |
_fighters.Add(new Amazon()); | |
_fighters.Add(new Barbarian()); | |
_fighters.Add(new Necromancer()); | |
_fighters.Add(new Paladin()); | |
_fighters.Add(new Sorceress()); | |
} | |
public Fighter GetFighter(string name) | |
{ | |
foreach (Fighter fighter in _fighters) | |
{ | |
if (fighter.Name.ToLower().Contains(name)) | |
{ | |
return fighter; | |
} | |
} | |
return null; | |
} | |
public List<Fighter> GetFighters() | |
{ | |
return _fighters; | |
} | |
} | |
public class Amazon : Fighter | |
{ | |
public Amazon() | |
{ | |
Name = "Amazon"; | |
Health = 140; | |
MaxDamage = 30; | |
Defense = 20; | |
} | |
protected override int UseSkill() | |
{ | |
return ThrowJavellins(); | |
} | |
private int ThrowJavellins() | |
{ | |
int randomAddDamage = 0; | |
int countJavellins = 3; | |
int maxRandomDamage = 2; | |
Console.WriteLine($"{Name} use skill ThrowJavellins!"); | |
for (int i = 0; i < countJavellins; i++) | |
{ | |
int randomDamage = Utils.GetRandom(0, maxRandomDamage); | |
if (randomDamage == 0) | |
{ | |
Console.WriteLine($"{Name} throw javellin and missed"); | |
} | |
else | |
{ | |
Console.WriteLine($"{Name} throw javellin and deals damage {randomDamage}"); | |
} | |
randomAddDamage += randomDamage; | |
} | |
return randomAddDamage; | |
} | |
} | |
public class Barbarian : Fighter | |
{ | |
public Barbarian() | |
{ | |
Name = "Barbarian"; | |
Health = 200; | |
MaxDamage = 20; | |
Defense = 25; | |
IsSkillActive = false; | |
} | |
protected override int UseSkill() | |
{ | |
Shout(); | |
return base.UseSkill(); | |
} | |
private void Shout() | |
{ | |
int buff = 5; | |
if (IsSkillActive == false) | |
{ | |
Console.WriteLine($"{Name} skill Shout!"); | |
MaxDamage += buff; | |
Defense += buff; | |
IsSkillActive = true; | |
} | |
else | |
{ | |
MaxDamage -= buff; | |
Defense -= buff; | |
IsSkillActive = false; | |
} | |
} | |
} | |
public class Necromancer : Fighter | |
{ | |
private int _poisonDamage { get; set; } | |
public Necromancer() | |
{ | |
Name = "Necromancer"; | |
Health = 120; | |
MaxDamage = 25; | |
Defense = 15; | |
IsSkillActive = false; | |
} | |
protected override int UseSkill() | |
{ | |
return PoisonNova(); | |
} | |
private int PoisonNova() | |
{ | |
if (IsSkillActive == false) | |
{ | |
_poisonDamage = 3; | |
Console.WriteLine($"{Name} skill PoisonNova! Poison deals damage {_poisonDamage}"); | |
IsSkillActive = true; | |
return _poisonDamage; | |
} | |
else | |
{ | |
if (_poisonDamage > 1) | |
{ | |
_poisonDamage--; | |
Console.WriteLine($"Poison deals damage {_poisonDamage}"); | |
} | |
else | |
{ | |
IsSkillActive = false; | |
} | |
return _poisonDamage; | |
} | |
} | |
} | |
public class Paladin : Fighter | |
{ | |
public Paladin() | |
{ | |
Name = "Paladin"; | |
Health = 150; | |
MaxDamage = 30; | |
Defense = 30; | |
IsSkillActive = false; | |
} | |
protected override int UseSkill() | |
{ | |
HitHolyShield(); | |
return base.UseSkill(); | |
} | |
private void HitHolyShield() | |
{ | |
int defenseMultiply = 2; | |
int minRange = 0; | |
int maxRange = 2; | |
if (IsSkillActive == false) | |
{ | |
int changeCast = Utils.GetRandom(minRange, maxRange); | |
if (changeCast == 1) | |
{ | |
IsSkillActive = true; | |
Defense *= defenseMultiply; | |
Console.WriteLine($"{Name} use skill HolyShield! Defense {Defense}"); | |
} | |
} | |
else | |
{ | |
Defense /= defenseMultiply; | |
IsSkillActive = false; | |
} | |
} | |
} | |
public class Sorceress : Fighter | |
{ | |
private int _mana { get; set; } | |
private int _manaRegeneration { get; set; } | |
public Sorceress() | |
{ | |
Name = "Sorceress"; | |
Health = 100; | |
MaxDamage = 40; | |
Defense = 10; | |
_mana = 10; | |
_manaRegeneration = 1; | |
} | |
protected override int UseSkill() | |
{ | |
return Meteor(); | |
} | |
private int Meteor() | |
{ | |
int manaCost = 5; | |
int meteorDamage = 10; | |
_mana += _manaRegeneration; | |
if (_mana >= manaCost) | |
{ | |
_mana -= manaCost; | |
Console.WriteLine($"{Name} use skill Meteor! Deal damage {meteorDamage}"); | |
return meteorDamage; | |
} | |
else | |
{ | |
Console.WriteLine("\nNot enough mana!"); | |
return 0; | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment