嘿,我遇到了一个问题。我想把一个字符串解析成一个整数,因为我正在制作一个控制台游戏,玩家应该选择使用哪个移动。到目前为止,我定义了解析,但我似乎无法找到如何迭代列表来查看移动是否有效。我有一个名为“移动”的列表,每个口袋妖怪都有自己的元素,但是我如何引用它呢?
List<Move> FireMoves = new List<Move>();
FireMoves.Add(new Move("Ember"));
FireMoves.Add(new Move("Fireblast"));
List<Move> WaterMoves = new List<Move>();
WaterMoves.Add(new Move("Bubble"));
WaterMoves.Add(new Move("Bite"));
List<Move> GrassMoves = new List<Move>();
GrassMoves.Add(new Move("Cut"));
GrassMoves.Add(new Move("Megadrain"));
GrassMoves.Add(new Move("Razor Leaf"));这是另一部分。最后两行我认为是对的,但我不明白如何让控制台理解当1被按下时,使用的是no 1
 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Pokemon
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Move> FireMoves = new List<Move>();
            FireMoves.Add(new Move("Ember"));
            FireMoves.Add(new Move("Fireblast"));
            List<Move> WaterMoves = new List<Move>();
            WaterMoves.Add(new Move("Bubble"));
            WaterMoves.Add(new Move("Bite"));
            List<Move> GrassMoves = new List<Move>();
            GrassMoves.Add(new Move("Cut"));
            GrassMoves.Add(new Move("Megadrain"));
            GrassMoves.Add(new Move("Razor Leaf"));
            List<Pokemon> roster = new List<Pokemon>();
            // INITIALIZE YOUR THREE POKEMONS HERE
            //Tilføj moves 
            roster.Add(new Pokemon("Charmander", 3, 52, 50, 39, Elements.Fire,FireMoves));
            roster.Add(new Pokemon("Squirtle", 2, 48, 65, 44, Elements.Water, WaterMoves));
            roster.Add(new Pokemon("Bulbasaur", 3, 49, 49, 45, Elements.Grass, GrassMoves));
            Console.WriteLine("Welcome to the world of Pokemon!\nThe available commands are list/fight/heal/quit");
            while (true)
            {
                Console.WriteLine("\nPlese enter a command");
                switch (Console.ReadLine())
                {
                    case "list":
                        // PRINT THE POKEMONS IN THE ROSTER HERE
                        Console.WriteLine("These are the pokemons that are currently active");
                        foreach(Pokemon g in roster)
                        {
                            Console.WriteLine(roster.IndexOf(g)+" "+g.Name);
                        }
                        break;
                    case "fight":
                        //PRINT INSTRUCTIONS AND POSSIBLE POKEMONS (SEE SLIDES FOR EXAMPLE OF EXECUTION)
                        Console.Write("Choose who you should fight against and the pokemon you want to control is mentionened last\n");
                        Console.Write("To chose your pokemon is mentioned first example of 'Charmander Squirtle', where Squirtle is the opponent\n");                       
                        //Console.Write("1=Charmander vs Squirtle\n2=Squirtle vs Charmander\n3=Charmander vs Bulbasaur\n4=Bulbasaur vs Squirtle\n5=Bulbasaur vs Charmander\n6=Squirtle vs Bulbasaur\n");
                        //READ INPUT, REMEMBER IT SHOULD BE TWO POKEMON NAMES
                        string input = Console.ReadLine();
                        //BE SURE TO CHECK THE POKEMON NAMES THE USER WROTE ARE VALID (IN THE ROSTER) AND IF THEY ARE IN FACT 2!
                        List<String> inputs = new List<string>(input.Split(" ".ToCharArray()));
                        //BE SURE TO CHECK THE POKEMON NAMES THE USER WROTE ARE VALID (IN THE ROSTER) AND IF THEY ARE IN FACT 2!
                        Pokemon player = null;
                        Pokemon enemy = null;
                        foreach (Pokemon p in roster)
                        {
                            if (inputs[0] == p.Name)
                            {
                                player = p;
                            }
                            if (inputs[1] == p.Name)
                            {
                                enemy = p;
                            }
                        }
                        //if everything is fine and we have 2 pokemons let's make them fight
                        if (player != null && enemy != null && player != enemy)
                        {
                            Console.WriteLine("A wild " + enemy.Name + " appears!");
                            Console.Write(player.Name + " I choose you! ");
                            //BEGIN FIGHT LOOP
                            while (player.Hp > 0 && enemy.Hp > 0)
                            {
                                //PRINT POSSIBLE MOVES
                                Console.Write("What move should we use?\n");
                                foreach(Pokemon p in roster) {
                                    if (player.Name == p.Name)
                                        foreach (Move n in p.Moves)
                                        {
                                        Console.WriteLine(p.Moves.IndexOf(n)+" "+n.Name);
                                        }
                             }
                                //GET USER ANSWER, BE SURE TO CHECK IF IT'S A VALID MOVE, OTHERWISE ASK AGAIN
                                string moveInput = Console.ReadLine();
                                int moveNo = int.Parse(moveInput);
                                int move = -1;
                                //CALCULATE AND APPLY DAMAGE
                                int damage = -1;
                                //print the move and damage
                                Console.WriteLine(player.Name + " uses " + player.Moves[move].Name + ". " + enemy.Name + " loses " + damage + " HP");
                                //if the enemy is not dead yet, it attacks
                                if (enemy.Hp > 0)
                                {
                                    //CHOOSE A RANDOM MOVE BETWEEN THE ENEMY MOVES AND USE IT TO ATTACK THE PLAYER
                                    Random rand = new Random();
                                    /*the C# random is a bit different than the Unity random
                                     * you can ask for a number between [0,X) (X not included) by writing
                                     * rand.Next(X) 
                                     * where X is a number 
                                     */
                                    int enemyMove = -1;
                                    int enemyDamage = -1;
                                    //print the move and damage
                                    Console.WriteLine(enemy.Name + " uses " + enemy.Moves[enemyMove].Name + ". " + player.Name + " loses " + enemyDamage + " HP");
                                }
                            }
                            //The loop is over, so either we won or lost
                            if (enemy.Hp <= 0)
                            {
                                Console.WriteLine(enemy.Name + " faints, you won!");
                            }
                            else
                            {
                                Console.WriteLine(player.Name + " faints, you lost...");
                            }
                        }
                        //otherwise let's print an error message
                        else
                        {
                            Console.WriteLine("Invalid pokemons");
                        }
                        break;
                    case "heal":
                        //RESTORE ALL POKEMONS IN THE ROSTER
                        Console.WriteLine("All pokemons have been healed");
                        break;
                    case "quit":
                        Environment.Exit(0);
                        break;
                    default:
                        Console.WriteLine("Unknown command");
                        break;
                }
            }
        }
    }
}发布于 2019-03-28 13:44:21
你只需要在玩家的移动过程中迭代。因为已经做出了选择
for (int i = 0; i < player.Moves.Count; i++)
{
    Console.WriteLine(i + " " + player.Moves[i].Name);
}“查看移动是否有效”和“我不明白如何使控制台理解当1被按下,第1号移动被使用”
任何正移动编号,即较小的,则列表中的项目数量是有效的输入。如果将索引提供给用户作为选择,则可以使用索引访问项/移动。
if(moveNo >= 0 && moveNo < player.Moves.Count)
{
    //access move by index
    var move = player.Moves[moveNo]
}
else
{
    // not a valid move
}发布于 2019-03-28 14:18:22
我认为这里真正的答案不是如何迭代,而是应该如何设计move类来工作。当你现在可以忽略这个设计缺陷并绕过它的时候,最好现在就修复它,从一开始就用正确的方法去做。
我要解决的问题,你可能没有面对,但他们是更好的例子,为什么你的设计是有缺陷的,他们将成为问题,如果你正在构建一个口袋妖怪风格的游戏。
问题
roster.Add(new Pokemon("Charmander", 3, 52, 50, 39, Elements.Fire, FireMoves));在这里,您可以说Charmander是一个Elements.Fire类型,并且有一个特定的List<Move>。
然而,应用程序无法知道这些是否是Charmander实际可以执行的移动。阻止我做的事情是:
roster.Add(new Pokemon("Charmander", 3, 52, 50, 39, Elements.Fire, WaterMoves));,,这看起来不像现在的问题。您可以读取列表的名称,因此定义了它的类型,对吗?既然你要负责把这个列表添加到“精灵精灵”的手机上,你就知道你做的是对的。对吗?
因此,让我们想象一下,当您的应用程序变得更大时,您有以下方法:
public void PerformAttack(Move move, Pokemon attacker, Pokemon defender)
{
}
// Example
PerformAttack(ember, charmander, bulbasaur);因为牛头龙是一种草类,他会受到额外的火力攻击伤害。但是,我们如何知道所选的移动实际上是一个火移动?如果没有存储在其中的列表的上下文,您就无法知道某个移动是否属于某种类型的。(而且您不能使用attacker.Type,因为如果Charmander执行正常攻击,牛头龙不会受到额外的伤害,因为牛头龙对正常攻击没有弱点)。
您没有任何地方可以检查一个精灵是否能够执行它要做的移动,您也没有任何地方可以检查一个精灵是否对某些移动有某种弱点/抵抗。这些都是口袋妖怪游戏的基本元素,你迟早会遇到这些,但是你的设计使得你不可能做到这一点。
这一切都来自于Move类中的一个错误的设计决策:移动没有一个类型。为了解决这一问题,您已经尝试列出您的列表:
List<Move> FireMoves = new List<Move>();
List<Move> WaterMoves = new List<Move>();
List<Move> GrassMoves = new List<Move>();解决方案:
移动必须有自己的类型:
public class Move
{
    public string Name { get; set; }
    public Elements Type { get; set; }
}现在,你可以解决我展示的所有问题了。您只需在创建移动时设置类型:
List<Move> FireMoves = new List<Move>();
FireMoves.Add(new Move("Ember", Elements.Fire));
List<Move> WaterMoves = new List<Move>();
WaterMoves .Add(new Move("Bubble", Elements.Water));这也意味着您不再需要有单独的基于类型的列表,您可以有一个大列表。
List<Move> Moves = new List<Move>();
Moves.Add(new Move("Ember", Elements.Fire));
Moves.Add(new Move("Bubble", Elements.Water));因为现在所有的动作都是同一个列表的一部分,所以你的问题更容易回答:
到目前为止,我定义了解析,但我似乎无法找到如何迭代列表来查看移动是否有效。
public bool IsMove(Pokemon target, string userCommand)
{
    return target.Moves.Any(move => move.Name.ToLower() == userCommand.ToLower());
}然后您可以像这样使用:
string userCommand = Console.ReadLine();
if(IsMove(userCurrentPokemon, userCommand))
{
    // Handle attack logic
}
else
{
    // Handle non-attack logic
}请注意,如果出于特定原因仍然希望有单独的列表,则仍然可以筛选移动列表:
var fireMoves = Moves.Where(move => move.Type == Elements.Fire).ToList();
var waterMoves = Moves.Where(move => move.Type == Elements.Water).ToList();
var grassMoves = Moves.Where(move => move.Type == Elements.Grass).ToList();如果有人想评论这个答案是专注于现有的口袋妖怪功能,而不是OP的游戏:这是正确的,但我选择这样做,因为OP是在这种情况下工作。我本可以给出一个更中性的例子,“添加一个属性而不是命名一个变量”,但这并不容易理解,我推断OP是编程领域的初学者,他们可能难以独立实现一个过于笼统的答案。
https://stackoverflow.com/questions/55399033
复制相似问题