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は、条件に an を追加するだけです。

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

楽しみのためにあなたのコードをリファクタリングしました :) いくつかのクラスGameHeroを抽出し、Monster関連するロジックをそこに移動すると (そう、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 に答える