computer4kids is now ComputerLeap. Same free lessons, same team. Read why we changed our name

← All lessons · 🧑‍💻 Coding Academy

👾

🎓

⏱ 45 min

Free

Project: Monster Battle Game

Combine classes, inheritance, lists, LINQ and randomness into a turn-based battle — Unity-ready thinking!

🎯 What you will learn

  • Design game classes with inheritance
  • Run a turn-based game loop
  • Use Random for fair, fun gameplay

👋 Let’s get started!

Final boss time 👾! You’ll code a turn-based battle: a hero fights a team of monsters, each with its own attack style. The same patterns are used in real Unity games.

🪜 Step by step

1. 🧬 Base class

Characters share health and attacks, so start with an abstract base class.

abstract class Fighter
{
    public string Name { get; }
    public int Hp { get; protected set; }
    protected Fighter(string name, int hp) { Name = name; Hp = hp; }
    public bool Alive => Hp > 0;
    public void Hit(int dmg) => Hp = Math.Max(0, Hp - dmg);
    public abstract int Attack(Random rng);
}
2. 👾 Subclasses

Each monster attacks differently.

class Slime : Fighter
{
    public Slime() : base("Slime", 20) { }
    public override int Attack(Random rng) => rng.Next(2, 6);
}
3. 🔁 Game loop

Take turns until one side is defeated.

while (hero.Alive && monsters.Any(m => m.Alive))
{
    // hero attacks the first living monster
    // each living monster attacks back
}

🧪 Try it!

Read the code, guess what it prints, then press 👀 Show output.

Monster Battle (sample run — your numbers will differ)

var rng = new Random();
var hero = new Hero();
var monsters = new List<Fighter> { new Slime(), new Bat() };
int round = 1;

while (hero.Alive && monsters.Any(m => m.Alive))
{
    var target = monsters.First(m => m.Alive);
    int dmg = hero.Attack(rng);
    target.Hit(dmg);
    Console.WriteLine($"Round {round}: {hero.Name} hits {target.Name} for {dmg} ⚔️");
    foreach (var m in monsters.Where(m => m.Alive))
        hero.Hit(m.Attack(rng));
    round++;
}
Console.WriteLine(hero.Alive ? "🏆 Victory!" : "💀 Defeated...");

// ---------- The game’s classes (they go after the main code in C#) ----------
abstract class Fighter
{
    public string Name { get; }
    public int Hp { get; protected set; }
    protected Fighter(string name, int hp) { Name = name; Hp = hp; }
    public bool Alive => Hp > 0;
    public void Hit(int dmg) => Hp = Math.Max(0, Hp - dmg);
    public abstract int Attack(Random rng);
}

class Hero : Fighter
{
    public Hero() : base("Hero", 60) { }
    public override int Attack(Random rng) => rng.Next(8, 17);
}

class Slime : Fighter
{
    public Slime() : base("Slime", 20) { }
    public override int Attack(Random rng) => rng.Next(2, 6);
}

class Bat : Fighter
{
    public Bat() : base("Bat", 25) { }
    public override int Attack(Random rng) => rng.Next(3, 8);
}

A Bat monster

class Bat : Fighter
{
    public Bat() : base("Bat", 25) { }
    public override int Attack(Random rng) => rng.Next(3, 8);
}

📖 Key words

Tap a card to flip it over!

abstract
A base that must be extended 🧬
: (inherit)
class Slime : Fighter means Slime is a Fighter 👪
override
Provides the subclass version 🔁
Game loop
Repeats turns until the game ends 🎮

🏆 Challenge

Remix it: add a Dragon boss with 60 HP that attacks for 8–14, and give the Hero a Heal() move every third round. Build it with the free .NET SDK (dotnet new console) in VS Code. Sample ending:

Challenge

class Dragon : Fighter
{
    public Dragon() : base("Dragon", 60) { }
    public override int Attack(Random rng) => rng.Next(8, 15);
}

Knowledge Check Quiz

  1. How does C# show inheritance?
  2. What does monsters.Any(m => m.Alive) check?
  3. Why make Fighter abstract?
← Previous lesson