2

大家好,我只是VS2010中的C#初学者,学习它的原因是能够在游戏编程中发展,我得到了这个程序的源代码并添加了很多东西。这是控制台应用程序源。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace First_Game

{
     class Program
    {
        void DisplayChoices(int heroHitPoints, int monsterHitPoints) // 1st method to display the choices 
        {
            Console.Write(@"
************************************************
Your hero has {0}hp and the Monster has {1}hp
************************************************", heroHitPoints, monsterHitPoints);

            Console.Write(@"
__________________________
Please Choose an action:
(A)ttack
(D)efend
(H)eal
(F)lee
__________________________");
            Console.WriteLine();
        }
        int GetHeroDamage(Random rand)// 2nd Method to calculate the hero's Damage during battle.
     {
         int attackdamage;
         attackdamage = rand.Next(350, 450);
         return attackdamage;
     }
        int GetMonsterDamage(Random rand) // 3rd Method to calculate the monster's damage during the battle.
         {
         int attackdamage;
         attackdamage = rand.Next(250, 350);
         return attackdamage;
     }
        static void Main(string[] args)
        {
            Program CH = new Program();
            int heroHitPoints, monsterHitPoints, attackdamage, healing, fleechance, hitchance;
            Random rand;
            string battlechoice;
            Console.WriteLine("You are facing a Monster!");
            //this is outside the loop so that it will only print once
            heroHitPoints = 1500;// our variables are assigned ouside
            monsterHitPoints =2000;//so that each loop won't "heal" them
            do
            {
                rand = new Random();
                CH.DisplayChoices(heroHitPoints, monsterHitPoints);
                battlechoice = Console.ReadLine();
                switch (battlechoice)
                {
                    case "a":
                    case "A"://this way a or A work
                        hitchance = rand.Next(0, 100);
                        if (hitchance > 30)
                        {
                            attackdamage = CH.GetHeroDamage(rand);
                            Console.WriteLine("The hero attacks!");
                            monsterHitPoints -= attackdamage;
                            Console.WriteLine("The monster loses {0}hp", attackdamage);
                        }
                        else
                        {
                            Console.WriteLine("You missed!");
                        }
                        break;
                    case "d":
                    case "D":
                        Console.WriteLine("The Hero Defends");
                        break;
                    case "h":
                    case "H":
                        healing = 400;
                        heroHitPoints += healing;
                        Console.WriteLine("The Hero uses a Potion!");
                        Console.WriteLine("The Hero heals himself for {0} Points", healing);
                        break;
                    case "f":
                    case "F":
                        fleechance = rand.Next(0, 100);
                        if (fleechance > 40)
                        {
                            Console.WriteLine("The hero fled!");
                            Console.ReadLine();
                            Environment.Exit(0);
                        }
                        else
                        {
                            Console.WriteLine("Fleeing Failed");
                            Console.ReadLine();

                        }
                        break;
                    default://defaults always a good idea with user input
                        Console.WriteLine("Sorry that choice was invalid and the monster took a cheap shot!");
                        break;
                }

                Console.WriteLine();
                if (monsterHitPoints > 0)//if the monster is still alive
                {
                    hitchance = rand.Next(0, 100);
                    if (hitchance > 30)
                    {
                        attackdamage = CH.GetMonsterDamage(rand);
                        Console.WriteLine("The Monster Attacks!");
                        if (battlechoice == "d" || battlechoice == "D")
                        { //this is so that defend has some sort of benefit
                            attackdamage /= 2;
                        }
                        heroHitPoints -= attackdamage;//subtract the damage
                        Console.WriteLine("The Hero loses {0}hp", attackdamage);
                    }
                    Console.WriteLine("Press Enter to Continue");
                    Console.ReadLine();
                    Console.Clear();//this clears the screen so that we don't have the
                    //last turns info on it.
                }
            }
            while (heroHitPoints > 0 && monsterHitPoints > 0);

            if (heroHitPoints > 0)
            {
                Console.WriteLine("You are Victorious!");
            }
            else
            {
                Console.WriteLine("You have been defeated :(");
            }
            Console.ReadLine();
        }
    }

     }

该程序应该要求您选择一个选项,并且在您执行它之后,怪物应该无论如何都会攻击。我创建了 3 个方法并调用了它们。我的问题是,以 IF 语句开头并在 while 之前结束的部分有时会运行,有时不会,就像它完全随机一样,我认为这与怪物的偶然性有关,但事实并非如此,帮助表示赞赏。VS2010没有给我任何错误,并且每次都使用相同的方式英雄攻击。

4

3 回答 3

3

好的。我试过了,它工作正常,但是当怪物错过时你不打印任何东西,这就是你所说的随机失败吗?要纠正它,只需在条件后面附加一个else

hitchance = rand.Next(0, 100);
if (hitchance > 30)
{
    attackdamage = CH.GetMonsterDamage(rand);
    Console.WriteLine("The Monster Attacks!");
    if (battlechoice == "d" || battlechoice == "D")
    { //this is so that defend has some sort of benefit
        attackdamage /= 2;
    }
    heroHitPoints -= attackdamage;//subtract the damage
    Console.WriteLine("The Hero loses {0}hp", attackdamage);
}
else
{
    Console.WriteLine("The monster misses!");
}
于 2012-07-25T09:30:10.413 回答
1

我认为它工作正常;你只是因为hitchance. 不过,怪物确实会攻击,这取决于偶然性:

You are facing a Monster!

************************************************
Your hero has 1500hp and the Monster has 2000hp
************************************************
__________________________
Please Choose an action:
(A)ttack
(D)efend
(H)eal
(F)lee
__________________________
a
The hero attacks!
The monster loses 442hp

The Monster Attacks!
The Hero loses 348hp
Press Enter to Continue
于 2012-07-25T09:29:23.200 回答
1

我重构了你的代码只是为了好玩 :) 在提取了一些类GameHeroMonster移动相关逻辑之后(是的,OOP),你的游戏看起来像:

class Program
{     
    static void Main(string[] args)
    {
        Game game = new Game();
        game.Start();
        Console.ReadLine();
    }
}

所有游戏逻辑都移到了Game类,它负责创建和管理角色、向用户显示游戏以及检索用户输入:

public class Game
{
    private const int _dispalyWidth = 42;

    public void Start()
    {
        Hero hero = new Hero();
        Monster monster = new Monster();
        Console.WriteLine("You are facing a Monster!");
        Console.ReadKey();
        Console.Clear();

        do
        {
            DisplayBattle(hero, monster);

            switch (GetChoice())
            {
                case BattleChoice.Attack:
                    hero.Attack(monster);
                    break;
                case BattleChoice.Defend:
                    hero.Defend();
                    break;
                case BattleChoice.Heal:
                    hero.Heal(400);
                    break;
                default:
                    Console.WriteLine("Monster took a cheap shot!");
                    break;
            }                

            if (monster.IsAlive)
                monster.Attack(hero);

            Console.WriteLine("Press Enter to Continue");
            Console.ReadLine();
            Console.Clear();
        }
        while(hero.IsAlive && monster.IsAlive);

        DisplayBattleResult(hero);
        Console.ReadLine();
    }

    private void DisplayBattleResult(Hero hero)
    {
        if (hero.IsAlive)
            Console.WriteLine("You are victorious!");
        else
            Console.WriteLine("You have been defeated :(");
    }

    private void DisplayBattle(Hero hero, Monster monster)
    {
        Console.WriteLine(new String('*', _dispalyWidth));
        Console.WriteLine("{0} has {1}hp and the {2} has {3}hp", 
            hero.Name, hero.HitPoints, monster.Name, monster.HitPoints);
        Console.WriteLine(new String('*', _dispalyWidth));
    }

    private void DisplayChoices()
    {
        Console.WriteLine(new String('-', _dispalyWidth));
        Console.WriteLine("Please Choose an action:");
        Console.WriteLine("(A)ttack");
        Console.WriteLine("(D)efend");
        Console.WriteLine("(H)eal");
        Console.WriteLine("(F)lee");
        Console.WriteLine(new String('-', _dispalyWidth));
    }

    private BattleChoice GetChoice()
    {
        DisplayChoices();
        ConsoleKeyInfo key = Console.ReadKey(true);
        switch (key.Key)
        {
            case ConsoleKey.A:
                return BattleChoice.Attack;
            case ConsoleKey.H:
                return BattleChoice.Heal;
            case ConsoleKey.D:
                return BattleChoice.Defend;
            default:
                return BattleChoice.Wait;
        }
    }
}

如你所见,我介绍了英雄和怪物的类。它们继承自Character类,该类负责保存和操作角色的数据:

public class Character
{
    private readonly Random _random = new Random();

    public Character(string name, int hitPoints, Range damageRange, int hitChance)
    {
        Name = name;
        HitPoints = hitPoints;
        HitChance = hitChance;
        DamageRange = damageRange;
    }

    public string Name { get; set; }
    public int HitChance { get; private set; }
    public int HitPoints { get; private set; }
    public Range DamageRange { get; private set; }
    private bool IsDefending { get; set; }

    public bool IsAlive
    {
        get { return HitPoints > 0; }
    }

    public void Defend()
    {
        Console.WriteLine("The {0} defends", Name);
        IsDefending = true;
    }

    public void Heal(int amount)
    {
        Console.WriteLine("The {0} uses a Potion!", Name);            
        IsDefending = false;
        HitPoints += amount;
        Console.WriteLine("The {0} heals himself for {0} points", amount);
    }

    public void Hit(int amount)
    {
        int receivedDamage = IsDefending ? (amount / 2) : amount;
        HitPoints -= receivedDamage;
        Console.WriteLine("The {0} loses {1}hp", Name, receivedDamage);
    }

    public void Attack(Character target)
    {
        Console.WriteLine("The {0} attacks!", Name);
        IsDefending = false;

        if (HitChance <= _random.Next(0, 100))
        {
            Console.WriteLine("{0} missed!", Name);
            return;
        }

        target.Hit(_random.Next(DamageRange.Min, DamageRange.Max));
    }
}

public class Hero : Character
{
    public Hero()
        : base("Hero", 1500, new Range(350, 450), 30)
    {
    }   
}

public class Monster : Character
{
    public Monster()
        : base("Monster", 2000, new Range(250, 350), 30)
    {
    }
}

我还使用范围来保持可能的伤害(也许在同一个物体上保持伤害机会也很好):

public class Range
{
    public Range(int min, int max)
    {
        Min = min;
        Max = max;
    }

    public int Min { get; private set; }
    public int Max { get; private set; }
}

以及描述用户选择的枚举:

public enum BattleChoice
{
    Attack,
    Defend,
    Heal,
    Wait
}

我认为将机会验证和伤害生成转移到诸如 之类Universe的类会很好,但它适合你。祝你好运!

于 2012-07-25T11:14:47.957 回答