Строка в int, чтобы ответить, что делать - PullRequest
0 голосов
/ 28 марта 2019

Эй, я застрял с проблемой. Я хочу разобрать строку в целое число, потому что я делаю консольную игру, где игрок должен выбрать, какой ход использовать. До сих пор я определил синтаксический анализ, но я не могу понять, как я перебрал бы свой список, чтобы проверить, действительно ли перемещение действительно. У меня есть список, который называется Move, где у каждого покемона есть свой элементал, но как бы я сослался на это, вот код

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, перемещение не используется 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;
                }
            }
        }
    }
}

Ответы [ 2 ]

1 голос
/ 28 марта 2019

Я думаю, что реальный ответ здесь не столько в том, как вы выполняете итерацию, но в том, как вы должны были сконструировать класс перемещения для работы.Хотя теперь вы можете игнорировать недостаток дизайна и обходить его, гораздо лучше исправить это сейчас и сделать это правильно с самого начала.

Я собираюсь решать проблемы, с которыми вы, возможно, не сталкивалисьсейчас, но они являются лучшими примерами того, почему ваш дизайн имеет недостатки, и они станут проблемой, если вы создаете игру в стиле покемонов.

Проблема :

roster.Add(new Pokemon("Charmander", 3, 52, 50, 39, Elements.Fire, FireMoves));

Здесь вы говорите, что Чармандер относится к типу Elements.Fire и имеет определенный List<Move>.

Однако приложение не может узнать, действительно ли эти действия Чармандер может выполнить.Что мешает мне сделать:

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, потому что, если Чармандер выполняет Нормальную атаку, Бульбазавр не получает дополнительного урона от этого, так как Булбазавр не имеет слабости к Нормальным атакам.)проверьте, способен ли покемон выполнить ход, о котором ему говорят, и вам нечего проверить, имеет ли покемон определенную слабость / сопротивление определенным ходам.Это важные элементы игр про покемонов, с которыми вы будете сталкиваться раньше, чем раньше, но ваш дизайн делает невозможным это сделать.

Все это происходит из-за неудачного дизайнерского решения в 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 - новичок в области программирования, который может бороться с независимой реализациейслишком обобщенный ответ.

0 голосов
/ 28 марта 2019

вам нужно перебирать только ходы игрока. Так как выбор был сделан

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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...