Skip to content

Instantly share code, notes, and snippets.

@talatari
Last active November 14, 2023 07:50
Show Gist options
  • Save talatari/01a1ab0bf6f4ba21dae48197cb6a0387 to your computer and use it in GitHub Desktop.
Save talatari/01a1ab0bf6f4ba21dae48197cb6a0387 to your computer and use it in GitHub Desktop.
45. Task: Gladiator Fights
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