对游戏进行编程,代码执行是随机的

时间:2012-07-25 09:13:34

标签: c# visual-studio-2010

大家好,我只是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语句开头并在片刻之前结束的部分有时会运行,有时则不会,就像它是完全随机的一样,我认为这与怪物的命中有关但事实并非如此,帮助表示赞赏。 VS2010没有给我任何错误,并且英雄每次都会攻击,即使我对它们使用相同的方式。

3 个答案:

答案 0 :(得分: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!");
}

答案 1 :(得分: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

答案 2 :(得分: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会很好,但它适合你。 祝你好运!