C# · Chapter 3.12 · Pro level

Capstone: Mini RPG Battle (enum + switch + Random + classes + List + while)

कैपस्टोन: मिनी RPG बैटल (enum + switch + Random + classes + List + while)

Capstone time! A real game runs a game loop: while both fighters are alive, pick a move, apply it and let the enemy hit back. You will use everything you learnt: an enum for fixed choices (enum Move { Slash, Fireball, Heal } — like the buttons on a controller), a switch to run the right code for each move, a class for the fighters, a List for the loot, a while loop for the rounds and Random for the dice. Real games use new Random(), which gives different rolls every time. We write new Random(7): a fixed seed gives the same sequence every run, so you (and the checker) can replay the battle exactly. The same C# runs inside Unity, where the game loop is the Update() method that runs about 60 times a second.

कैपस्टोन का समय! असली गेम एक game loop चलाता है: जब तक दोनों लड़ाके ज़िंदा हैं, एक चाल चुनो, उसे लागू करो और दुश्मन को पलटवार करने दो। इसमें आपकी सीखी हर चीज़ लगेगी: तय विकल्पों के लिए enum (enum Move { Slash, Fireball, Heal } — कंट्रोलर के बटनों जैसा), हर चाल का सही कोड चलाने के लिए switch, लड़ाकों के लिए class, लूट के सामान के लिए List, राउंड्स के लिए while लूप और पासे के लिए Random। असली गेम new Random() लिखते हैं, जो हर बार अलग नंबर देता है। हम new Random(7) लिखते हैं: तय seed से हर बार वही क्रम आता है, इसलिए आप (और checker) वही लड़ाई दोबारा हूबहू देख सकते हो। यही C# Unity में चलती है, जहाँ game loop Update() method होता है जो एक सेकंड में लगभग 60 बार चलता है।

In the classroom you can run and edit this code in your browser, get hints and mark the chapter as done. क्लास में यह code ब्राउज़र में चलाकर बदल सकते हो।

Words and symbols in this chapter

enum Move { Slash, Fireball, Heal }
A type with a fixed list of named choices (stored as 0, 1, 2).
तय नाम वाले विकल्पों का टाइप (अंदर 0, 1, 2 के रूप में)।
(Move)dice.Next(0, 3)
A random number 0, 1 or 2 turned into a Move.
0, 1 या 2 में से एक random नंबर, जिसे Move में बदल दिया।
switch (move) { case Move.Slash: ... break; }
Runs the code of the matching case; every case ends with break;.
मिलते हुए case का कोड चलाता है; हर case break; पर ख़त्म होता है।
new Random(7)
Dice with a fixed seed: the same rolls every run (great for testing).
तय seed वाला पासा: हर बार वही नंबर (टेस्टिंग के लिए बढ़िया)।
while (hero.Health > 0 && boss.Health > 0)
The game loop: it continues while both are alive (&& = AND).
Game loop: जब तक दोनों ज़िंदा हैं, चलता रहता है (&& = और)।
string.Join(", ", loot)
Joins all items of a list into one line of text.
List के सारे items को जोड़कर एक लाइन बना देता है।

Ready example

using System;
using System.Collections.Generic;

enum Move { Slash, Fireball, Heal }

class Fighter {
    public string Name;
    public int Health;

    public Fighter(string name, int health) {
        Name = name;
        Health = health;
    }

    public void Attack(Fighter target, int damage) {
        target.Health -= damage;
        if (target.Health < 0) target.Health = 0;
        Console.WriteLine(Name + " hits " + target.Name + " for " + damage + " -> " + target.Name + " HP: " + target.Health);
    }
}

class Program {
    static void Main() {
        Random dice = new Random(7);
        Fighter hero = new Fighter("Arjun", 100);
        Fighter boss = new Fighter("Dragon", 120);
        List<string> loot = new List<string> { "Gold Coin", "Dragon Scale" };
        int level = 10;
        int round = 1;

        Console.WriteLine("Level " + level + ": Boss fight begins!");
        while (hero.Health > 0 && boss.Health > 0) {
            Move move = (Move)dice.Next(0, 3);
            Console.WriteLine("-- Round " + round + ": " + move + " --");
            switch (move) {
                case Move.Slash:
                    hero.Attack(boss, 25);
                    break;
                case Move.Fireball:
                    hero.Attack(boss, 40);
                    break;
                case Move.Heal:
                    hero.Health += 15;
                    Console.WriteLine(hero.Name + " heals +15 -> HP: " + hero.Health);
                    break;
            }
            if (boss.Health > 0) {
                boss.Attack(hero, 18);
            }
            round++;
        }

        if (hero.Health > 0) {
            Console.WriteLine(hero.Name + " wins! Loot: " + string.Join(", ", loot));
        } else {
            Console.WriteLine("Game over! " + boss.Name + " wins.");
        }
    }
}

What you will see: The battle log appears round by round; the 2D stage shows the boss fight and every attack.

लड़ाई का हाल राउंड-दर-राउंड दिखेगा; 2D स्टेज पर बॉस फ़ाइट और हर हमला दिखेगा।

Line by line

enum Move { Slash, Fireball, Heal }
The three moves the hero knows.
हीरो की तीन चालें।
Random dice = new Random(7);
Seeded dice: this battle is the same every time you Run.
Seed वाला पासा: हर बार Run करने पर यही लड़ाई होगी।
while (hero.Health > 0 && boss.Health > 0) { ... }
One loop round = one battle round.
लूप का एक चक्कर = लड़ाई का एक राउंड।
switch (move) { ... }
Slash -25, Fireball -40, Heal +15.
Slash -25, Fireball -40, Heal +15।
if (boss.Health > 0) { boss.Attack(hero, 18); }
A defeated dragon cannot hit back.
हारा हुआ ड्रैगन पलटवार नहीं कर सकता।

Common mistake

✗ Wrong

case Move.Kick:
    enemy.Health -= 30;
case Move.Block:
    hero.Health += 10;
    break;

✓ Right

case Move.Kick:
    enemy.Health -= 30;
    break;
case Move.Block:
    hero.Health += 10;
    break;

In C# every case section must end with break; — falling into the next case is error CS0163.

C# में हर case हिस्सा break; पर ख़त्म होना चाहिए — अगले case में गिर जाना error CS0163 है।

Your task

Finish the Orc battle: write enum Move { Punch, Kick, Block }, a while game loop, a switch (Punch: enemy -20, Kick: enemy -30, Block: hero +10), add each move to log, let the Orc hit back 15 while it is alive, and print the winner. With new Random(7) the log must be Kick, Block, Kick, Punch, Kick and the result Arjun wins!.

Orc वाली लड़ाई पूरी करो: enum Move { Punch, Kick, Block }, एक while game loop, एक switch (Punch: दुश्मन -20, Kick: दुश्मन -30, Block: हीरो +10) लिखो, हर चाल log में जोड़ो, Orc ज़िंदा हो तो 15 का पलटवार करे, और विजेता print करो। new Random(7) के साथ log Kick, Block, Kick, Punch, Kick और नतीजा Arjun wins! होना चाहिए।

  1. Above class Fighter write enum Move { Punch, Kick, Block }.
    class Fighter के ऊपर enum Move { Punch, Kick, Block } लिखो।
  2. In Main: while (hero.Health > 0 && enemy.Health > 0) { → Move move = (Move)dice.Next(0, 3); → switch (move) with the 3 cases (each ends with break;) → log.Add(move.ToString()); → if (enemy.Health > 0) hero.Health -= 15; → }.
    Main में: while (hero.Health > 0 && enemy.Health > 0) { → Move move = (Move)dice.Next(0, 3); → 3 cases वाला switch (move) (हर case break; पर ख़त्म) → log.Add(move.ToString()); → if (enemy.Health > 0) hero.Health -= 15; → }।
  3. After the loop: if hero.Health > 0 print hero.Name + " wins!", else enemy.Name + " wins!" — then Run.
    लूप के बाद: अगर hero.Health > 0 तो hero.Name + " wins!" print करो, वरना enemy.Name + " wins!" — फिर Run करो।
Starter code for the task
using System;
using System.Collections.Generic;

// TODO 1: enum Move { Punch, Kick, Block } banao

class Fighter {
    public string Name;
    public int Health;

    public Fighter(string name, int health) {
        Name = name;
        Health = health;
    }
}

class Program {
    static void Main() {
        Random dice = new Random(7);
        Fighter hero = new Fighter("Arjun", 100);
        Fighter enemy = new Fighter("Orc", 90);
        List<string> log = new List<string>();

        // TODO 2: while (hero.Health > 0 && enemy.Health > 0) { ... } loop banao
        // TODO 3: loop ke andar: Move move = (Move)dice.Next(0, 3);
        // TODO 4: switch (move): Punch -> enemy.Health -= 20;  Kick -> enemy.Health -= 30;  Block -> hero.Health += 10;
        //         switch ke baad: log.Add(move.ToString());  aur  if (enemy.Health > 0) hero.Health -= 15;

        Console.WriteLine("Moves: " + string.Join(", ", log));
        // TODO 5: jo jeeta uska naam print karo: hero.Name + " wins!"  ya  enemy.Name + " wins!"
    }
}

Do this task in the classroom: your code is checked automatically and you get hints if something is missing.

Recap

Quick quiz

Why does this capstone use new Random(7) instead of new Random()?

यह कैपस्टोन new Random() की जगह new Random(7) क्यों लिखता है?

  1. So the dice always rolls 7
  2. The same seed gives the same sequence every run, so the battle can be repeated and tested
  3. It makes the program faster
  4. C# does not allow Random without a number
Show the answer

Answer: B (The same seed gives the same sequence every run, so the battle can be repeated and tested)

A seed fixes the sequence of random numbers. Games use no seed (different every time); tests use a seed.

Seed random नंबरों का क्रम तय कर देता है। गेम में seed नहीं देते (हर बार अलग), टेस्टिंग में seed देते हैं।

Practice problems for this chapter

Solve them in the Practice Zone, where each answer is checked automatically and two hints are available.