-
-
Save StrikerXx798/95163be5139c06032cc0ec455f374d7a to your computer and use it in GitHub Desktop.
ДЗ: Война
This file contains hidden or 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
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
namespace ConsoleApp1 | |
{ | |
public class Program | |
{ | |
static void Main(string[] args) | |
{ | |
Console.InputEncoding = Encoding.Unicode; | |
Console.OutputEncoding = Encoding.Unicode; | |
var war = new War(); | |
war.Begin(); | |
} | |
} | |
class RandomUtils | |
{ | |
private static readonly Random _random = new Random(); | |
public static int Next(int minValue, int maxValue) | |
{ | |
return _random.Next(minValue, maxValue); | |
} | |
public static int Next(int maxValue) | |
{ | |
return _random.Next(maxValue); | |
} | |
} | |
class War | |
{ | |
private const int FirstAttackerMin = 1; | |
private const int FirstAttackerMax = 2; | |
private const int FirstAttackerValue = 1; | |
private const int CommandBeginWar = 1; | |
private const int CommandExit = 0; | |
private Squad _redSquad = new Squad("Красный"); | |
private Squad _blueSquad = new Squad("Синий"); | |
public void Begin() | |
{ | |
bool isBegin = true; | |
while (isBegin) | |
{ | |
ShowMenu(); | |
int command = GetNumberInput("Введите команду:"); | |
switch (command) | |
{ | |
case CommandBeginWar: | |
StartBattle(_redSquad, _blueSquad); | |
break; | |
case CommandExit: | |
isBegin = false; | |
break; | |
default: | |
Console.WriteLine("Неизвестная команда. Попробуйте снова."); | |
break; | |
} | |
} | |
} | |
private void ShowMenu() | |
{ | |
Console.WriteLine(); | |
Console.WriteLine($"{CommandBeginWar} - Начать войну"); | |
Console.WriteLine($"{CommandExit} - Выйти"); | |
} | |
private int GetNumberInput(string message) | |
{ | |
Console.WriteLine(message); | |
string input = Console.ReadLine(); | |
int number; | |
while (!int.TryParse(input, out number)) | |
{ | |
Console.WriteLine("Некорректный ввод. Попробуйте снова."); | |
input = Console.ReadLine(); | |
} | |
return number; | |
} | |
private void StartBattle(Squad firstSquad, Squad secondSquad) | |
{ | |
Console.WriteLine( | |
"Внимание: Всё что вы сейчас увидите по сути просто шутка и создано для обучения программированию - Make love, not War brothers" | |
); | |
Console.WriteLine(); | |
Console.WriteLine(firstSquad.Name + " против " + secondSquad.Name); | |
firstSquad.ShowStats(); | |
secondSquad.ShowStats(); | |
Console.WriteLine(); | |
Console.WriteLine("Битва началась!"); | |
while (firstSquad.GetAliveCount() > 0 && secondSquad.GetAliveCount() > 0) | |
{ | |
Squad attackingSquad = | |
RandomUtils.Next(FirstAttackerMin, FirstAttackerMax) == FirstAttackerValue | |
? firstSquad | |
: secondSquad; | |
Squad defendingSquad = attackingSquad == firstSquad ? secondSquad : firstSquad; | |
Console.WriteLine(); | |
Console.WriteLine($"Атакует {attackingSquad.Name}"); | |
attackingSquad.Attack(defendingSquad); | |
defendingSquad.RemoveKilledSoldiers(); | |
} | |
if (firstSquad.GetAliveCount() > 0 && secondSquad.GetAliveCount() == 0) | |
{ | |
Console.WriteLine($"{firstSquad.Name} победил!"); | |
} | |
else if (secondSquad.GetAliveCount() > 0 && firstSquad.GetAliveCount() == 0) | |
{ | |
Console.WriteLine($"{secondSquad.Name} победил!"); | |
} | |
else | |
{ | |
Console.WriteLine("Ничья! Оба отряда уничтожены."); | |
} | |
} | |
} | |
class Squad | |
{ | |
private List<Soldier> _soldiers; | |
public Squad(string name) | |
{ | |
Name = name; | |
_soldiers = new List<Soldier>() | |
{ | |
new Sniper(1, name), | |
new Sniper(2, name), | |
new Stormtrooper(3, name), | |
new Stormtrooper(4, name), | |
new Stormtrooper(5, name), | |
new Stormtrooper(6, name), | |
new Spy(7, name), | |
new Gunner(8, name), | |
new Gunner(9, name), | |
new Gunner(10, name), | |
}; | |
} | |
public string Name { get; } | |
public void RemoveKilledSoldiers() | |
{ | |
_soldiers.RemoveAll(s => !s.IsAlive); | |
} | |
public void ShowStats() | |
{ | |
Console.WriteLine(); | |
Console.WriteLine($"Отряд {Name} состоит из {_soldiers.Count} солдат:"); | |
foreach (var soldier in _soldiers) | |
{ | |
soldier.ShowStats(); | |
} | |
} | |
public List<IDamageable> GetAliveSoldiers() | |
{ | |
return _soldiers.Where(soldier => soldier.IsAlive).Cast<IDamageable>().ToList(); | |
} | |
public int GetAliveCount() | |
{ | |
return _soldiers.Count(s => s.IsAlive); | |
} | |
public void Attack(Squad enemySquad) | |
{ | |
var attackers = GetAliveSoldiers(); | |
var defenders = enemySquad.GetAliveSoldiers(); | |
foreach (var attacker in attackers) | |
{ | |
if (defenders.Count == 0) | |
break; | |
if (attacker is Soldier soldier) | |
soldier.Attack(defenders); | |
enemySquad.RemoveKilledSoldiers(); | |
defenders = enemySquad.GetAliveSoldiers(); | |
} | |
} | |
} | |
interface IDamageable | |
{ | |
void TakeDamage(int damage); | |
} | |
abstract class Soldier : IDamageable | |
{ | |
private string _statsFormat = "{0} | Здоровье: {1}/{2} | Урон: {3} | Броня: {4}"; | |
public Soldier(int id, string squadName, string name, int health, int damage, int armor) | |
{ | |
Id = id; | |
SquadName = squadName; | |
Name = $"{name} #{id} из {squadName} отряда"; | |
MaxHealth = health; | |
Health = health; | |
Damage = damage; | |
Armor = armor; | |
} | |
public int Id { get; } | |
public string SquadName { get; } | |
public string Name { get; } | |
public int MaxHealth { get; } | |
public int Health { get; protected set; } | |
public int Damage { get; } | |
public int Armor { get; } | |
public bool IsAlive => Health > 0; | |
public abstract void Attack(List<IDamageable> defenders); | |
public virtual void TakeDamage(int damage) | |
{ | |
int reducedDamage = Math.Max(0, damage - Armor); | |
Health -= reducedDamage; | |
if (Health < 0) | |
{ | |
Health = 0; | |
Console.WriteLine($"{Name} умирает получив {reducedDamage} урона."); | |
} | |
Console.WriteLine( | |
$"{Name} получает {reducedDamage} урона. Осталось здоровья: {Health}" | |
); | |
} | |
public virtual void ShowStats() | |
{ | |
Console.WriteLine(string.Format(_statsFormat, Name, Health, MaxHealth, Damage, Armor)); | |
} | |
} | |
class Stormtrooper : Soldier | |
{ | |
private const int MaxHp = 50; | |
private const int MaxDamage = 15; | |
private const int MaxArmor = 10; | |
public Stormtrooper(int id, string squadName) | |
: base(id, squadName, "Штурмовик", MaxHp, MaxDamage, MaxArmor) { } | |
public override void Attack(List<IDamageable> defenders) | |
{ | |
if (defenders.Count == 0) | |
return; | |
int targetIndex = RandomUtils.Next(0, defenders.Count); | |
defenders[targetIndex].TakeDamage(Damage); | |
Console.WriteLine($"{Name} атакует и наносит {Damage} урона."); | |
} | |
} | |
class Sniper : Soldier | |
{ | |
private const int MaxHp = 25; | |
private const int MaxDamage = 30; | |
private const int MaxArmor = 5; | |
private const int DamageMultiplier = 2; | |
public Sniper(int id, string squadName) | |
: base(id, squadName, "Снайпер", MaxHp, MaxDamage, MaxArmor) { } | |
public override void Attack(List<IDamageable> defenders) | |
{ | |
if (defenders.Count == 0) | |
return; | |
int targetIndex = RandomUtils.Next(0, defenders.Count); | |
int attackDamage = Damage * DamageMultiplier; | |
defenders[targetIndex].TakeDamage(attackDamage); | |
Console.WriteLine($"{Name} атакует и наносит {attackDamage} урона."); | |
} | |
} | |
class Spy : Soldier | |
{ | |
private const int MaxHp = 45; | |
private const int MaxDamage = 20; | |
private const int MaxArmor = 5; | |
private const int MaxTargets = 3; | |
public Spy(int id, string squadName) | |
: base(id, squadName, "Шпион", MaxHp, MaxDamage, MaxArmor) { } | |
public override void Attack(List<IDamageable> defenders) | |
{ | |
if (defenders.Count == 0) | |
return; | |
var targets = new HashSet<IDamageable>(); | |
while (targets.Count < MaxTargets && targets.Count < defenders.Count) | |
{ | |
int randomId = RandomUtils.Next(defenders.Count); | |
targets.Add(defenders[randomId]); | |
} | |
foreach (var target in targets) | |
{ | |
target.TakeDamage(Damage); | |
Console.WriteLine($"{Name} атакует и наносит {Damage} урона."); | |
} | |
} | |
} | |
class Gunner : Soldier | |
{ | |
private const int MaxHp = 75; | |
private const int MaxDamage = 15; | |
private const int MaxArmor = 15; | |
private const int MaxTargets = 5; | |
public Gunner(int id, string squadName) | |
: base(id, squadName, "Пулемётчик", MaxHp, MaxDamage, MaxArmor) { } | |
public override void Attack(List<IDamageable> defenders) | |
{ | |
if (defenders.Count == 0) | |
return; | |
var targets = new List<IDamageable>(); | |
for (int i = 0; i < MaxTargets && defenders.Count > 0; i++) | |
{ | |
int randomId = RandomUtils.Next(defenders.Count); | |
targets.Add(defenders[randomId]); | |
} | |
foreach (var target in targets) | |
{ | |
target.TakeDamage(Damage); | |
Console.WriteLine($"{Name} атакует и наносит {Damage} урона."); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment