开发者

get bool from other method to end while loop

开发者 https://www.devze.com 2023-03-25 20:23 出处:网络
I am having difficulty getting the bool done value from EndLoop() and moving it to the Start() method to end my while loop.What am I doing wrong?

I am having difficulty getting the bool done value from EndLoop() and moving it to the Start() method to end my while loop. What am I doing wrong?

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

namespace ConsoleApplication1
{
    class Program
    {


        public static void Main(string[] args)
        {
            Start("r");
        }

        public static string Start(string move)
        {

            Console.Write("Welcome to the Shotgun App\nEnter s for single player and m for multiplayer: ");
            string gameType = Console.ReadLine();

            if (gameType == "s")
            {

                Console.Write("Single Player Controls:\n r = reload\n s = shield\n f = fire\nYou start with 1 ammo\nReady to play?");
                Console.ReadLine();

                int ammo = 1;
                int geniusAmmo = 1;
                string geniusMove = "";
                bool done = false;
                while (!done)
                {
                    Console.Write("\nEnter your move: ");
                    move = Console.ReadLine();


                    switch (move)
                    {
                        case "r":
                            Console.Write("\nYou have reloaded, press enter for Genius\n");

                            ammo++;
                            Console.Write("Your ammo is " + ammo);

                            Console.ReadLine();
                            Genius(geniusMove, move, geniusAmmo, done);


                            break;
                        case "s":
                            Console.Write("\nYou have shielded, press enter for Genius\n");

                            Console.Write("Your ammo is " + ammo);

                            Console.ReadLine();
                            Genius(geniusMove, move, geniusAmmo, done);


                            break;
                        case "f":
                            if (ammo != 0)
                            {
                                Console.Write("\nYou have fired, press enter for Genius\n");

                                ammo--;
                                Console.Write("Your ammo is " + ammo);

                                Console.ReadLine();

                                Genius(geniusMove, move, geniusAmmo, done);

                            }
                            else
                            {
                                Console.Write("You don't have enough ammo, try again");
                                done = false;
                            }
                            break;
                        default:
                            Console.Write("\nInvalid move, try again\n");
                            done = false;
                            break;
                    }

                    Console.ReadLine();

                }
                return move;
            }
            else
            {
                return move;
            }
        }

        public static string Genius(string geniusMove, string move, int geniusAmmo, bool done)
        {
            Random RandomNumber = new Random();
            int x = RandomNumber.Next(0,3);
            if (x == 0)
            {
                geniusMove = "f";
                geniusAmmo--;
                Console.Write("Genius had decided to fire.\nGenius ammo is " + geniusAmmo + "\n");
                TestMoves(move, geniusMove);
            }
            else if (x == 1)
            {
                geniusMove = "r";
                geniusAmmo++;
                Console.Write("Genius had decided to reload.\nGenius ammo is " + geniusAmmo + "\n");
                TestMoves(move, geniusMove);
            }
            else if (x == 2)
            {
                geniusMove = "s";  
                Console.Write("Genius had decided to shield.\nGenius ammo is " + geniusAmmo + "\n");
                TestMoves(move, geniusMove);
            }

            return geniusMove;

        }


        public static void TestMoves(string move, string geniusMove)
        {
            bool done = false;
            if (move == "s" && geniusMove == "f")
            {
                Console.Write("Nice shield, no one has died yet");
                EndLoop(move, geniusMove, done);


            }
            else if (move == "f" && geniusMove == "f")
            {
                Console.Write("You both died!  Good game!");
                EndLoop(move, geniusMove, done);


            }
            else if (move == "r" && geniusMove == "f")
            {
                Console.Write("No shield!?  You died!  Good game!");
                EndLoop(move, geniusMove, done);


            }
            else if (move == "f" && geniusMove == "s")
            {
                Console.Write("Genius is too good, no one has died yet");
                EndLoop(move, geniusMove, done);


            }
            else if (move == "f" && geniusMove != "s")
            {
                Console.Write("Genius let his guard down!  Good game!");
                EndLoop(move, geniusMove, done);


            }
            else if (move != "f" && geniusMove != "f")
            {
                Console.Write("Keep playing it safe.");
                EndLoop(move, geniusMove, done);


            }
            else
            {
                EndLoop(move, geniusMove, done);

            }

        }

        public static bool EndLoop(string move, string geniusMove, bool done)
        {

            if (move == "s" && geniusMove == "f")
            {
                done = false;
                Console.Write(move + geniusMove + done);
                return done;
            }
            else if (move == "s" && geniusMove == "r")
            {
                done = false;
                Console.Write(move + geniusMove + done);
                return done;
            }
            else if (move == "s" && geniusMove == "s")
            {
                done = false;
                Console.Write(move + geniusMove + done);
                return done;
            }
            else if (move == "r" && geniusMove == "f")
            {
                done = true;
                Console.Write(move + geniusMove + done);
                return done;
            }
            else if (move == "r" && geniusMove == "r")
            {
                done = false;
                Console.Write(move + geniusMove + done);
                return done;
            }
            else if (move == "r" && geniusMove == "s")
            {
                done = false;
                Console.Write(move + geniusMove + done);
                return done;
            }
            else if (move == "f" && geniusMove == "f")
            {
                done = true;
                Console.Write(move + geniusMove + done);
                return done;
            }
            else if (move == "f" && geniusMove == "r")
            {
                done = true;
                Console.Write(move + geniusMove + done);
                return done;
            }
            else if (move == "f" && geniusMove == "s")
            {
                done = false;
                Console.Write(move + ge开发者_高级运维niusMove + done);
                return done;
            }
            else
            {
                done = false;
                Console.Write(move + geniusMove + done);
                return done;
            }
        }
    }
}


I know that I'm not answering your question directly, but I thought I'd try to give you an alternative way of implementing your game, using objects and LINQ, and trying to make the code more modular. Really for interest sake.

Here it is:

void Main()
{
    var moves = new Dictionary<string, Move>()
    {
        { "r", new Move(1, "Reloaded") },
        { "s", new Move(0, "Shielded") },
        { "f", new Move(-1, "Fired") },
    };

    var messages = new Dictionary<string, string>()
    {
        { "Shielded-Fired", "Nice shield, no one has died yet" },
        { "Fired-Fired", "You both died!  Good game!" },
        { "Reloaded-Fired", "No shield!?  You died!  Good game!" },
        { "Shielded-Shielded", "Keep playing it safe." },
        { "Fired-Shielded", "Genius is too good, no one has died yet" },
        { "Reloaded-Shielded", "No-one fired" },
        { "Shielded-Reloaded", "No-one fired" },
        { "Fired-Reloaded", "Genius let his guard down!  Good game!" },
        { "Reloaded-Reloaded", "No-one fired" },
    };

    var isDone = new Dictionary<string, bool>()
    {
        { "Shielded-Fired", false },
        { "Fired-Fired", true },
        { "Reloaded-Fired", true },
        { "Shielded-Shielded", false },
        { "Fired-Shielded", false },
        { "Reloaded-Shielded", false },
        { "Shielded-Reloaded", false },
        { "Fired-Reloaded", true },
        { "Reloaded-Reloaded", false },
    };

    var rnd = new Random();
    var choices = new [] { "r", "s", "f", };

    var human = new Player("You", () => Console.ReadLine(), m => Console.WriteLine(m));
    var genius = new Player("Genius", () => choices[rnd.Next(0, 3)], m => { });

    var allMoves = GetPlayerMoves(moves, human).Zip(GetPlayerMoves(moves, genius), (h, g) =>
    {
        human.Play(h);
        genius.Play(g);
        var hg = String.Format("{0}-{1}", h.Name, g.Name);
        Console.WriteLine(messages[hg]);
        return isDone[hg];
    });

    foreach (var done in allMoves)
        if (done)
            break;
}

private static IEnumerable<Move> GetPlayerMoves(Dictionary<string, Move> moves, Player player)
{
    while (true)
    {
        player.WriteMessage("\nEnter your move: ");
        var choice = player.GetChoice();
        if (moves.ContainsKey(choice))
        {
            var move = moves[choice];
            if (move.Play(player.Ammo) < 0)
            {
                player.WriteMessage("\nYou don't have enough ammo, try again.\n");
            }
            else
            {
                yield return move;
            }
        }
        else
        {
            player.WriteMessage("\nInvalid move, try again.\n");
        }
    }
}

public class Player
{
    public Player(string name, Func<string> getChoice, Action<string> writeMessage)
    {
        this.Name = name;
        this.Ammo = 1;
        _getChoice = getChoice;
        _writeMessage = writeMessage;
    }

    private readonly Func<string> _getChoice;
    private readonly Action<string> _writeMessage;

    public string GetChoice()
    {
        return _getChoice();
    }

    public void WriteMessage(string message)
    {
        _writeMessage(message);
    }

    public string Name { get; private set; }
    public int Ammo { get; private set; }

    public void Play(Move move)
    {
        this.Ammo = move.Play(this.Ammo);
        Console.Write(String.Format("{0} {1} (ammo is {2}.)\n", this.Name, move.Name.ToLowerInvariant(), this.Ammo));
    }
}

public class Move
{
    public Move(int ammoChange, string name)
    {
        this.AmmoChange = ammoChange;
        this.Name = name;
    }

    public string Name { get; private set; }

    private int AmmoChange { get; set; }

    public int Play(int ammo)
    {
        return ammo + AmmoChange;
    }
}


Declare static bool done = false; in the scope of your class and use the same instead of passing state over the different methods. You could have do that, if you pass the state up to the calling function Start.


You have two local variables called done. They are separate variables, so the done in Start is not the same variable as the done in TestMoves. And neither is the same as the parameter in EndLoop.

Best practice would be to actually create a Program instance, and have common variables like done as class members.

If there is some overriding reason why you want everything to be static, then just have a static class variable called done, instead of all the local variables and parameters.

There are lots of other things wrong with this code - e.g. there are other local variables and/or parameters that you alter the value of, but that alteration will not affect the calling method. There is lots of repeated code in every branch of an if/else if/else which could be moved out to a single call at the end.


You need to make bool done static and global that way when you call EndLoop the value of done in the loop is set as well.

class Program
{
    static bool done = false;
    // rest of code
}

You should also only be checking for the conditions where you want to set done to true and ignore the rest (as changing it from false to false does nothing).

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号