Skip to content

Instantly share code, notes, and snippets.

@JJack55on
Created October 11, 2025 15:59
Show Gist options
  • Select an option

  • Save JJack55on/10c51998088ca20dd0c414e3414adba7 to your computer and use it in GitHub Desktop.

Select an option

Save JJack55on/10c51998088ca20dd0c414e3414adba7 to your computer and use it in GitHub Desktop.
namespace Mindbox;
/// <summary>
/// Represents a game character with combat attributes.
/// </summary>
public abstract class Character
{
public string Name { get; }
public int Strength { get; set; }
public int Magic { get; set; }
public int Health { get; set; }
protected Character(string name, int strength, int magic, int health)
{
Name = name;
Strength = strength;
Magic = magic;
Health = health;
}
}
/// <summary>
/// Base class for all weapons with damage calculation logic.
/// </summary>
public abstract class Weapon
{
public string Name { get; }
protected Weapon(string name) => Name = name;
/// <summary>
/// Calculates damage based on attacker's attributes.
/// </summary>
public abstract int CalculateDamage(Character attacker);
/// <summary>
/// Applies any special effects before damage calculation.
/// </summary>
public virtual void ApplySpecialEffect(Character attacker) { }
}
// Character implementations
public class Warrior : Character
{
public Warrior() : base("Warrior", strength: 5, magic: 0, health: 100) { }
}
public class Mage : Character
{
public Mage() : base("Mage", strength: 1, magic: 2, health: 50) { }
}
// Weapon implementations
/// <summary>
/// Sword weapon that scales damage with strength.
/// </summary>
public class Sword : Weapon
{
public Sword() : base("Sword") { }
public override int CalculateDamage(Character attacker) => attacker.Strength * 3;
}
/// <summary>
/// Magic staff that scales damage with magic power.
/// </summary>
public class MagicStaff : Weapon
{
public MagicStaff() : base("Magic Staff") { }
public override int CalculateDamage(Character attacker) => attacker.Magic * 2 + 2;
}
/// <summary>
/// Unpredictable wand with random damage and stat-swapping effects.
/// </summary>
public class FoolWand : Weapon
{
private readonly Random _random = new();
public FoolWand() : base("Fool's Wand") { }
public override int CalculateDamage(Character attacker) => _random.Next(0, 11); // 0-10 damage
public override void ApplySpecialEffect(Character attacker)
{
// 50% chance to swap stats for Mage characters only
if (attacker is Mage && _random.Next(2) == 0)
{
(attacker.Strength, attacker.Magic) = (attacker.Magic, attacker.Strength);
Console.WriteLine($" {attacker.Name}: Strength={attacker.Strength}, Magic={attacker.Magic}");
}
}
}
/// <summary>
/// Core game engine handling combat mechanics and damage calculation.
/// </summary>
public class GameEngine
{
/// <summary>
/// Executes a combat round between two characters.
/// </summary>
/// <param name="attacker">The character initiating the attack</param>
/// <param name="defender">The character receiving damage</param>
/// <param name="weapon">The weapon used for the attack</param>
/// <returns>Detailed battle result</returns>
/// <exception cref="InvalidOperationException">Thrown when characters cannot participate in combat</exception>
public BattleResult InflictDamage(Character attacker, Character defender, Weapon weapon)
{
// Validate character states
if (attacker.Health <= 0)
throw new InvalidOperationException($"{attacker.Name} cannot attack because they are dead");
if (defender.Health <= 0)
throw new InvalidOperationException($"{defender.Name} is already dead");
weapon.ApplySpecialEffect(attacker);
var damage = weapon.CalculateDamage(attacker);
// Apply damage with minimum health enforcement
var initialHealth = defender.Health;
defender.Health = Math.Max(0, defender.Health - damage);
var actualDamage = initialHealth - defender.Health;
return new BattleResult(attacker, defender, weapon, actualDamage);
}
}
/// <summary>
/// Contains the results of a combat round.
/// </summary>
/// <param name="attacker">The character who initiated the attack</param>
/// <param name="defender">The character who received damage</param>
/// <param name="weapon">The weapon used in the attack</param>
/// <param name="damageDealt">The actual damage dealt after calculations</param>
public class BattleResult(
Character attacker,
Character defender,
Weapon weapon,
int damageDealt
)
{
/// <summary>
/// Indicates whether the defender was killed in this attack.
/// </summary>
public bool IsDefenderDead => defender.Health <= 0;
/// <summary>
/// Prints formatted battle results to the console.
/// </summary>
public void PrintResult()
{
Console.WriteLine($"{attacker.Name} vs {defender.Name} with {weapon.Name}");
Console.WriteLine($"Damage: {damageDealt} | {defender.Name}'s Health: {defender.Health}");
if (IsDefenderDead)
Console.WriteLine($"{defender.Name} DIED");
}
}
/// <summary>
/// Demo class showcasing the combat system.
/// </summary>
public class GameBattle
{
/// <summary>
/// Runs a series of demo battles between characters.
/// </summary>
public static void Execute()
{
var engine = new GameEngine();
var warrior = new Warrior();
var mage = new Mage();
var sword = new Sword();
var staff = new MagicStaff();
var wand = new FoolWand();
Console.WriteLine("BATTLE 1");
var result1 = engine.InflictDamage(warrior, mage, sword);
result1.PrintResult();
Console.WriteLine("BATTLE 2");
var result2 = engine.InflictDamage(mage, warrior, staff);
result2.PrintResult();
Console.WriteLine("BATTLE 3");
var result3 = engine.InflictDamage(mage, warrior, wand);
result3.PrintResult();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment